Skip to content

Linux Security Modules

Linux Security Modules (LSM) is a framework that allows the Linux kernel to support a variety of computer security models while avoiding favouritism toward any single security implementation. The framework is lightweight, general purpose, and enables access control.

DAC (Discretionary Access Control) is the standard Linux security model based on user/group ownership and rwx permissions. While effective, it has limitations. LSMs provide Mandatory Access Control (MAC) which adds an additional layer of security that even the root user must obey.

For a long time, the only enhanced security model implemented was SELinux. When the project was first floated upstream in 2001 to be included directly in the kernel, there were objections about using only one approach to enhanced security.

As a result, the LSM approach was adopted, where alternative modules to SELinux could be used as they were developed and was incorporated into the Linux kernel in 2003.

Originally, only one LSM could be used at a time as they can potentially modify the same parts of the Linux kernel. However, it is now possible to stack them with some care. LSMs are now considered as either major or minor when configuring their combination.

The current LSM implementations are:


SELinux was originally developed by the United States NSA (National Security Administration) and has been integral to RHEL for a very long time, which has brought it a large usage base.

Operationally, SELinux is a set of security rules that are used to determine which processes can access which files, directories, ports, and other items on the system.

It works with three conceptual quantities:

  1. Contexts: Labels to files, processes, and ports. Examples of contexts are SELinux user, role and type.
  2. Rules: They describe access control in terms of contexts, processes, files, ports, users, etc.
  3. Policies: They are a set of rules that describe what system-wide access control decisions should be made by SELinux.

A SELinux context is a name used by a rule to define how users, processes, files and ports interact with each other. As the default policy is to deny any access, rules are used to describe allowed actions on the system.

SELinux can be run under one of three modes. These modes are selected (and explained) in a file (usually /etc/selinux/config) whose location varies by distribution (it is often either at /etc/sysconfig/selinux or linked from there).

ModeDescription
EnforcingAll SELinux code is operative and access is denied according to policy. All violations are audited and logged.
PermissiveEnables SELinux code, but only audits and warns about operations that would be denied in enforcing mode.
DisabledCompletely disables SELinux kernel and application code, leaving the system without any of its protections.

The sestatus utility can display the current mode and policy.

To examine or set the current mode:

Terminal window
getenforce
Enforcing
sudo setenforce Permissive
getenforce
Permissive

setenforce can be used to switch between enforcing and permissive modes on the fly while the system is in operation. However, changing in or out of the disabled mode cannot be done this way.

There are at least two ways to disable SELinux:

  • Configuration file: Edit the SELinux configuration file (usually /etc/selinux/config) and set SELINUX=disabled. This is the default method and should be used to permanently disable SELinux.
  • Kernel parameter: Add selinux=0 to the kernel parameter list when rebooting.

Note: Disabling SELinux on systems in which SELinux will be re-enabled is not recommended. It is preferable to use the permissive mode instead, so as to avoid relabeling the entire filesystem, which can be time-consuming.

The same configuration file that sets the mode also sets the SELinux policy. Multiple policies are allowed, but only one can be active at a time.

PolicyDescription
targetedThe default policy. SELinux is more restricted to targeted processes. User processes and init processes are not targeted, while network service processes are targeted.
minimumA modification of the targeted policy where only selected processes are protected.
MLSThe Multi-Level Security policy is much more restrictive; all processes are placed in fine-grained security domains with particular policies.

Contexts are labels applied to files, directories, ports, and processes. There are four SELinux contexts:

  • User
  • Role
  • Type
  • Level

The label naming convention determines that type context labels should end with _t, as in kernel_t.

Use the -Z option to see the context:

Terminal window
ls -Z
ps auZ

Use the chcon command to change context:

Terminal window
chcon -t etc_t somefile
chcon --reference somefile someotherfile
ls -Z
-rw-rw-r--. dog dog unconfined_u:object_r:etc_t:s0 somefile

Many standard command line commands, such as ls and ps, were extended to support SELinux. Often the parameter Z is passed:

Terminal window
ps axZ
LABEL PID TTY STAT TIME COMMAND
system_u:system_r:init_t:s0 1 ? Ss 0:04 /usr/lib/systemd/systemd ...
system_u:system_r:kernel_t:s0 2 ? S 0:00 [kthreadd]
...
system_u:system_r:httpd_t:s0 7490 ? Ss 0:00 /usr/sbin/httpd -DFOREGROUND

The restorecon command resets the file context based on the parent directory and policy rules:

Terminal window
# Create a new directory
mkdir /virtualHosts
ls -Z
# ... unconfined_u:object_r:default_t:s0 virtualHosts
# Add a context for the new directory
semanage fcontext -a -t httpd_sys_content_t /virtualHosts
# Apply the context
restorecon -RFv /virtualHosts
# restorecon reset /virtualHosts context
# unconfined_u:object_r:default_t:s0->system_u:object_r:httpd_sys_content_t:s0
ls -Z
# ... system_u:object_r:httpd_sys_content_t:s0 virtualHosts

The context change from default_t to httpd_sys_content_t is only applied after the call to restorecon.

SELinux policy behavior can be configured at runtime without rewriting the policy. This is accomplished by configuring SELinux Booleans:

  • getsebool – to see booleans
  • setsebool – to set booleans
  • semanage boolean -l – to see persistent boolean settings
Terminal window
setsebool allow_ftpd_anon_write on
getsebool allow_ftpd_anon_write
allow_ftpd_anon_write -> on
semanage boolean -l | grep allow_ftpd_anon_write
allow_ftpd_anon_write -> off
# Note: not persistent by default. Use -P flag:
setsebool -P allow_ftpd_anon_write on
semanage boolean -l | grep allow_ftpd_anon_write
allow_ftpd_anon_write -> on
# Now persistent.

SELinux comes with a set of tools that collect issues at run time, log these issues and propose solutions. These utilities are provided by the setroubleshoot-server package.

  • After installing the setroubleshoot-server utility, restart the auditd service
  • It stores raw messages in /var/log/audit/audit.log
  • Moves messages to /var/log/messages
  • You can use sealert to see detailed messages
Terminal window
echo 'File created at /root' > rootfile
mv rootfile /var/www/html/
wget -O - localhost/rootfile
# HTTP request sent, awaiting response... 403 Forbidden
tail /var/log/messages
# ... SELinux is preventing /usr/sbin/httpd from getattr access on the file.
# For complete SELinux messages. run sealert -l <id>
# Suggested fix:
grep httpd /var/log/audit/audit.log | audit2allow -M mypol
semodule -i mypol.pp

AppArmor is an LSM alternative to SELinux. Support for it has been incorporated in the Linux kernel since 2006. It has been used by SUSE, Ubuntu and other distributions.

AppArmor:

  • Provides Mandatory Access Control (MAC)
  • Allows administrators to associate a security profile to a program which restricts its capabilities
  • Is considered easier (by some but not all) to use than SELinux
  • Is considered filesystem-neutral (no security labels required)

In addition to manually specifying profiles, AppArmor includes a learning mode, in which violations of the profile are logged, but not prevented. This log can then be turned into a profile, based on the program’s typical behavior.

Distributions that come with AppArmor tend to enable it and load it by default. Note that the Linux kernel has to have it turned on as well, and, in most cases, only one LSM can run at a time.

Terminal window
sudo systemctl [start|stop|restart|status] apparmor
# To cause to be loaded or not loaded at boot:
sudo systemctl [enable|disable] apparmor
# To see the current status:
sudo apparmor_status
# apparmor module is loaded.
# 25 profiles are loaded.
# 25 profiles are in enforce mode.
# /sbin/dhclient
# ...

Profiles restrict how executable programs, which have pathnames on your system, can be used.

Processes can be run in either of the two modes:

ModeDescription
Enforce ModeApplications are prevented from acting in ways which are restricted. Attempted violations are reported to the system logging files. This is the default mode. A profile can be set to this mode with aa-enforce.
Complain ModePolicies are not enforced, but attempted policy violations are reported. This is also called the learning mode. A profile can be set to this mode with aa-complain.

Linux distributions come with pre-packaged profiles, typically installed either when a given package is installed, or with an AppArmor package, such as apparmor-profiles. These profiles are stored in /etc/apparmor.d.

Terminal window
ls /etc/apparmor.d
abstractions usr.lib.dovecot.anvil usr.lib.telepathy
apache2.d usr.lib.dovecot.auth usr.sbin.avahi-daemon
bin.ping usr.lib.dovecot.config usr.sbin.cups-brows
...
ProgramUse
apparmor_statusShow status of all profiles and processes with profiles
apparmor_notifyShow a summary for AppArmor log messages
complainSet a specified profile to complain mode
enforceSet a specified profile to enforce mode
disableUnload a specified profile from the current kernel and prevent from being loaded on system startup
logprofScan log files, and, if AppArmor events not covered by existing profiles have been recorded, suggest how to take into account, and, if approved, modify and reload
easyprofHelp set up a basic AppArmor profile for a program