In our previous guide we looked at how to setup modern ngnix configuration without disabling SELinux. In this post, we're going to look at a few more terms and concepts that SELinux uses, so that we can later do more advanced SELinux tricks.
This is the core part of SELinux: labels. Everything from ports to files are all labeled a SELinux label.
We can use the -Z
flag on most command line utilities to view the label:
$ ls -lhZ
dr-xr-xr-x. 6 root root system_u:object_r:boot_t:s0 5.0K Jan 27 08:41 boot/
drwxr-xr-x. 22 root root system_u:object_r:device_t:s0 4.1K Feb 6 14:01 dev/
drwxr-xr-x. 1 root root system_u:object_r:etc_t:s0 5.5K Feb 6 14:01 etc/
drwxr-xr-x. 1 root root system_u:object_r:home_root_t:s0 48 Jul 14 2016 home/
dr-xr-x---. 1 root root system_u:object_r:admin_home_t:s0 354 Jan 30 19:37 root/
drwxrwxrwt. 14 root root system_u:object_r:tmp_t:s0 300 Feb 6 14:38 tmp/
drwxr-xr-x. 1 root root system_u:object_r:usr_t:s0 174 Nov 16 20:58 usr/
$ ps -eZ
LABEL PID TTY TIME CMD
system_u:system_r:init_t:s0 1 ? 00:00:05 systemd
system_u:system_r:kernel_t:s0 2 ? 00:00:00 kthreadd
system_u:system_r:syslogd_t:s0 655 ? 00:00:05 systemd-journal
system_u:system_r:policykit_t:s0 1155 ? 00:00:36 polkitd
$ netstat -Z
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Security Context
tcp 0 0 vogon-constructor:48378 ec2-54-172-133-71:https ESTABLISHED 6146/firefox fined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
tcp 1 0 vogon-constructor:52280 www0.libre.fm:http CLOSE_WAIT 23503/rhythmbox fined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Labels are purely cosmetic. On their own, they don't mean anything. But they all policies to target the thing (process/port/file).
Let's pretend that a SELinux label is a class
on a HTML element. You add a class to an element:
<!-- SELinux HTML :) -->
<div process="/run/systemd/journal/" class="system_u object_r syslogd_var_run_t s0"></div>
<div process="/usr/bin/systemd-journald" class="system_u system_r syslogd_t s0"></div>
allow-file-access: /run/systemd/log/;
Once we have our SE-HTML, we could write a selinux policy (which is like the CSS in this analogy):
.syslogd_t {
allow-file-rw-access: syslog_var_run_t;
}
Just a disclaimer, the syntax for SELinux policies is not this pretty. We'll be covering that in the next post in the series, so make sure to subscribe:
Here's a label from systemd-journal
:
system_u:system_r:syslogd_t:s0
Labels can look very confusing. But they are really quite simple. We just break it into 4 parts:
system_u
- the user (hence the _u
)system_r
- the role (hence the _r
)syslogd_t
- the type (hence the _t
). This is the most important part - it tells SELinux to use the policy for syslog_t
processes - which usually contains the bulk of the enforcement ruless0
- the MLS security code. By default, SELinux doesn't use MLS, so this is meaningless (see the section below for more)As you can see, the only important part of this label is the type (something_t
). That is a common pattern in SELinux labels. For example, her is the label for /etc/systemd/system/default.target
:
unconfined_u:object_r:systemd_unit_file_t:s0
unconfined_u
- see belowobject_r
- common for many configuration files, meaningless to ussystemd_unit_file_t
- this is a systemd unit file. There is probably a policy that targets this type, allowing systemd to read unit filess0
- the MLS security code. By default, SELinux doesn't use MLS, so this is meaninglessSo it is easy: just read the typename_t
section and you are good!
On your server, there are probably many things running as either unconfined_u
, unconfined_r
or unconfined_t
. We saw that above with the systemd unit file.
The unconfined_X
labels are reserved labels that have no policy attached. And with SELinux, no policy means there is no restriction. So if you don't want something to be policed, use unconfined. Unconfined doesn't override any other policies; so something with unconfined_u
and systemd_unit_file_t
will still be restricted per systemd_unit_file_t
policy.
Unconfined is the default for many processes on the desktop for that exact reason. I am typing now from gnome-terminal
running unconfined and inside vim
, unconfined again. You often don't want to restrict what desktop users can do, hence the user of unconfined.
Above we touched on the MLS codes. This is a very interesting part of SELinux.
SELinux comes with 2 modes; targeted (the default on every distro) and MLS (Multi-Level Security). Targeted policies mean that things are un-restricted by default, and only restricted if a policy is written for them (when they are targeted).
With MLS, everything is restricted by default. MLS is used by three letter agencies, such as the NSA (SELinux's initial developer). RedHat has a small section on MLS in their docs, if you are interested. MLS also uses the s0
part of the label to specify the security classification of the file.
With normal unix permissions, files permissions are set at file creation time. This means that every app has to think about what the correct permissions for files are.
In SELinux, things are labeled based on their characteristics. Ports are labeled based on their port number. Processes are labeled based on their executable path. And files are similar; they are labeled based on their path.
We can see the list of path labeling rules by running:
$ sudo semanage fcontext --list
SELinux fcontext type Context
/ directory system_u:object_r:root_t:s0
/.* all files system_u:object_r:default_t:s0
/bin all files system_u:object_r:bin_t:s0
/bin/.* all files system_u:object_r:bin_t:s0
/bin/alsaunmute regular file system_u:object_r:alsa_exec_t:s0
/bin/bash regular file system_u:object_r:shell_exec_t:s0
/bin/bash2 regular file system_u:object_r:shell_exec_t:s0
/bin/d?ash regular file system_u:object_r:shell_exec_t:s0
/bin/dbus-daemon regular file system_u:object_r:dbusd_exec_t:s0
/bin/dmesg regular file system_u:object_r:dmesg_exec_t:s0
/bin/fish regular file system_u:object_r:shell_exec_t:s0
/bin/hostname regular file system_u:object_r:hostname_exec_t:s0
...
As you can see, it is just a simple map from path regex to label. We how to add a new rule to this fcontext map in our previous guide. Adding custom fcontexts is a very important part of SELinux policy development and usage.
SELinux is conceptually simple: we label some things, then apply policies to them. Hopefully this post helps you understand how SELinux works on a 1000-foot level. If not, make sure to check Red Hat's SELinux coloring book for a different explanation. Make sure to subscribe as we continue our journey to secure a normal web-app server with a custom SELinux policy!
I hope you enjoyed this article. Contact me if you have any thoughts or questions.
© 2015—2024 Sam Parkinson