Linux Security

Security-Enhanced (SE) Linux

References

To Read

https://www.systutorials.com/docs/linux/man/1-audit2why/

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:

  1. If the resource available to anyone, the the process can access it,
  2. Otherwise if the process and resource are in the same group then the the process can access it,
  3. Otherwies if the process and resource are owned by the same user, the process can access it,
  4. 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:

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:

TermMeaning
UserLinux users mapped 1-to-1 to SELinux users.
RolesGateway between user and process. Roles defines which users can access which processes.
SubjectPerson, process, or device. Anything that can affect an object.
ObjectAnything that can be acted upon. E.g. file.
PermissionsActions that a subject can perform on an object are the subject's permissions.
DomainDomains are for Subjects. Security context associated with a process: it tells the process what it can and can't do.
TypeTypes are for Objects: Dictates the objects purpose.
PolicySet 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.

Modes

SELinux can be run in one of three modes:

  1. Enforcing: Policy is actively enforced.
  2. Permissive: Policy is not enforcedm but violations are still logged. Good for debug.
  3. Disabled: Not running :(

You can check what mode you're in by running either of the commands getenforce or sestatus.

Security Contexts

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:

user:role:type:level

The field type is used for type enforcement (TE), the role and level fields I will ignore.

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?

References

  • https://wiki.debian.org/SELinux/Setup
  • https://www.centos.org/docs/5/html/Deployment_Guide-en-US/rhlcommon-chapter-0001.html
  • 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 "user:role:type:level"? Well, here is the only security context in our system. The user unconfined_u has the roll unconfined_r, with a type unconfined_t.

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, the user 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 subdirectories of /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.