Hello,
I am new to selinux and new to this community, and I was wondering if someone could help me review two policies for a new web server I am preparing for release. (Apologize in advance if I am posting this in the wrong location).
Software list: CentOS 7.2.1511 MariaDB 10.1.13 NGINX 1.9.14 PHP 5.6 Redis 2.8.19
I have modified the web root and the mysql/mariadb data directory and it seems selinux does not like that at all. Below are some proposed modules from audit2allow. Was wondering if there are any red flags to using them in production. I got a little nervous when I read that "Modules created with audit2allow may allow more access than required. It is recommended that policy created with audit2allow be posted to an SELinux list, such as fedora-selinux-list, for review." https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/htm...
Any help greatly appreciated.
module phpfpmlocal 1.0; require { type redis_port_t; type httpd_t; type httpd_sys_content_t; class tcp_socket name_connect; class file { write create unlink setattr append }; class dir { write rmdir setattr remove_name create add_name }; } #============= httpd_t ============== #!!!! This avc can be allowed using the boolean 'httpd_unified' allow httpd_t httpd_sys_content_t:dir { write rmdir setattr remove_name create add_name }; #!!!! This avc can be allowed using the boolean 'httpd_unified' allow httpd_t httpd_sys_content_t:file { write create unlink append setattr }; #!!!! This avc can be allowed using the boolean 'httpd_can_network_connect' allow httpd_t redis_port_t:tcp_socket name_connect;
module http_t_filerename_local 1.0; require { type httpd_t; type httpd_sys_content_t; class file rename; } #============= httpd_t ============== #!!!! This avc can be allowed using the boolean 'httpd_unified' allow httpd_t httpd_sys_content_t:file rename;
Also, can someone advise if using file_contexts.local is a good or bad practice, and what is the difference between using the .local v. creating a custom policy. Here is what I added to /etc/selinux/targeted/contexts/files/file_contexts.local. I am not sure if it is introducing any new risks by doing so.
/www/mysql(/.*)? system_u:object_r:mysqld_db_t:s0 /www/sites(/.*)? system_u:object_r:httpd_sys_content_t:s0
Thanks in advance,
Michael Stephenson MS Information Systems, BS Computer Science
Update: I just read how to Manually Customizing Policy Modules at this link here: https://wiki.centos.org/HowTos/SELinux. I did not know I could use the .te file and modify it, this is great news. I kept encountering new issues as I would install new web applications and I was not able to see the older issues anymore when using audit2allow against the logs. I understand now how to modify my local policies as I go, phew.
That said, here is my new policy that combines the previous two from my frist message. I am running an NGINX web root and MariaDB data dir from a separate SSD mount point '/www'. I am using PHP-FPM for my application code and Redis for session caching. Here is the policy I would like to roll-with. It seems good to me but just wanted a second set of eyes to tell me what I may be missing.
module phpfpmlocal 1.1;
require { type redis_port_t; type httpd_t; type httpd_sys_content_t; class tcp_socket name_connect; class file { rename write create unlink setattr append }; class dir { write rmdir setattr remove_name create add_name }; }
#============= httpd_t ==============
#!!!! This avc can be allowed using the boolean 'httpd_unified' allow httpd_t httpd_sys_content_t:dir { write rmdir setattr remove_name create add_name };
#!!!! This avc can be allowed using the boolean 'httpd_unified' allow httpd_t httpd_sys_content_t:file { rename write create unlink append setattr };
#!!!! This avc can be allowed using the boolean 'httpd_can_network_connect' allow httpd_t redis_port_t:tcp_socket name_connect;
On 04/15/2016 03:22 AM, Michael Stephenson wrote:
Update: I just read how to Manually Customizing Policy Modules at this link here: https://wiki.centos.org/HowTos/SELinux. I did not know I could use the .te file and modify it, this is great news. I kept encountering new issues as I would install new web applications and I was not able to see the older issues anymore when using audit2allow against the logs. I understand now how to modify my local policies as I go, phew.
That said, here is my new policy that combines the previous two from my frist message. I am running an NGINX web root and MariaDB data dir from a separate SSD mount point '/www'. I am using PHP-FPM for my application code and Redis for session caching. Here is the policy I would like to roll-with. It seems good to me but just wanted a second set of eyes to tell me what I may be missing.
module phpfpmlocal 1.1;
require { type redis_port_t; type httpd_t; type httpd_sys_content_t; class tcp_socket name_connect; class file { rename write create unlink setattr append }; class dir { write rmdir setattr remove_name create add_name }; }
#============= httpd_t ==============
#!!!! This avc can be allowed using the boolean 'httpd_unified' allow httpd_t httpd_sys_content_t:dir { write rmdir setattr remove_name create add_name };
#!!!! This avc can be allowed using the boolean 'httpd_unified' allow httpd_t httpd_sys_content_t:file { rename write create unlink append setattr };
Hello Michael,
the httpd_unified boolean is very powerfull boolean and basically turns SELinux protection off for httpd. I would go with a context which can be written by httpd_t - httpd_sys_rw_content for example.
Also you specify local customizations, the semanage tool should be used and *.local file contexts will be updated.
semanage fcontext -a -t httpd_sys_rw_content_t "/www/sites(/.*)?"
Also the question is if we need to add this label for the entire /www/sites directory and subdirectories or it just needs to access a subdirectory.
#!!!! This avc can be allowed using the boolean 'httpd_can_network_connect' allow httpd_t redis_port_t:tcp_socket name_connect; -- selinux mailing list selinux@lists.fedoraproject.org http://lists.fedoraproject.org/admin/lists/selinux@lists.fedoraproject.org
Hello Michael,
the httpd_unified boolean is very powerfull boolean and basically turns SELinux protection off for httpd. I would go with a context which can be written by httpd_t - httpd_sys_rw_content for example.
Thanks for the reply Miroslav!
Your comment about using the http_unified boolean is very helpful. To be honest I was just using the recommendation from audit2allow based the input from the /var/log/audit/audit.log. I am not familiar with the httpd_sys_rw_content context. I will start reading up on that one now.
Also you specify local customizations, the semanage tool should be used and *.local file contexts will be updated.
semanage fcontext -a -t httpd_sys_rw_content_t "/www/sites(/.*)?"
About the .local file contexts, yes I used the semanage tool. Thanks for confirming the usage was the correct way to go about it. Looking at the content of the file it is easy to see how one could want to edit that file manually and skip using the tool, but I'm not that brave :)
Here are my notes from how I used semanage, just for context.
[...] # We need to tell SELinux about the new location, grant permission and then recursive restorecon semanage fcontext -a -t mysqld_db_t "/www/mysql(/.*)?"
# Confirm the write to local selinux policy grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local
# Might as well add the web directory too for httpd_sys semanage fcontext -a -t httpd_sys_content_t "/www/sites(/.*)?"
# Restore perms restorecon -R -v /www [...]
Also the question is if we need to add this label for the entire /www/sites directory and subdirectories or it just needs to access a subdirectory.
This is a great question. To be honest, I was just looking for the all-encompassing rule to make sure that none of the websites that we plan on running from that location would not get blocked. I'm totally open to suggestion on how to improve.
Here is a little more on the application/server. This is not a shared server, only primary business sites will be running on the box so there will not be many local user accounts - probably just one admin/root and the necessary nginx and mysql accounts.
My plan to place everything in /www was a first draft just to get things moving. I wanted to have a small OS disk mount and a larger DATA disk mounted to streamline operations (e.g. backups/snapshots, new system clones, etc.). A second draft will probably be one that has 3 disks - OS, DB, DATA, but not ready to cross that bridge yet until I get everything going.
That said, my current /web mount will store all the data necessary for our web applications - mysql db and application code.
I have chose to organize all the domain web roots in the /www/sites directory in the following way:
/www/sites/domain_one/html /www/sites/domain_two/html ... /www/sites/domain_ten/html
nginx will have permission over all 'html' dir in each domain folder.
The applications we are running are common CMS and eCommerce app - Wordpress, Magento, Drupal, etc.
Going back to answer your question "do we need to add this label for the entire www/sites directory and subdirectories, or can it be just the subdirectories," I'm not sure. Being that the domain names are random, I did not know if there was a way I could make sure the apps didn't get blocked each time we add a new domain - forcing us to revisit the *.local rules and add another exception. The logic I used to justify adding the label to all /www/sites was because root owns everything up to /html, and my thinking was that even if httpd_sys_content_t was allowed on all below /www/sites, it could not however, step into folders outside nginx ownership. I may completely wrong so please offer some guidance here. I am not linux security expert and I appreciate expert opinion and recommendations.
Thanks again for all your help so far. This is a great community!
On 04/15/2016 07:50 PM, Michael Stephenson wrote:
Hello Michael,
the httpd_unified boolean is very powerfull boolean and basically turns SELinux protection off for httpd. I would go with a context which can be written by httpd_t - httpd_sys_rw_content for example.
Thanks for the reply Miroslav!
Your comment about using the http_unified boolean is very helpful. To be honest I was just using the recommendation from audit2allow based the input from the /var/log/audit/audit.log. I am not familiar with the httpd_sys_rw_content context. I will start reading up on that one now.
Also you specify local customizations, the semanage tool should be used and *.local file contexts will be updated.
semanage fcontext -a -t httpd_sys_rw_content_t "/www/sites(/.*)?"
About the .local file contexts, yes I used the semanage tool. Thanks for confirming the usage was the correct way to go about it. Looking at the content of the file it is easy to see how one could want to edit that file manually and skip using the tool, but I'm not that brave :)
Here are my notes from how I used semanage, just for context.
[...] # We need to tell SELinux about the new location, grant permission and then recursive restorecon semanage fcontext -a -t mysqld_db_t "/www/mysql(/.*)?"
# Confirm the write to local selinux policy grep -i mysql /etc/selinux/targeted/contexts/files/file_contexts.local
# Might as well add the web directory too for httpd_sys semanage fcontext -a -t httpd_sys_content_t "/www/sites(/.*)?"
# Restore perms restorecon -R -v /www [...]
Also the question is if we need to add this label for the entire /www/sites directory and subdirectories or it just needs to access a subdirectory.
This is a great question. To be honest, I was just looking for the all-encompassing rule to make sure that none of the websites that we plan on running from that location would not get blocked. I'm totally open to suggestion on how to improve.
Here is a little more on the application/server. This is not a shared server, only primary business sites will be running on the box so there will not be many local user accounts - probably just one admin/root and the necessary nginx and mysql accounts.
My plan to place everything in /www was a first draft just to get things moving. I wanted to have a small OS disk mount and a larger DATA disk mounted to streamline operations (e.g. backups/snapshots, new system clones, etc.). A second draft will probably be one that has 3 disks - OS, DB, DATA, but not ready to cross that bridge yet until I get everything going.
That said, my current /web mount will store all the data necessary for our web applications - mysql db and application code.
I have chose to organize all the domain web roots in the /www/sites directory in the following way:
/www/sites/domain_one/html /www/sites/domain_two/html ... /www/sites/domain_ten/html
nginx will have permission over all 'html' dir in each domain folder.
The applications we are running are common CMS and eCommerce app - Wordpress, Magento, Drupal, etc.
Going back to answer your question "do we need to add this label for the entire www/sites directory and subdirectories, or can it be just the subdirectories," I'm not sure. Being that the domain names are random, I did not know if there was a way I could make sure the apps didn't get blocked each time we add a new domain - forcing us to revisit the *.local rules and add another exception. The logic I used to justify adding the label to all /www/sites was because root owns everything up to /html, and my thinking was that even if httpd_sys_content_t was allowed on all below /www/sites, it could not however, step into folders outside nginx ownership. I may completely wrong so please offer some guidance here. I am not linux security expert and I appreciate expert opinion and recommendations.
We can say something like "/www/sites/*/html(/.*)?" but the question is how they are created? If they are created by hand, we can restore labeling. If they are created on the fly, it is more complicated to make sure all labeling is correct.
So I would go with labeling how I described above.
Thanks again for all your help so far. This is a great community!
-- selinux mailing list selinux@lists.fedoraproject.org http://lists.fedoraproject.org/admin/lists/selinux@lists.fedoraproject.org
selinux@lists.fedoraproject.org