SELinux, De-mystified
By apexwm, 20 October, 2010 14:23
Are you in a habit of disabling SELinux, because it seems to break things? That seems to be the first reaction, as the first impression of SELinux is that it's just a troublemaker that stops tasks and causes access denied errors. However, recently I had the pleasure of digging in to SELinux to see just what it is all about. After figuring out how it works, I am making sure it's enabled on systems in the future. Why? Because it's an extra layer of security, and when you look at it, SELinux is actually a very smart way to prohibit attacks on a Linux system, mainly servers. If a system is compromised, SELinux greatly limits the damage that can be done.
A general observation about SELinux. Basically, it's a security layer that uses the kernel to allow/disallow activities on a Linux machine. By default, SELinux denies everything, then rules and policies are set to define what is allowed. What I did not know before, is that SELinux has 3 modes. Enforcing, permissive, and disabled. Enforcing means that it is actively enforcing rules. Permissive means that it is logging what would happen, but not actively enforcing. This is actually a very neat idea. Permissive can be used while diagnosing a SELinux problem, but will allow everything to work while you are troubleshooting. Also, SELinux can be toggled between Enforcing and Permissive modes on the fly, with the "setenforce" command: "setenforce 1" sets Enabled mode, and "setenforce 0" sets Permissive mode. This allows you to switch to Enforcing mode, test, and if something fails to work, you can switch right back to Permissive mode while you troubleshoot further. The "getenforce" command shows what the current setting is. Disabling SELinux entirely is done by editing the file /etc/sysconfig/selinux, and setting "mode=disabled". However, when putting SELinux in or taking out of Disabled mode, requires a reboot of the system for the kernel to restart in the appropriate mode. Also, if you are taking SELinux out of Disabled mode, switch to Permissive mode first and reboot. This will require a complete relabel operation when you reboot, which can take up to 10 minutes or so. After the reboot, you can then switch SELinux to Enforcing mode using the "setenforce 1" command.
SELinux is mainly designed to lock down running daemons. Common settings that need to be tweaked are boolean settings and file context settings. Each daemon has its own group of available settings, so usually these settings are documented in each daemon's own documentation. The "setsebool" command is used to set boolean values for a daemon. For instance, to allow Apache to connect to network resources, the command "setsebool -P httpd_can_network_connect 1" is used. These boolean values can be turned on/off on the fly. You can view the current setting by using "getsebool" command as well.
The other main area of SELinux settings are file contexts. These are labels applied in addition to permissions on each file/folder, that define what daemons have access to each file/folder. You can view the context assigned to a file/folder by using the -Z option on most commands that work with the filesystem. For instance, "ls -Z" or "ll -Z" will list files/folders with their contexts listed for each. Two additional commands commonly used to view and modify file contexts are "chcon" and "semanage".
The "chcon" command stands for "change context". So for instance, say you have a folder on your disk, and you want multiple daemons to have access to it. This can be handled with a context called "var_t". To apply this context to the folder, you simply use the chcon command like this: "chcon -Rv -t var_t foldername". The -Rv options stand for recursive and verbose, respectively. -t defines the context to be used. You can leave off the -R option if you do NOT want to set it on subfolders/files. Changes made on a folder will be automatically inherited for new subfolders and files created. So, the chcon command can change file contexts on the fly, however if the filesystem has to be relabeled, these contexts would be lost; the "chcon" command actively changes files, but it does not modify the rules that are stored and used when relabeling.
To ensure the contexts are always persistent even after relabeling, you can use the "semanage" command to permanently store the rules. Typically, I use the "chcon" command to assign contexts and test them. Once I've ensured everything is working I use the "semanage" command to make them permanent. To apply the changes in the example above and make them permanent, the semanage command would be as follows: semanage fcontext -a -t var_t "/path/to/foldername(/.*)?" . The -a option means "add" the rule; alternatively you would use the -d option to delete a rule. -t defines the context. You can see the existing file context rules by running "semanage fcontext -l". You will notice this contains a huge number of predefined rules, for many files and folders on your system. But in this example, if you wanted to see your stored rule, you could run "semanage fcontext -l | grep foldername" and it would return the rule you created.
Troubleshooting SELinux is the hardest part, and also to figure out which contexts are appropriate for the access you want to provide to daemons. Remember SELinux is designed to deny everything, then you specify what you want to allow. So by default, chances are you will run across access denied errors in your logs. By default, SELinux will log activity to /var/log/messages. If you start the "auditd" service, this will route these log entries to /var/log/auditd/auditd.log. This is nice for troubleshooting to keep these entries in their own log. Also, there is another service called "setroubleshootd". This service is for obtaining friendly messages about the denied errors that happen. Troubleshooting SELinux is an entirely separate topic. Also, don't forget about online forums which are a great resource. Remember, chances are somebody else has already had the problem you have, and provided a solution.