For years, SELinux has assisted in preventing damage to systems from zero-day exploits. This tool is also useful for virtual machine isolation and is required for container isolation. Yet SELinux is still commonly disabled or placed in permissive mode.
SELinux’s targeted
policy is designed to isolate various process domains while still allowing interaction between services as needed. Just a few commands are needed for an administrator to configure a system to use this policy with their customized applications, keeping SELinux in enforcing mode.
[Learn more about using the SELinux policy documentation here.]
The semanage
command is used to adjust file contexts, port contexts, and booleans. If there is still a conflict with a particular process, that domain can be placed into permissive mode until further investigation can be completed. This leaves the rest of the system protected in enforcing mode.
With just the four semanage
commands below, most systems can be configured so your customized applications run with SELinux in enforcing mode.
The semanage boolean
command
The targeted
policy includes many booleans to enable and disable sets of allow
rules, making the assumption that services have multiple use cases and are run differently in each environment. The use of booleans allows different rule sets for different use cases: A web server in an academic environment may need to allow students to publish content from their home directories, while a corporate, public-facing site may need to refuse access to any user home directories, limit SSI executables, and display data stored on an NFS share.
The httpd_selinux
man page describes the use of all booleans provided for the httpd
domain as well as sample setsebool
commands to persistently enable each boolean. An alternate (and newer) way to see and change these booleans is with the semanage boolean
command.
The -l
option lists all the booleans in the loaded policy. You can then filter for a keyword:
$ sudo semanage boolean -l | grep httpd
httpd_anon_write (off , off) Allow httpd to anon write
httpd_builtin_scripting (on , on) Allow httpd to builtin scripting
httpd_can_check_spam (off , off) Allow httpd to can check spam
httpd_can_connect_ftp (off , off) Allow httpd to can connect ftp
httpd_can_connect_ldap (off , off) Allow httpd to can connect ldap
This output includes the name of the boolean, the current and persistent state of the boolean, and a brief description of how the boolean is used.
To change the boolean with semanage
use:
$ sudo semanage boolean -m --off httpd_ssi_exec
You can also list the locally customized booleans by adding the -C
option:
$ sudo semanage boolean -l -C
SELinux boolean State Default Description
httpd_ssi_exec (off , off) Allow httpd to ssi exec
virt_sandbox_use_all_caps (on , on) Allow virt to sandbox use all caps
virt_use_nfs (on , on) Allow virt to use nfs
The man pages for each SELinux domain have descriptions of all provided booleans for those domains. For more options when modifying SELinux booleans with semanage
, see the semanage-boolean
man page.
You can automate these semanage
commands with their related Ansible modules and roles. The Ansible module for semanage boolean
is seboolean
. This, and the related modules described below, are used by the roles provided by the linux-system-roles
package in Fedora or rhel-system-roles
package in Red Hat Enterprise Linux. The Red Hat package is available beginning with Red Hat Enterprise Linux 7.4 and can be found in the "Extras" repository.
The semanage fcontext
command
The targeted
policy provides file context information for application file—including data, log, and runtime files—default and common alternate locations. These context definitions are the mappings that the restorecon
command uses to verify or change file context.
The semanage fcontext
command can be used to list file context definitions, and add more. The -l
option shows all of the contexts in the loaded policy. You can then filter for a keyword:
$ sudo semanage fcontext -l | grep sshd
/etc/rc\.d/init\.d/sshd regular file system_u:object_r:sshd_initrc_exec_t:s0
/etc/ssh/primes regular file system_u:object_r:sshd_key_t:s0
/etc/ssh/ssh_host.*_key regular file system_u:object_r:sshd_key_t:s0
/etc/ssh/ssh_host.*_key\.pub regular file system_u:object_r:sshd_key_t:s0
/usr/lib/systemd/system/sshd-keygen.* regular file system_u:object_r:sshd_keygen_unit_file_t:s0
This output includes the regular expression pattern for the target filenames, the type of file, and the file context to assign to the matching filename.
The related man page, in this case man sshd_selinux
, includes a list of managed files and a description of each file context available for the domain. There are also sample commands to specify and apply alternate labeling.
For example, if you wanted to store the sshd
host keys in a separate subdirectory, you could run the following two commands:
$ sudo semanage fcontext -a -t sshd_key_t '/etc/ssh/keys(/.*)?'
$ sudo restorecon -r /etc/ssh/keys
In this example, the regular expression will match the directory /etc/ssh/keys
as well as any subdirectories and files found in the /etc/ssh/keys
directory.
Just like the booleans, you can view any locally-customized file contexts by adding the -C
option:
$ sudo semanage fcontext -l -C
SELinux fcontext type Context
/usr/share/dnfdaemon/dnfdaemon-system all files system_u:object_r:rpm_exec_t:s0
For more options when modifying SELinux file contexts, see the semanage-fcontext
man page.
You can automate the semanage fcontext
command with the Ansible sefcontext
module. The restorecon
command will still need to be run with a separate command module. See ansible-doc sefcontext
for examples. The selinux
system role includes both tasks.
The semanage port
command
In addition to file contexts, the targeted
policy also defines port contexts. Just as with the booleans and file contexts, the domain-specific man pages list the defined types, and may also show the sample commands needed to run a service on a different port.
View the port contexts with:
$ sudo semanage port -l | grep http
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
When running a service on a custom port, you must change the configuration file for the service and also add an SELinux port definition. Without the port definition, the service will fail to start and log an error similar to "cannot bind to port".
Add a port definition with:
$ sudo semanage port -a -t http_cache_port_t -p tcp 8010
When specifying the port, you must include both the protocol and the port number. Additionally, only one type can be defined for each protocol and port number. For more options when modifying SELinux port contexts, see the semanage-port
man page.
You can automate the semanage-port
command with the seport
Ansible module.
The semanage permissive
command
Instead of moving the entire system to permissive mode—or worse, disabling SELinux completely—you can place a single domain into permissive mode. A domain in permissive mode allows all actions while still logging any would be denials. The other domains on the system remain in enforcing mode, which both logs and denies actions which are not specifically allowed.
The man pages for common domains list the SELinux types that can be placed into permissive mode.
To list any domains currently in permissive mode use:
$ sudo semanage permissive -l
At initial installation, it is unlikely that there will be any domains in permissive mode.
To place a domain into permissive mode use:
$ sudo semanage permissive -a squid_t
The -d
option deletes a permissive domain, thus reenabling enforcing mode for that domain.
For more options when placing domains into permissive mode, see the semanage-permissive
man page.
The Ansible selinux_permissive
module can be used to place a domain into permissive mode. See ansible-doc selinux_permissive
for examples.
The files
All of the semanage
commands that add or modify the targeted policy configuration store information in *local
files under the /etc/selinux/targeted
directory tree. These files all have warnings that they should not be edited directly but are used to preserve customization. When the SELinux and policy packages are updated, these local customization files are left in place and applied to the updated policy.