SELinux basics
I recently came in touch with SELinux when I had to write/extend a policy for a commercial app. This post is some kind of notepad/cheatsheet I created while learning the topic. The aim is to document the concepts and commands which are necessary in order to be able to understand the basics and modify/adjust an existing SELinux policy.
What is SELinux
SELinux is an implementation of a mandatory access control mechanism (MAC) in the Linux kernel. It enforces rules on files and processes in a Linux system, and on their actions, based on defined policies.
It checks for allowed operations after standard discretionary access control mechanism (DAC = the traditional Unix permissions) is checked.
Linux processes are referred to as subjects. Files, including directories and devices, are referred to as objects.
Basic Concepts
Security Context
A security context, or security label, is the mechanism used to classify resources, such as processes and files.
Processes and files are labeled with an SELinux security context that contains information, such as an SELinux user
, role
, type
, and optionally, a level
. When running SELinux, all of this information is used to make access control decisions.
The security context is usually written in the format:
User:Role:TypeOrDomain:Level
As a naming conventions the following suffixes are used: _u
for user, _r
for role, _t
for type (or domain when it is for a running process).
All processes and files have a SELinux security context.
Security Context of Processes
The security context of processes can be shown with ps -Z
, e.g.:
> ps -ZC httpd
LABEL PID TTY TIME CMD
system_u:system_r:httpd_t:s0 3826 ? 00:00:00 httpd
where the LABEL system_u:system_r:httpd_t:s0
is the security context.
Security Context of Files and Directories
The security context of a file or directory is stored as extended file attribute. It can be shown with ps -Z
, e.g.:
> ls -Z /var/www/
drwxr-xr-x. root root system_u:object_r:httpd_sys_script_exec_t:s0 cgi-bin
drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 html
or with stat
, e.g.:
> stat -c %C /var/www/html/
system_u:object_r:httpd_sys_content_t:s0
where the part system_u:object_r:httpd_sys_content_t:s0
is the security context.
Subject
A subject is an active process with a security context associated with it.
Object
An object is a resource such as files, sockets, pipes or network interfaces that are accessed by processes (subjects)
Domain
A domain is part of the security context of a subject (process):
User:Role:Domain:Level
Type
A type is part of the security context of an object (file):
User:Role:Type:Level
Policy
A Policy specifies granted permissions in an SE-Linux system.
It basically defines:
- types for file objects and domains for processes
- rules on security contexts (see above), specifying which domains are allowed to access which types.
On an SELinux system, everything is denied by default, only what is specifically allowed by a rules is permitted. An SELinux policy is a set of rules specifying what is allowed on a system.
Linux distributions with SELinux support usually ship with a default policy containing hundreds or even thousands of rules.
On Red Hat/CentOS the default policy is the “targeted” policy. When using targeted policy, processes that are targeted run in a confined domain, and processes that are not targeted run in an unconfined domain.
Enabling/disabling SELinux
SELinux can run in three different modes:
- enforcing: SELinux policy is enforced. SELinux denies access based on SELinux policy rules.
- permissive: SELinux does not deny access, but denials are logged for actions that would have been denied if running in enforcing mode.
- disabled: SELinux disabled
Current status can be checked with getenforce
or sestatus
.
The mode is configured in the default SELinux config file /etc/selinux/config
:
SELINUX=[enfocing|permissive|disabled]
A system reboot is required for changes to take effect.
To switch between enforcing and permissive setenforce [0|1]
can be used.
SELinux type enforcement
In SELinux, all subjects and objects have a type identifier associated to them – the type identifier is the _t
part of the security context (see above).
Type enforcement is the feature of SELinux that uses that type to enforce rules laid down by policy.
A type enforcement rule has the following structure:
allow <domain> <type>:<class> { <permissions> };
<domain>
is the context of a process<type>
is the context of the resource on which the process is acting<class>
is the kind of the resource<permissions>
are the permissions of the<domain>
on the<type>
of<class>
Example:
allow innd_t usr_t:file { getattr read ioctl }
Reads as: allow processes running in the innd_t
domain to do getattr
, read
and ioctl
on file
s
of type usr_t
.
Querying SELinux rules
To query SELinux if a certain rule is active, sesearch
can be used. E.g., to search rules allowing file
write
access from processes of domain httpd_t
:
> sesearch --allow --source httpd_t --target httpd_sys_content_t --class file --perm write
Found 1 semantic av rules:
allow httpd_t httpdcontent : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
Controlling file contexts
Listing file contexts mappings
To list all default file context mapping definition, specified in the current policy:
> semanage fcontext -l
...
/.* all files system_u:object_r:default_t:s0
/etc/.* all files system_u:object_r:etc_t:s0
/lib/.* all files system_u:object_r:lib_t:s0
/usr/.*\.cgi regular file system_u:object_r:httpd_sys_script_exec_t:s0
/opt/.*\.cgi regular file system_u:object_r:httpd_sys_script_exec_t:s0
/root(/.*)? all files system_u:object_r:admin_home_t:s0
/dev/[0-9].* character device system_u:object_r:usb_device_t:s0
...
Note that semanage fcontext -l
does not show the “auto-generated” contexts, such as with home directory contexts.
To get the default SELinux security context for the specified path from the file contexts configuration, matchpathcon can be used:
> matchpathcon /etc/
/etc system_u:object_r:etc_t:s0
Note that the default context is not necessarily the currently applied context. So the context shown by matchpathcon FILE
and ls -Z FILE
don’t have to be the same. This is the case when changing a file context mapping definition but it’s not yet applied with restorecon
.
Changing file contexts (labeling files)
Making temporary changes
To temporally label a FILE the with type var_log_t, use chcon
:
chcon -t var_log_t FILE
ls -Z
will immediately reflect the canges. But the changes are not stored in the policy, only the file labels are changed. So matchpathcon FILE
will show the same labels as before chcon
.
A system reboot or calling restorecon
will “revert” the changes by apply the default policy again.
Making persistent changes
Change context mapping with,
semanage fcontext
, e.g. to label files in/srv/logs/
with typevar_log_t
:semanage fcontext -a -t var_log_t "/srv/logs(/.*)?"
The new context mapping is stored persisently in the policy, e.g. when using the targeted policy, files are written to
/etc/selinux/targeted/contexts/files/
to actually apply the mapping to the files, run
restorecon
:restorecon -Rv /srv/logs
Searching file contexts
findcon
searches for files/mappings with a specified context.
If the first parameter is a file context file, findcon prints matching entries, e.g. find mappings applying to /var/cache:
> findcon /etc/selinux/targeted/contexts/files/file_contexts -p /var/cache/
/.* system_u:object_r:default_t:s0
/var/.* system_u:object_r:var_t:s0
If the first parameter is a file or directory, mathing files are printed, e.g. find files/directories with type var_t:
> findcon /var/cache -t var_t
/var/cache -d system_u:object_r:var_t:s0
/var/cache/powertop/saved_results.powertop -- system_u:object_r:var_t:s0
Deleting context definitions
File context definitions mapping label var_log_t
to /srv/logs(/.*)?
can be removed with:
semanage fcontext -d -t var_log_t "/srv/logs(/.*)?"
to actually apply the changes, run restorecon
:
restorecon -Rv /srv/logs
Controlling process contexts
Querying policies
The SELinux policy query tool sesearch
can be used to search for rules in a policy, e.g. to search for rules
allowing file
write
access from domain auditd_t
to file
s with type label auditd_log_t
:
> sesearch --allow --source auditd_t --target auditd_log_t --class file --perm write
Found 1 semantic av rules:
allow auditd_t auditd_log_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
SELinux permission denial details
One of the most important features of SELinux is, that it is able to log everything! And with everything, I mean everything. If we want, we can have SELinux even log all granted accesses, but more importantly it logs access denials.
The default location of the audit log depends on the distribution, but usually it is one of the following /var/log/audit/audit.log
, /var/log/audit.log
or /var/log/avc
(if you are not running the audit daemon auditd).
If SELinux denies access, a log entry with type=AVC
(Access Vector Cache) is written. This is an example from my audit.log:
type=AVC msg=audit(1483812519.383:165): avc: denied { create } for pid=3057 comm="gdm-session-wor" name="gdm" scontext=system_u:system_r:xdm_t:s0-s0:c0.c1023 tcontext=system_u:object_r:admin_home_t:s0 tclass=dir
Means that the gdm
proccess with pid=3057
with domain context system_u:system_r:xdm_t:s0-s0:c0.c1023
was denied to create
a dir
in a file system context tcontext=system_u:object_r:admin_home_t:s0
The timestamp 1483812519.383
is in seconds since epoch January 1st, 1970. It can be converted to a more human readable format using date -d @1483812519.383
=> Sat Jan 7 19:08:39 CET 2017
There is also the ausearch
command. It is a Linux audit related utility (not SELinux specific), which parses the audit logs and allows to query the entries in the logs. One of the advantages that it shows is that it already converts the time stamp into a human readable one:
> ausearch -m avc --start recent
time->Sat Jan 7 13:08:39 2017
type=AVC msg=audit(1483812519.383:165): avc: denied { create } for pid=3057 comm="gdm-session-wor" name="gdm" scontext=system_u:system_r:xdm_t:s0-s0:c0.c1023 tcontext=system_u:object_r:admin_home_t:s0 tclass=dir
Commands
ps -Z # show security context of processes
ls -Z [FILE] # show security context of file(s)
stat -c %C FILE # show security context of file
chcon # change file security context (temporally)
semanage ... # the SE-linux policy management tool
semanage fcontext -a # add file file context rule
semanage fcontext -d # delete file context rule
semodule # the selinux policy modules management tool
semodule -l # list installed modules
semodule -i # install module
restorecon # restore file(s) default SELinux security contexts
audit2allow # generate SELinux policy allow/dontaudit rules from logs of denied operations
audit2why # translates SELinux audit messages into a description of why the access was denied
findcon # file context search tool
findcon DIR -t TYPE # searches for files/dirs beyond DIR labeled with TYPE
sesearch # SELinux policy query tool
ausearch -m avc --start [recent|today|...] # query audit daemon logs
Resources
Very good resources on the topic:
- SELinux Tutorial on gentoo.org - a good tutorial to get into the topic
- The SELinux user guide by Red Hat - a well structured, detailed user guide