Four semanage commands to keep SELinux in enforcing mode
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.
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.]
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.
semanage boolean command
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.
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.
-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
$ sudo semanage boolean -m --off httpd_ssi_exec
You can also list the locally customized booleans by adding the
$ 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.
semanage fcontext command
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.
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
Just like the booleans, you can view any locally-customized file contexts by adding the
$ 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.
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.
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
-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.
selinux_permissive module can be used to place a domain into permissive mode. See
ansible-doc selinux_permissive for examples.
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.