Professional Documents
Culture Documents
Posted on 23/06/2015
SELinux is often seen as an evil, complex, unnecessary and especially annoying security
component which exists in a lot of Linux distributions. Often you can hear something like:
Disable SELinux and try again or , The first thing I do on a new server is to disable
SELinux. The problem with SELinux is that it looks very complex and that it looks like you
need to spend ages to understand it. In this post, Ill try to explain a few basic SELinux principles
and especially focus on daily, practical problems related to SELinux and their solutions. Dont
forget that theres a very good reason for SELinux and it would be a shame to not use it.
SELinux stands for Security Enhanced Linux. Its a kernel security module that is responsible for
mandatory access control. This means that something wont work unless its explicitly allowed
by SELinux. The big advantage of SELinux is that it makes your system much more secure
because it provides a more granular approach to security. Its way more flexible that standard
permissions.
2 Job for httpd.service failed. See 'systemctl status httpd.service' and 'journalctl -xn' for details.
The following appears in the syslog/journal:
1 Jun 23 19:47:52 cen httpd[13190]: AH00557: httpd: apr_sockaddr_info_get() failed for cen
As you see, there isnt anything that tells us that the above error is SELinux related and this is
where SELinux usually tends to be annoying. In most situations, you will start to check various
settings, permissions, and you lose a lot of time to double check and see that actually
everything should be correct.
A good thing for such situations is to check the audit log immediately. This way, you can be sure
that the problem is or isnt SELinux related:
[jensd@cen ~]$ sudo tail -n100 /var/log/audit/audit.log |grep AVC
1 type=AVC msg=audit(1435063672.779:9069): avc: denied { name_bind } for pid=13190
2 comm="httpd" src=90 scontext=system_u:system_r:httpd_t:s0
tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket
The above line in the audit log tells us that it was SELinux that blocked httpd to bind on TCP
port 90.
Another example is when you try to access a file which is copied from somewhere else or which
has been extracted from an archive and doesnt have the correct SELinux security context.
Imagine that I created a nice html-file in my home directory and I decide to make it accessible
via my webserver. To be sure, I even change the owner of the file to apache and give it all
possible permissions (not a good idea):
1 [jensd@cen ~]$ sudo mv test.html /var/www/html/
2 [jensd@cen ~]$ sudo chown apache:apache /var/www/html/test.html
3 [jensd@cen ~]$ sudo chmod 777 /var/www/html/test.html
You would expect the above to work fine but when I try to access the file, I get a 403 Forbidden
in my browser and the following is in the Apache error log:
[jensd@cen ~]$ sudo tail /var/log/httpd/error_log|grep deny
1
[Tue Jun 23 19:55:20.411240 2015] [core:error] [pid 13257] (13)Permission denied: [client
2
192.168.202.1:50837] AH00132: file permissions deny server access: /var/www/html/test.html
As with the previous example, you can really get frustrated with such issue since there isnt any
hint or clue related to SELinux.
When checking the audit log, we can see that indeed SELinux blocked access to the file for
Apache:
Each of them needs to be solved in a different way to do things correctly. Using a custom module
to solve a context-related problem would solve the issue but potentially creates a security hole.
The order which I listed here is the order which you should follow for most cases.
4
5
6
7
8
9
10
11
12
abrt_upload_watch_anon_write --> on
antivirus_can_scan_system --> off
...
zabbix_can_network --> off
zarafa_setrlimit --> off
zebra_write_config --> off
zoneminder_anon_write --> off
zoneminder_run_sudo --> off
You could browse the list of booleans and guess which one to set to solve your problem. A better
way is to use audit2allow.
Audit2allow analyses a line in the audit log and will propose you with a possible solution. For
example when we want Apache to send emails with PHP directly to an SMTP server, we would
get something like this in the audit log:
1
2
3
4
5
6
7
LISTEN
13613/httpd
Audit2allow tells us indeed that we can give access to all files for FTP:
1
2
3
4
5
6
7
1
2
3
4
5
6
7
8
9
10
1
2
3
4
5
6
7
8
9
The above actions will allow ftpd to list a directory that has a httpd_sys_content_t label but
wont allow read or write of the files in those directories. We could repeat all actions multiple
times for each action we need but that would take a lot of time and generate a lot of different
modules.
A more clean way is to edit the source of the custom module yourself and allow all actions that
you need in one module:
The previous command (audit2allow -M) create the source of the module in a .te file which we
can use as a base for our custom module.
Edit the file to look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
After changing the source, we need to create/build the actual SELinux module ourselves and
activate it:
1
2
3
4
5
6
7
8
9
10
11
12
13