Traditional security within the system has been based on discretionary access control (DAC) techniques, whereby normally each program has full control over the access to its resources. If a specific program (or the user permitting) decides to make an incorrect access (for example, leaving confidential data open, whether through negligence or malfunctioning). Therefore in DAC, a user has full control over the objects that belong to him or her and the programs he or she executes. The executed program will have the same permissions as the user who is executing it. Therefore, the system's security will depend on the applications that are being executed and on the vulnerabilities that these may have or on the malicious software that these may include,and will especially affect the objects (other programs, files or resources) to which the user has access. In the case of the root user, this would compromise the global security of the system.
On a separate note, mandatory access control (MAC) techniques, develop security policies (defined by the administrator) where the system has full control over the rights of access granted over each resource. For example, we can give access to files with permissions (of the Unix type), but, with MAC policies, we have extra control to determine explicity what files a process is allowed to access and what level of access we wish to grant. Contexts that specify in what situations an object can access another object are established.
SELinux [NSAb] is a MAC type component recently included in branch 2.6.x of the kernel, which the distributions are progressively incorporating: Fedora/Red Hat have it enabled by default (although it is possible to change it during the installation) and it is an optional component in Debian.
SELinux implements MAC-type security policies, which allow more refined access permissions than traditional UNIX file permissions. For example, the administrator could allow data to be added to a log file, but not to rewrite or truncate it (techniques commonly used by attackers to erase their tracks). In another example, we could allow network programs to link to the port (or ports) they require, but deny access to other ports (for example, it could be a technique that helps to control certain Trojans or backdoors).
SELinux was developed by the US NSA agency with direct contributions from various companies for UNIX and free systems, such as Linux and BSD. It was freed in the year 2000 and since then it has been integrated in different GNU/Linux distributions.
Example 9-14. Web sites
Some resources on SELinux:
In SELinux we have a domain-type model, where each process runs in a so-called security context and any resource (file, directory, socket etc.) has a type associated to it. There is a set of rules that indicates what actions can be performed in each context on each type. One of the advantages of this context-type model is that the policies defined can be analysed (there are tools) for determining what flows of information are allowed, for example, to detect various routes of attack, or whether the policy is sufficiently complete so as to cover all potential accesses.
It has what is known as the SELinux policy database which controls all aspects of SELinux. It determines what contexts each program can use to run and specifies what types of each context can be accessed.
In SELlinux, every system process has a context consisting of three parts: an identity, a role and a domain. The identity is the name of the user account or system_u for system processes or user_u if the user has no defined policies. The role determines what the associated contexts are. For example user_r is not allowed to have the context sysadm_t (main domain for the system administrator). Therefore a user_r with identity user_u cannot obtain a sysadm_t context in anyway. A security context is always specified by this set of values like:
is the context for the system administrator, defines its identity, role and security context.
For example, in a machine with SELinux activated (in this case a Fedora) we can see the -Z option of the ps of contexts associated to the processes:
# ps ax –Z
and with ls using the -Z option we can see the contexts associated to files and directories:
# ls -Z drwxr-xr-x josep josep user_u:object_r:user_home_t Desktop drwxrwxr-x josep josep user_u:object_r:user_home_t proves -rw-r--r-- josep josep user_u:object_r:user_home_t yum.conf
and from the console we can find out our current context with:
$ id -Z user_u:system_r:unconfined_t
In relation to the functioning mode, SELinux presents two modes known as: permissive and enforcing. In permissive, unauthorised access is allowed, but is audited in the corresponding logs (normally directly over /var/log/messages or, depending on the distribution, with the use of audit in /var/log/audit/audit.log). In enforcing mode no type of access that is not allowed by the defined policies is permitted. We can also deactivate SELinux through its configuration file (normally in /etc/selinux/config), by setting SELINUX=disabled.
We need to take care with activating and deactivating SELinux, especially with the labelling of contexts in the files, since during periods of activation/deactivation labels could be lost or simply not made. Likewise, when backing up the file system, we need to make sure that the SELinux labels are preserved.
Another possible problem to be taken into account is the large number of security policy rules that can exist and that can cause limitations in terms of controlling the services. In the face of a specific type of malfunctioning, it is worth determining first that it is not precisely SELinux that is preventing functioning due to a too strict security limitation (see the section on SELinux criticism) or options that we did not expect to have activated (can require a change in the configuration of the Booleans as we will see).
In relation to the policy applied, SELinux supports two different types: targered and strict. In targered policy type, most processes operate without restrictions and only specific services (some daemons) are put into different security contexts that are confined to security policy. In strict policy type, all processes are assigned to security contexts and confined to defined policies, in such a way that any action is controlled by the defined policies. In principle, these are the two types of policies defined in general, but the specification is open to include more.
A special case of policy is the multilevel security (MLS), which is a multilevel policy of the strict type. The idea is to define different levels of security within the same policy, with security contexts having an additional field of access level associated to them. This type of security policy (like MLS) tends to be used in governmental and military organisations, where there are hierarchical structures with different levels of privileged information, levels of general access and different capabilities of action at each level. In order to obtain some security certifications, we need to have this type of security policy.
We can define what type of policy will be used in /etc/selinux/config, variable SELINUXTYPE. The corresponding policy and its configuration will normally be installed in the directories /etc/selinux/SELINUXTYPE/, for example, in the policy subdirectory we tend to find the binary file of the policy compiled (which is what is loaded in the kernel, when SELinux is initiated).
SELinux architecture consists of the following components:
Code at kernel level
Shared SELinux library
The security policy (the database)
Let us take a look at a few considerations with regards to each component:
The kernel code monitors the system's activity and ensures that the requested operations are authorised under the current SELinux security policy configuration, not allowing unauthorised operations and normally generating log entries of denied operations. The code is currently integrated in kernels 2.6.x and, in previous ones, is offered as a series of patches.
Most SELinux utilities and components not directly related to the kernel use the shared library called libselinux1.so, which provides an API for interacting with SELinux.
The security policy is what is integrated in the SELinux rules database. When the system starts up (with SELinux activated), it loads the binary policy file, which normally resides in /etc/security/selinux (although it can vary according to the distribution).
The binary policy file is created on the basis of a compilation (via make) of the policy source files and some configuration files.
Some distributions (such as Fedora) do not install the sources by default, which we can normally find in /etc/security/selinux/src/policy or in /etc/selinux.
Normally, these sources consist of various groups of information:
The files related to the compilation, makefile and associated scripts.
Initial configuration files, associated users and roles.
Type-enforcement files, which contain most sentences of the policy language associated to a particular context. We need to take into account that these files are enormous, typically tens of thousands of lines, which means that we can encounter the problem of finding bugs or defining changes in policies.
And files that serve to label the contexts of the files and directories during loading or at specific moments.
Tools: include commands used to administrate and use SELinux. Modified versions of standard Linux commands. And Tools for the analysis of policies and for development.
Let's look from this last section at the typical tools that we can generally find:
Also, other common programs are modified to support SELinux such as:
cron: modified to include the contexts for jobs in progress by cron.
login: modified to place the initial security context for users when they log in the system.
logrotate: modified to preserve the context of the logs when they have been compiled.
pam: modified to place the user's initial context and to use the SELinux API and obtain privileged access to password information.
ssh: modified to place the user's initial context when the user logs in the system.
And various additional programs that modify /etc/passwd or /etc/shadow.
Also some distributions include tools for managing SELinux, such as the setools(-gui), which carry several tools for managing and analysing policies. As well as specific tools for controlling the contexts associated to the different services supported by SELinux in the distribution, for example the system-config-security level tool in Fedora has a section for configuring SELinux as we can see in the following figure:
In the figure, we can see the Booleans configuration for different services and generic options, including the web server. We can also obtain this list with the getsebool -a command and, with the setsebool/togglesebool command, we can activate/deactivate the options.
In Fedora, for example, we find Booleans support for (among others): Cron, FTP, httpd (apache), dns, grub, lilo, nfs, nis, cups, pam, ppd, samba, protections against undue access to the process memory etc.
The configuration of Booleans allows the SELinux policy to be tailored during running time. Booleans are used as conditional values of the applied policy rules, which allow policy modifications without having to load a new policy.
Some administrators and security experts have criticised SELinux in particular for being too complex to configure and administer. It is argued that due to its intrinsic complexity, even experienced users can commit errors, leaving the SELinux configuration insecure or unusable and the system vulnerable. Although to a certain extent this is debatable, since even if we have SELinux badly configured, the UNIX permissions would remain active, SELinux will not allow an operation that the original permissions already did not allow, in fact, we can see this as another stricter level of security.
Performance factors may also be affected, due to the enormous size of the policies, which use up a lot of memory and take a lot of time to load, and, in some cases, due to the processing of rules. We need to bear in mind that we are dealing with a system of practically 10,000 policy rules. And that this number can be even greater if we select the strict type policy where we need to specify absolutely all the options to be controlled. Normally, the processing of policy in binary format and the use of Booleans in order to disable rules allows the system to be used more efficiently.
Another aspect that tends to bother administrators is the additional problem of determining, in the event of a malfunction, what the origin or initial cause is. Because it is common for us to find in the end that the problem has stemmed from an excessively restrictive configuration (perhaps due to unawareness on the part of the administrator) of SELinux for a particular service.
In the last instance, we need to point out the extensive support that SELinux offers for security and that, as administrators, we need to be aware of the capabilities and dangers of any new technique that we employ.