Showing posts with label Practical. Show all posts
Showing posts with label Practical. Show all posts

Saturday, May 28, 2011

Practical SELinux: Port contexts and handling access alerts

Takeaway: After introducing and recommending SELinux a couple of weeks ago, I followed up with some of the basics - learning about setting file contexts with the semanage tool. This time, I’ll show you how to set other contexts, and also look at how to handle reported access violations. Previously, we concentrated on file contexts; yet another [...]

After introducing and recommending SELinux a couple of weeks ago, I followed up with some of the basics - learning about setting file contexts with the semanage tool. This time, I’ll show you how to set other contexts, and also look at how to handle reported access violations.

Previously, we concentrated on file contexts; yet another common and useful type of context to set is one related to ports. Using Apache as an example again, we know that Apache typically listens to ports 80 and 443. Default policy allows for this. If we wanted to have Apache listen on port 888 as well, however, this would not be permitted.

For instance, if you have:

...

in your httpd.conf file and attempted to restart Apache, it would fail as follows: # service httpd restartStopping httpd:                                            [  OK  ]Starting httpd: (13)Permission denied: make_sock: could not bind to address [::]:888(13)Permission denied: make_sock: could not bind to address 0.0.0.0:888no listening sockets available, shutting downUnable to open logs                                                           [FAILED]

What happened? Looking in /var/log/messages is a great place to start: Apr  2 15:34:03 cerberus setroubleshoot: SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 888. For complete SELinux messages. run sealert -l b9797116-ceaa-4dc8-acbc-b2fdb1dd1cfd

This is fairly useful and gives the exact command to view the alert in detail. The information used to construct this is stored in /var/log/audit/audit.log, but using sealert to view it is much easier: # sealert -l b9797116-ceaa-4dc8-acbc-b2fdb1dd1cfdSELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 888.*****  Plugin bind_ports (92.2 confidence) suggests  *************************If you want to allow /usr/sbin/httpd to bind to network port 888Then you need to modify the port type.Do# semanage port -a -t PORT_TYPE -p tcp 888    where PORT_TYPE is one of the following: ntop_port_t, http_cache_port_t, http_port_t.*****  Plugin catchall_boolean (7.83 confidence) suggests  *******************If you want to allow system to run with NISThen you must tell SELinux about this by enabling the 'allow_ypbind' boolean.Dosetsebool -P allow_ypbind 1*****  Plugin catchall (1.41 confidence) suggests  ***************************If you believe that httpd should be allowed name_bind access on the port 888 tcp_socket by default.Then you should report this as a bug.You can generate a local policy module to allow this access.Doallow this access for now by executing:# grep httpd /var/log/audit/audit.log | audit2allow -M mypol# semodule -i mypol.pp

The sealert tool offers a lot of information here, including suggestions on how to resolve the issue. Out of the three suggestions it provides, the first is the one we want. We need Apache to listen to this port. The third suggestion would work as well, but the first is the easiest of the bunch (provided the correct context is chosen). In this case, it isn’t to be used for caching, but serving up content, so the httpd_port_t type is the one to use: # semanage port -a -t http_port_t -p tcp 888# semanage port -l | grep http_porthttp_port_t                    tcp      888, 80, 443, 488, 8008, 8009, 8443pegasus_http_port_t            tcp      5988

Incidentally, semanage port -l works the same for ports as semanage fcontext -l works for file contexts. In the above, we can see that the http_port_t type is now applied to port 888, and Apache should start. When it does, you can verify it is listening to the port with netstat: # netstat -lpn --tcp | grep 888tcp        0      0 :::888                      :::*                        LISTEN      28463/httpd

If you make a mistake, it is easy enough to delete the type. Also, if you wanted to prevent a service from binding on a particular port, the semanage delete (-d) argument is used (the rest of the arguments are identical to the add command): # semanage port -d -t http_port_t -p tcp 888# semanage port -l | grep http_porthttp_port_t                    tcp      80, 443, 488, 8008, 8009, 8443pegasus_http_port_t            tcp      5988

The final tools to get a quick introduction are the getsebool and setsebool tools. SELinux has a number of boolean macros that allow or deny certain types of functionality. For instance, Apache has a mechanism to allow users to have their own personal web sites using the ~/public_html/ directory (which shows up as http://foo.com/~user/). By default, SELinux does not permit this type of functionality, as seen by the value of the httpd_enable_homedirs boolean: # getsebool httpd_enable_homedirshttpd_enable_homedirs --> off

This in itself isn’t very descriptive, so semanage can provide further information: # semanage boolean -l | grep httpd...httpd_enable_homedirs          -> off   Allow httpd to read home directories...

Incidentally, using semanage boolean -l is a great way to see what booleans can be set and what they are used for.

To enable allowing httpd to read home directories, we would use setsebool:

# setsebool httpd_enable_homedirs 1# getsebool httpd_enable_homedirshttpd_enable_homedirs --> on

This will persist only while the system is running. To save this boolean change to the SELinux policy files, you must use the persistent change (-P) option to setsebool: # setsebool -P httpd_enable_homedirs 1

There is, obviously, so much more to SELinux, but these are the basics. Knowing how to change boolean settings, how to change the ability to access certain ports, files, and directories, as well as how to obtain information on SELinux violations, should provide you with the confidence to give SELinux a try. It isn’t nearly as scary as I thought it was a few years ago, and using SELinux now, on supported and recent distributions, will provide you with tools that are better and easier to use than those provided a decade ago. If you have been running a system capable of using SELinux, but have had it running in Disabled mode, you owe it to yourself to give it a try in at least Permissive mode. For a little bit of time and effort, it could save you when the next 0-day flaw that is applicable to you comes around (and, honestly, they seem to be coming around a lot more often than they used to).

Vincent Danen Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years.

Practical SELinux for the beginner: Contexts and labels

Takeaway: Vincent Danen gets into some of the basics of working with SELinux. Learn how to work with contexts, which include ports, processes, files, and directories, and labels.

Last time, I introduced you to SELinux: what it is, what it can do, and really why you need it (or a system like it). It is especially important with reported (and fixed) security vulnerabilities on the rise, and each year brings more reports, and more updates for end-users to install. This data tells us that we are in greater need of proactive security measures now than we ever were before. And this is where software like SELinux fits in.

There is a lot to SELinux, and we’re only going to touch on SELinux contexts and labels. Suffice it to say, SELinux policies contain various rules that allow interaction between different contexts. Contexts are ports, processes, files, directories, and so on. Instead of getting overwhelmed with the technical concepts of SELinux, we’ll instead look at the practical side of using SELinux so that it doesn’t seem quite as daunting.

The first thing to do is determine what mode SELinux is running in:

$ getenforceEnforcing

The getenforce command tells us what mode SELinux is in. The possible modes are Enforcing, Permissive, or Disabled. Enforcing means that SELinux will report access violations and deny the attempt, Permissive tells SELinux to report the violation but allow it, and Disabled completely turns SELinux off.

Ideally, if you are unprepared to run SELinux in Enforcing mode, it should be in Permissive mode.

This can be set at boot by editing (on Red Hat Enterprise Linux and Fedora) the /etc/sysconfig/selinux file and setting the SELINUX option:

SELINUX=enforcing

This will ensure it persists across reboot. SELinux can transition from Enforcing to Permissive easily using the setenforce command. Providing setenforce with a “0? argument will put the system in Permissive mode, a “1? will set it to Enforcing. To transition to or from Disabled mode, you need to reboot after making the appropriate changes to the sysconfig file. Using setenforce can be a great way of troubleshooting problems; if the problem goes away after setting the system to Permissive mode then you know it is SELinux.

If not, then it is something else.

# setenforce 0# getenforcePermissive

To view the contexts that a process is running with, add the Z option to ps: # ps auxZ | grep httpdsystem_u:system_r:httpd_t:s0    apache   30544  0.0  0.0 305612  6688 ?        S    Mar30   0:00 /usr/sbin/httpd

This tells us that the httpd process is using the httpd_t type, the system_r role, and the system_u user. More often than not, it is the httpd_t type you would be interested in.

The Z option is also used with other commands, such as ls, cp, id, and others. For instance, to view your security context:

# id -Zunconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Or to view the security context associated with a file: # ls -lZ /var/www/html/index.html-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html

Again, probably the most useful bit of information here is the type, in this case it is httpd_sys_content_t.

As an example of how to quickly change the policy, assume that you do not put your websites in /var/www/, but rather use /srv/www/foo.com/html/ for your site’s document root. You can configure Apache to use these directories as the DocumentRoot for various websites, but if you were to visit them, Apache would return an error because SELinux would disallow access. SELinux knows nothing about allowing Apache to these directories as of yet.

To determine what type a file needs to have in order for Apache to access it, the above ls command tells us that the type we want is probably httpd_sys_content_t; after all, Apache by default serves files from /var/www/html/. Another, probably better, way is to use the semanage tool.

This tool is used to show, and change, defined SELinux policy. We could also do:

# semanage fcontext -l | grep '/var/www'/var/www(/.*)?                                     all files          system_u:object_r:httpd_sys_content_t:s0

This command tells semanage to list all fcontext entries (file contexts), and we hand that output to grep to search for and display ‘/var/www’. For brevity, the whole output is not shown, but the above confirms that /var/www/* has the httpd_sys_content_t type. So what we need to do is tell SELinux to give this same type to /srv/www/foo.com/html/*, so that Apache can serve up those files.

This can be done by using semanage to add a new context:

# semanage fcontext -a -t httpd_sys_content_t '/srv/www(/.*)?'# semanage fcontext -l | grep '/srv/www'/srv/www(/.*)?                                     all files          system_u:object_r:httpd_sys_content_t:s0# restorecon -Rv /srv/www

The SELinux policies here use regular expressions, so the above tells semanage to add (-a) a new fcontext with the type (-t) httpd_sys_content_t, and targets /srv/www itself and any sub-directories and files. We use semanage to list the fcontexts and search for any ‘/srv/www’ entries, to verify it is in place, and then use restorecon to re-label and set the appropriate security context on the /srv/www directory and any sub-directories and files.

At this point, Apache will serve content from that directory if configured to do so, because Apache has the right to read httpd_sys_content_t files and /srv/www/ will now be labeled correctly.

The restorecon tool is used to set default contexts on files and directories, according to policy. You will become very familiar with this tool because it is used very often. For instance, if you move a file from a home directory to this web root, it will not immediately gain the appropriate security context because the mv command retains the existing context (cp will make a new context because it is making a new file). For instance:

% echo "my file" >file.html% ls -Z file.html-rw-rw-r--. vdanen vdanen unconfined_u:object_r:user_home_t:s0 file.html% mv file.html /srv/www/foo.com/html/% ls -Z /srv/www/foo.com/html/-rw-rw-r--. vdanen vdanen unconfined_u:object_r:user_home_t:s0 file.html

Apache is not, by default, allowed to serve up user_home_t files, so any attempt to display this file via Apache will fail with denied access. restorecon is required to re-label the file so Apache can access it: # restorecon -v /srv/www/foo.com/html/file.htmlrestorecon reset /srv/www/foo.com/html/file.html context unconfined_u:object_r:user_home_t:s0->system_u:object_r:httpd_sys_content_t:s0

Now the security context of the file is correct.

Similarly, when going from Disabled mode to Permissive or Enforcing mode, SELinux will have to re-label the entire filesystem (effectively running “estorecon /) because contexts are not set at all when SELinux is disabled.

Once you wrap your head around these basics of SELinux, all of a sudden it is no more difficult to use than manipulating iptables firewall rules. Just as you would adjust your firewall to allow access to a new service, you adjust SELinux file contexts to allow applications and services to access them. Yes, it does require a little more work to set up, initially, but the security benefits are really quite useful, especially considering that the bulk of this kind of manipulation will only happen when initially setting up a system or adding new services. And getting into the habit of running restorecon on new files and directories as they are created isn’t any more difficult than using ls on them to double-check their permissions.

The next and final tip on SELinux will introduce us to SELinux logging, to detect access violations, and to some other basic SELinux commands.

Vincent Danen Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years.