Security-Enhanced (SE) Linux
- Red Hat Enterprise Linux 6, Security-Enhanced Linux User Guide.
- Note: this "article"/section is mainly notes based on this reference. This is a r-e-a-l-l-y good bit of documentation!
- Managing Red Hat Enterprise Linux, D J Walsh, K MacMilan.
- Note: this "article"/section is mainly notes based on this reference.
- The SELinux Notebook, 4th edition.
- Note: this "article"/section is mainly notes based on this reference.
- Discretionary access control, Wikipedia.
- Mandatory access control, Wikipedia.
- Principle of Least Privilege, Wikipedia.
- Linux Security Modules, Wikipedia.
- SELinux concepts, Android Docs.
- SE Linux Colouring Booko, RedHat.
- SE Linux Saves: Examples where SE Linux prevent exploits.
Linux without the SE
The Linux kernel controls that access that a process has to resources. In the standard Linux Discrtionary Access Controll (DAC) this is does by assigning users and resources to groups. Processes are given the same group and user IDs as the user that started the process. The process can then access a resource if it shares either the same user or group ID with the resource, or if the resource is "public".
I.e., a process accesses a resource based on the resource access bits:
- If the resource available to anyone, the the process can access it,
- Otherwise if the process and resource are in the same group then the the process can access it,
- Otherwies if the process and resource are owned by the same user, the process can access it,
- Otherwise the process cannot access the resource.
This is called a security policy. The policy is the set of rules used to make access control decisions.
Therefore, access to system resources must be set by the system admin, who will decide which
users belong to which groups and which system resources belong to which group (and user). However,
the system is discretionary
in the sense that a subject with a certain access permission is capable of passing that permission (perhaps indirectly) on to any other subject [Ref].
This discretionary access means that the system admin is not totally in control of who accesses what. For example, Bob can change the group associated with a file he owns and suddenly give a different set of indiviudals the right to read/write/execute that file. This is not in the system admin's control. Bob has been able to make to make a policy decision!
The main RedHat article referenced [Ref], describes some of the disadvantages in more detail. In summary they are:
- Processes' access is based on users' access: the kernel can not distinguish applications from users,
- Processes can change security properties: discretionary access control. Processes can escape security policy!
- Only 2 privilege levels, user and root: too simplistic and no way to enforce "least-privilege" (i.e., a process should be given only those priviliges essential for it to perform its work) [Ref]
Summary of terminology:
- Security policy is the set of rules used to make access control decisions.
- Discretionary access means that a subject with a certain access permission is capable of passing that permission on.
- Least-privilege describes a security mindset that states that a process should be given only those priviliges essential for it to perform its work.
SELinux: A Bird's Eye View
SELinux stands for Security Enhanced Linux. It is built on years of the NSA's security research and is an applicaton of their Flash security architecture, implemented as part of the Linux Security Module (LSM) framework. It adds Manditory Access Controll (MAC) to Linux:
...With mandatory access control, this security policy is centrally controlled by a security policy administrator; users do not have the ability to override the policy ... By contrast, discretionary access control ... allows users the ability to make policy decisions and/or assign security attributes. ... MAC-enabled systems allow policy administrators to implement organization-wide security policies. Under MAC (and unlike DAC), users cannot override or modify this policy, either accidentally or intentionally ... in principle ...
Most intestestingly, for me at least, Android uses SELinux (since 4.3) [Ref] which means that it is a very heavily used and "industry-leading" security measure. If you're going to work in the guts of Android, a little knowledge of SELinux goes a long way... hence why I'm trying to learn a little about it.
So, a more secure Linux: access control is mandatory (default denial - anythong not explicilty allowed is denied), more fine grained (no longer just root and not-root) and also implements the principle of least-privilege.
There are thee forms of access control, the only one I've made notes on is Type Enforcement (TE), which is the primary SELinux mechanism.
The basic, 30k foot view of SELinux operation is this... Whenever a process accesses a file (this could be disk-based, a socket or shared memory, for example) or some other resource, this is intercepted in the kernel by SELinux. It will check all of the rules in the security policy and if the rules allow it access is granted, otherwise it is denied. The same is true when a user attempts to start a process. Note though that it runs after the built in Linux DAC. If the DAC blocks it SELinux won't even get a look in.
The SELinux Parlance
Cribbed almost verbatim from:
|User||Linux users mapped 1-to-1 to SELinux users.|
|Roles||Gateway between user and process. Roles defines which users can access which processes.|
|Subject||Person, process, or device. Anything that can affect an object.|
|Object||Anything that can be acted upon. E.g. file.|
|Permissions||Actions that a subject can perform on an object are the subject's permissions.|
|Domain||Domains are for Subjects. Security context associated with a process: it tells the process what it can and can't do.|
|Type||Types are for Objects: Dictates the objects purpose.|
|Policy||Set of rules used to make access control decisions.|
|Type Enforcement (TE)||Where a process running within a particular domain can perform only certain operations on certain types of objects.|
SELinux can be run in one of three modes:
- Enforcing: Policy is actively enforced.
- Permissive: Policy is not enforcedm but violations are still logged. Good for debug.
- Disabled: Not running :(
You can check what mode you're in by running either of the commands
All processes and files have a security context. A security context defines the security settings applied to a subject (person, process, or device). I guess the entire set of security contexts applied to everything in a system constitutes the security policy.
Security context: security settings applied to a person, process or device (aka "object").
The SELinux security context (aka "(security) label") is applied via a label associated with every user, process and resource. To put it another way, we can say that the rights of a process depend on it's security context. A security context is defined as follows:
type is used for type enforcement (TE), the role and level fields I will
Access is only allowed between types via the security policy and every process and resources used by that processes must have a security context (remember denial by default).
A "domain" is a little bit of jargon you'll hear a lot: The security context associated with a process is called the processes' domain.
When a type is associated with a process, it defines what processes (or domains) the SELinux user (the subject) can access.
When a type is associated with an object, it defines what access permissions the SELinux user has to that object.
So... we label all of our resources and all of our subjects and then define rules which say which subjects can do what with which objects.
Get SELinux Running On Ubuntu?
- Android Security Internals, chapter 12.
The SELinux Ubuntu Setup
Okay, to do this I am going to follow the debian tutorial as the Ubuntu one points to it.
Following the instructions went pretty well. I now have SELinux running in permissive mode on my desktop:
sudo apt-get install selinux-basics selinux-policy-default auditd sudo cp ~/Downloads/_load_selinux_policy /usr/share/initramfs-tools/scripts/init-bottom update-initramfs -u sudo update-initramfs -u selinux-activate sudo selinux-activate sudo reboot now sudo check-selinux-installation sudo audit2why -al
The last command
audit2what -al outputs a shed load of denial messages. Unfortunately
that's where the first references Debian setup tutorial ends.
In an earlier paragraph we talked about Linux users being mapped 1-to-1 onto SELinux users. Let's see what this new setup has configured for us...
~$ sudo semanage login -l Login Name SELinux User MLS/MCS Range Service __default__ unconfined_u SystemLow-SystemHigh * root unconfined_u SystemLow-SystemHigh * system_u system_u SystemLow-SystemHigh *
We can also see what roles exist:
~$ seinfo -r Roles: 14 auditadm_r dbadm_r guest_r staff_r user_r logadm_r object_r secadm_r sysadm_r system_r webadm_r xguest_r nx_server_r unconfined_r
We can also see the security contexts in terns of rolls and types that users a labelled with:
~$ id -Z unconfined_u:unconfined_r:unconfined_t:SystemLow-SystemHigh
Remember when we said a security context looked like "
Well, here is the only security context in our system. The user
has the roll
unconfined_r, with a type
So, have our files been labelled as the tutorial claimed? Lets see...
~$ ls -lZ total 84 drwxrwxr-x. 3 jh jh unconfined_u:object_r:user_home_t:SystemLow 4096 Feb 3 2017 Android drwxrwxr-x. 3 jh jh unconfined_u:object_r:user_home_t:SystemLow 4096 Feb 3 2017 AndroidStudioProjects drwxrwxr-x. 2 jh jh unconfined_u:object_r:user_home_t:SystemLow 4096 May 16 19:57 bin drwxr-xr-x. 10 jh jh unconfined_u:object_r:user_home_t:SystemLow 4096 Aug 29 17:34 Desktop drwxr-xr-x. 4 jh jh unconfined_u:object_r:user_home_t:SystemLow 4096 May 1 18:31 Documents ...
Here we see that, for example, the directory
Android has a security context
unconfined_u:object_r:user_home_t:SystemLow. This means that, if we are using
type enforcement (TE), any user that has the type
user_home_t or is, in fact,
unconfined_u can access the directory.
But where is all of this defined? Well, it appears the SELinux policy is compiled and exists in binary trees, which are compiled from source trees [Ref]. Binary policy files are used for performance reasons [Ref]. Doing a little grep we find this:
~$ grep -R user_home_t /etc/selinux/default/ ... /etc/selinux/default/contexts/files/file_contexts.homedirs:/home/[^/]*/.+ unconfined_u:object_r:user_home_t:s0 /etc/selinux/default/contexts/files/file_contexts.homedirs:/root/.+ unconfined_u:object_r:user_home_t:s0 ...
So, the file
file_contexts.homedirs is defining a rule that matches all direct
/home and labels them with the security context
unconfined_u:object_r:user_home_t:s0. Presumably this was compiled into a binary
policy tree, which was applied to create the default labelling of the file system when I first
setup SELinux, following the Debian tutorial referenced.