Introduction to SELinux
SELinux is well known as the most sophisticated Linux Mandatory Access Control (MAC) System. If you install any Fedora or Redhat operating System it is enabled by default and running in enforcing mode. So far so good.
Its available for many years and its not rocket science to use it. This article is supposed to give you some hints how to make your system even more secure and how to solve some troubles SELinux may have on your system.
DAC vs. MAC
Linux and traditional Unix systems are using DAC (Discretionary Access Control). Every user can change access rights to its own files. SELinux is a MAC (Mandatory Access Control) System where access rights are ruled by system wide policies. This can cause confusion when access is denied to a resource. Be aware that DAC will kick in before SELinux policies do. So if access to a resource is denied, please check access rights first. In such a case you will not see any AVC denials in your logs. The return code (EACCES) is the same.
There is plenty of information available in the man pages. Some of the configuration file examples also contains additional information.
server:~# man -k selinux
Gives a good overview
Stick to Standards
Sofware installed from a RHEL or Fedora repository is usually not a problem at all, as long as you are using standards for config files, data, ports etc. Stick to the standards wherever possible. I.e. It does not make any sense to store websites in /opt instead of /var/www/html
Standards do not work for you?
If you can not stick to the standards for whatever reason, you can adjust a lot of settings with semanage.
Adding an allowed TCP Port for Apache
If you want to run your Apache httpd on port 8010, Apache will not start and a SELinux AVC denial is filed. To check which ports are allowed for Apache run:
server:~# semanage port -l|grep http_port_t
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
There is nothing like 8010
You can simply add port 8010 to the allowed ports by running
server:~# semanage port -a -t http_port_t 8010 -p tcp
server:~# semanage port -l|grep http_port_t
http_port_t tcp 8010, 80, 81, 443, 488, 8008, 8009, 8443, 9000
Using a non-standard location for HTML files
Lets assume you want to store your HTML files in /opt/srv. To do so, you need to change the file context of that path and restore the file context afterwards.
server:~# semanage fcontext -a -t httpd_sys_rw_content_t '/opt/srv(/.*)?'
server:~# restorecon -R -v /opt/srv
Make use of Boolean variables
There are plenty of bool variables which simple allows to turn on or off a particular protection.
To get a list of defined bools, run
server:~# getsebool -a
You may want to pipe it to less or grep for a search pattern.
As an example, the default behavior is that a web application running in the httpd_t context will not be allowed to send emails. That helps greatly to prevent a vulnerable web application to send out SPAM. Well, if you want to operate a web mail service Apache must be able to send emails. No big deal:
server:~# setsebool -P httpd_can_sendmail on
The are some CLI (and GUI) tools available to troubleshoot AVC denials. The most important is sealert. Here is an example of an AVC because of a mislabled file in /var/www/html
sealert -a /var/log/audit/audit.log
SELinux is preventing /usr/sbin/httpd from getattr access on the file /var/www/html/test.html
***** Plugin restorecon (99.5 confidence) suggests ************************
If you want to fix the label.
/var/www/html/test.html default label should be
Then you can run restorecon.
# /sbin/restorecon -v /var/www/html/test.html
As you can see, sealert already provides you a hint how to fix the problem. In more complex cases, audit2why and audit2allow will help you. You simply grep for the misbehaving process:
server:~# grep httpd /var/log/audit/audit.log |audit2allow -m my_local_module
Review the result to check if it makes sense (ensure your grep statement does not catch too much). If you’re confident its okay, run the same command again with a capital M as parameter. It will create you a Local Policy Module which can be inserted:
server:~# grep httpd /var/log/audit/audit.log |audit2allow -M my_local_module
server:~# semodule -i my_local_module.pp
Temporary mitigation of SELinux troubles
If sealert and audit2allow can not immediately solve your problems and you quickly need to get your service up and running again, temporary put your system in permissive mode.
server:~# setenforce permissive
It will stay in pemissive mode until you reboot your system.
Permissive mode does not enforce the SELinux policies, it just logs AVC denials and help you to solve the problems without any service interruption. Be aware: This is a temporary quick fix, not a solution.
Put the affected domain only into permissive mode
If all your investigation did not help, all answers from support did not helped (very unlikely) you can put a particular domain into permissive mode. The rest of the policies are still in enforcing mode, your system still have some protection.
As an example, you can put the Apache module into permissive mode:
server:~# semanage permissive -a http_t
Hardening your System
Most people are not aware of the fact that when a system is in enforcing mode a malicious user with root access can manipulate policies or put SELinux into permissive mode.
There is a method to prevent this: Lock down your system
server:~# setsebool -P secure_mode_policyload on
Be aware: Once active nothing can not be changed during runtime, you need to reboot your system and provide selinux=1 enforcing=0 as grub boot parameter to be able to change any SELinux settings.
Have some fun!
Download “The SELinux Coloring Book” and learn more 🙂
Have fun 🙂