Note:
- This tutorial is available in an Oracle-provided free lab environment.
- It uses example values for Oracle Cloud Infrastructure credentials, tenancy, and compartments. When completing your lab, substitute these values with ones specific to your cloud environment.
Use SELinux on Oracle Linux
Introduction
SELinux is a set of kernel mods and user-space tools that provide another layer of system security, precise access control, system-wide admin-defined policies, and improved mitigation for privilege escalation attacks.
This tutorial guides you through using these user-space tools to help keep your system running in enforcing mode.
Objectives
In this lab, you’ll learn to:
- Check SELinux mode and status
- Understand SELinux security labels
- Work with SELinux network services
- Use SELinux users
- Change SELinux booleans
- Evaluate SELinux file contexts
Prerequisites
- A system with Oracle Linux 8 installed with the following configuration:
- a non-root user with
sudo
permissions
- a non-root user with
Setup Lab Environment
Note: When using the free lab environment, see Oracle Linux Lab Basics for connection and other usage instructions.
Create a User
An additional user allows testing the assignment of an SELinux user later in this lab.
-
If not already connected, open a terminal and connect via ssh to the ol8-server system.
ssh oracle@<ip_address_of_ol8-server>
-
Create a user and set a password.
sudo useradd -u 8000 ralph echo "ralph:oracle" | sudo chpasswd
-
Allow SSH connections.
Copy the SSH key from the
oracle
user account.sudo mkdir /home/ralph/.ssh sudo cp /home/oracle/.ssh/authorized_keys /home/ralph/.ssh/authorized_keys sudo chown -R ralph:ralph /home/ralph/.ssh sudo chmod 700 /home/ralph/.ssh sudo chmod 600 /home/ralph/.ssh/authorized_keys
-
Open a new terminal and verify the SSH connection works.
ssh ralph@<ip_address_of_ol8-server>
Then
exit
the session, and close the terminal window.
SELinux Mode and Status
Oracle Linux installs SELinux by default and runs in Enforcing
mode.
-
Confirm by checking the SELinux mode.
It should be set to
Enforcing
.getenforce
-
Check the SELinux states and modes.
sestatus
The
sestatus
command output shows the SELinux status, policy, and mode.Example Output:
SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Memory protection checking: actual (secure) Max kernel policy version: 31
SELinux Security Labels
Every process and system resource under SELinux has a security label called an SELinux context. The SELinux context, also called an SELinux label focuses on the security properties and ensures a consistent way to reference objects in the SELinux policy.
-
Show the SELinux security label for a file.
ls -ldZ /etc/passwd
Example Output:
-rw-r--r--. 1 root root system_u:object_r:passwd_file_t:s0 1892 Apr 13 14:39 /etc/passwd
The
ls
output with the-Z
option displays the four SELinux attribute fields:- user:
system_u
- role:
object_r
- type:
passwd_file_t
- security:
s0
The most important of these is the SELinux type, as the majority of SELinux
targeted
policy rules leverage SELinux types to define the allowed interaction between one object (e.g., process) and another (e.g., file). - user:
-
Get a listing of the available SELinux types.
seinfo --type | head
- The
head
command limits the output to only the first ten output lines.
The full output shows SELinux types exist for many different commands and services, such as
ssh
andsshd
. - The
-
Get a listing of specific SELinux types.
The
grep
will limit the output to only those types containing the wordssh
.seinfo -t | grep ssh
-
Get a listing of the security lables for specific processes and configuration files.
Using
ps
gets the security labels for the processes.ps -efZ | grep sshd
Example Output:
system_u:system_r:sshd_t:s0-s0:c0.c1023 root 2535 1 0 14:37 ? 00:00:00 /usr/sbin/sshd -D system_u:system_r:sshd_t:s0-s0:c0.c1023 root 18514 2535 0 15:21 ? 00:00:00 sshd: oracle [priv] unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 oracle 18528 18514 0 15:21 ? 00:00:00 sshd: oracle@pts/0 unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 oracle 23611 18529 0 15:41 pts/0 00:00:00 grep --color=auto sshd
Using
ls
gets the security labels for the configuration files.ls -lZ /etc/ssh/
Example Output:
total 600 -rw-r--r--. 1 root root system_u:object_r:etc_t:s0 577388 Oct 9 2021 moduli -rw-r--r--. 1 root root system_u:object_r:etc_t:s0 1770 Oct 9 2021 ssh_config drwxr-xr-x. 2 root root system_u:object_r:etc_t:s0 28 Feb 18 08:51 ssh_config.d -rw-------. 1 root root system_u:object_r:etc_t:s0 4268 Apr 13 14:37 sshd_config -rw-r-----. 1 root ssh_keys system_u:object_r:sshd_key_t:s0 537 Apr 13 14:37 ssh_host_ecdsa_key -rw-r--r--. 1 root root system_u:object_r:sshd_key_t:s0 197 Apr 13 14:37 ssh_host_ecdsa_key.pub -rw-r-----. 1 root ssh_keys system_u:object_r:sshd_key_t:s0 432 Apr 13 14:37 ssh_host_ed25519_key -rw-r--r--. 1 root root system_u:object_r:sshd_key_t:s0 117 Apr 13 14:37 ssh_host_ed25519_key.pub -rw-r-----. 1 root ssh_keys system_u:object_r:sshd_key_t:s0 2635 Apr 13 14:37 ssh_host_rsa_key -rw-r--r--. 1 root root system_u:object_r:sshd_key_t:s0 589 Apr 13 14:37 ssh_host_rsa_key.pub
The
sshd
daemon process uses thesshd_t
type. Therefore, in the targeted policy, there is expected a rule for thesshd_t
SELinux attribute that states objects withsshd_t
can access any objects with the following security attribute:etc_t
sshd_key_t
- …
Similarly, if we were to examine the
ssh
command, we would be able to determine a similar mapping betweenssh_home_t
andssh_exec_t
.ls -lZ /usr/bin/ssh
Example Output:
-rwxr-xr-x. 1 root root system_u:object_r:ssh_exec_t:s0 775720 Oct 9 2021 /usr/bin/ssh
ls -lZ ~/.ssh
Example Output:
total 4 -rw-------. 1 oracle oracle unconfined_u:object_r:ssh_home_t:s0 404 Apr 13 14:39 authorized_keys
-
Get the security context of a user.
The other context type of interest is
unconfined_t
. Objects with this SELinux type, such as users, have unrestricted access. This level of access means SELinux doesn’t limit what users can do and only inhibits them through DAC permissions. DAC (Discretionary Access Control) is the security policy handled by traditional users, groups, and other permissions.For example, show the security attributes for the
oracle
user.whoami
id -Z
Example Output:
[oracle@ol-selinux ~]$ whoami oracle [oracle@ol-selinux ~]$ id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
SELinux and Network Services
SELinux tracks the configurations for the most commonly used network-based software packages within its internal database. This tracking allows SELinux to protect the system from externally-facing services prone to attacks.
Therefore, SELinux may prevent a service from working if you configure the software to use a non-standard directory or port.
To show what SELinux knows about a system’s standard ports, we need to use the SELinux utility semanage
. Oracle Linux doesn’t install the utility by default, so install it.
-
Determine which package provides the utility.
sudo dnf whatprovides semanage
The results show that
/usr/sbin/semanage
is part of thepolicycoreutils-python-utils
package. -
Install the package and any dependencies.
sudo dnf install -y policycoreutils-python-utils
-
Check what ports SELinux allows for
sshd
.sudo semanage port -l | grep ssh
Example Output:
ssh_port_t tcp 22
-
Add a new port to the SELinux policy.
If we were to change the port the SSH daemon listens on to 2222 or change where it stores the default configuration; then we would need to inform SELinux that we want those changes. We can again use
semanage
to allow a custom port by adding a new policy rule.sudo semanage port -a -t ssh_port_t -p tcp 2222
- The
-a
option adds a new policy rule of type-t
.
- The
-
Check what ports SELinux allows now.
sudo semanage port -l | grep ssh
Example Output:
ssh_port_t tcp 2222, 22
-
Modify a port in the SELinux policy.
Let’s say we wanted to map the SSH daemon to port 443. Repeat the same command, but it will error with a message that the port is already in use.
sudo semanage port -a -t ssh_port_t -p tcp 443
Example Output:
ValueError: Port tcp/443 already defined
The error occurred because we are trying to switch port 443 from the
http_port_t
type to thessh_port_t
type. For this to work, use the-m
option, which modifies the port object record.sudo semanage port -m -t ssh_port_t -p tcp 443
SELinux Users
Each Linux user is mapped to an SELinux user using an SELinux policy. This approach allows Linux users to inherit restrictions based on their SELinux user mapping. The default mapping in Oracle Linux is the __default__
login, which maps to the SELinux unconfined_u
user.
-
Get a listing of all the current Linux user mappings.
sudo semanage login -l
- Notice that our
oracle
user is not listed and thus maps to theunconfined_u
user.
- Notice that our
-
Get a listing of the SELinux users.
seinfo -u
-
Restrict a user’s actions.
Although a default Linux user runs unconstrained, the user’s actions may induce restrictions based on an applications
domain
. Thedomain
is a bunch of objects with the same SELinux type.What if we wanted to block users from using the X Window System,
sudo
, and the network?SELinux has a user for that.
To verify this, we need to have another Linux user. We’ll use the user ralph.
-
Create the new mapping to
guest_u
.sudo semanage login -a -s guest_u ralph
-
Verify the mapping.
sudo semanage login -l
-
Test that ralph cannot access the network.
The restrictions inherited from
guest_u
only occur after login and not by performing asudo
orsu
.Open a new terminal and connect via ssh to the ol8-server system as the ralph user.
ssh ralph@<ip_address_of_ol8-server>
-
Check the user’s context.
id; id -Z
Example Output:
uid=8000(ralph) gid=8000(ralph) groups=8000(ralph) context=guest_u:guest_r:guest_t:s0 guest_u:guest_r:guest_t:s0
-
Show the security context of the user’s current processes:
ps axZ
The output shows user ralph mapped to
guest_u
and can log in. However, ralph should not be able to access the network. -
Test network connectivity with
ping
.ping localhost
Example Output:
ping: socket: Permission denied
-
Additionally test the network using
curl
.curl ifconfig.me
Example Output:
curl: (6) Could not resolve host: ifconfig.me
The message indicates that
curl
cannot resolve the DNS name ofifconfig.me
to an IP address. DNS, a Linux network service, requires opening a socket, so the SELinuxguest_u
user blocks it. -
Close the current terminal window.
We finished testing with the user ralph, so close that terminal window.
exit
-
SELinux Booleans
SELinux booleans allow specific policy changes at runtime without knowing how to write SELinux policies. Oracle Linux provides many built-in booleans, or administrators familiar with SELinux policies may write their own. Administrators are encouraged to write policies as booleans if the policy implemented is optional.
-
Get a list of booleans along with their meaning.
Switch back to the terminal where you are logged in as oracle and run the following command.
sudo semanage boolean -l
Example Output:
SELinux boolean State Default Description abrt_anon_write (off , off) Allow abrt to anon write abrt_handle_event (off , off) Allow abrt to handle event abrt_upload_watch_anon_write (on , on) Allow abrt to upload watch anon write antivirus_can_scan_system (off , off) Allow antivirus to can scan system antivirus_use_jit (off , off) Allow antivirus to use jit auditadm_exec_content (on , on) Allow auditadm to exec content authlogin_nsswitch_use_ldap (off , off) Allow authlogin to nsswitch use ldap authlogin_radius (off , off) Allow authlogin to radius ...
- The output explains what each boolean does and whether enabled (
on
) or disabled (off
).
- The output explains what each boolean does and whether enabled (
-
Get a list of just the booleans and their status.
sudo getsebool -a
Example Output:
abrt_anon_write --> off abrt_handle_event --> off abrt_upload_watch_anon_write --> on antivirus_can_scan_system --> off antivirus_use_jit --> off auditadm_exec_content --> on authlogin_nsswitch_use_ldap --> off authlogin_radius --> off authlogin_yubikey --> off ...
-
Get the status of a single boolean.
If the boolean name is known, pass the name as an argument to only get that booleans status.
sudo getsebool virt_use_nfs
-
Query the SELinux policy for a boolean.
Ever wonder what a boolean triggers within the SELinux policy? SELinux provides a utility to query those rules.
sesearch -b virt_use_nfs -A
Example Output:
allow fsdaemon_t autofs_t:dir { getattr open search }; [ virt_use_nfs ]:True allow fsdaemon_t nfs_t:dir { getattr ioctl lock open read search }; [ virt_use_nfs ]:True allow fsdaemon_t nfs_t:dir { getattr ioctl lock open read search }; [ virt_use_nfs ]:True allow fsdaemon_t nfs_t:dir { getattr ioctl lock open read search }; [ virt_use_nfs ]:True allow fsdaemon_t nfs_t:dir { getattr open search }; [ virt_use_nfs ]:True allow fsdaemon_t nfs_t:dir { getattr open search }; [ virt_use_nfs ]:True allow fsdaemon_t nfs_t:file { getattr ioctl lock open read }; [ virt_use_nfs ]:True allow fsdaemon_t nfs_t:lnk_file { getattr read }; [ virt_use_nfs ]:True ...
-
Query if a boolean allows access.
What about if particular access is allowed based on a conditional boolean? Answer the question: Does user ping permit the transition from a user domain (
user_t
) to the ping domain (ping_t
)?sesearch -s user_t -t ping_t -c process -p transition -AT
Example Output:
allow user_t ping_t:process transition; [ selinuxuser_ping ]:True
- The transition is allowed if the
user_ping
SELinux boolean is enabled.
- The transition is allowed if the
-
Enable a boolean.
Suppose we want to allow KVM to store images on a Samba share? There’s a boolean for that too.
-
Find the boolean.
sudo semanage boolean -l | grep virt | grep samba
Example Output:
virt_use_samba (off , off) Allow virt to use samba
-
Change the boolean to enabled.
sudo setsebool virt_use_samba on
or
sudo semanage boolean -m --on virt_use_samba
-
Check the current status.
getsebool virt_use_samba
-
Ensure the change survives a reboot.
sudo setsebool -P virt_use_samba on
-
-
Show local SELinux policy customizations.
Knowing that we have changed the default settings, we can show those local customizations.
sudo semanage boolean -l -C
Example Output:
SELinux boolean State Default Description virt_use_samba (on , on) Allow virt to use samba
- The output shows that the default value is now
on
. The default value changed after making the switch permanent and writing the pending values to the policy file on disk.
- The output shows that the default value is now
SELinux File Context
All files and directories get labeled with an SELinux context when running SELinux. We’ll examine a few commands for managing the file system labeling.
One familiar example is creating a new directory for Nginx’s document root.
-
Create the new directory along with three files.
sudo mkdir -p /web sudo touch /web/file{1,2,3}
-
Check the new directory and file labeling.
ls -lZ /web
Example Output:
total 0 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file1 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file2 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file3
- The new directory’s context type and the files are
default_t
.
Note: Newly-created files and directories inherit the SELinux type of their parent directories.
- The new directory’s context type and the files are
-
Make temporary label changes.
As part of troubleshooting or testing, we can temporarily change the context.
sudo chcon -R -t httpd_sys_content_t /web/
ls -lZ /web
-
Return labels to default settings.
Switch the context back to the default context type.
sudo restorecon -R -v /web/
Example Output:
[oracle@ol-selinux ~]$ sudo restorecon -R -v /web/ Relabeled /web from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0 Relabeled /web/file1 from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0 Relabeled /web/file2 from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0 Relabeled /web/file3 from unconfined_u:object_r:httpd_sys_content_t:s0 to unconfined_u:object_r:default_t:s0 [oracle@ol-selinux ~]$ ls -lZ /web total 0 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file1 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file2 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file3
-
Make label changes permanent.
In order to make the changes permanent and survive a reboot, use the
semanage fcontext
command. The-a
adds a record to the file/etc/selinux/targeted/contexts/files/file_contexts.local
, and-t
defines the type.sudo semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
Note: When changing the SELinux context with
semanage fcontext
, it’s recommended to use the full path to the file or directory to avoid mislabeling files after a file system relabeling or after runningrestorecon
. -
Check the context.
ls -ldZ /web; ls -lZ /web
Example Output:
[oracle@ol-selinux ~]$ ls -ldZ /web; ls -lZ /web drwxr-xr-x. 2 root root unconfined_u:object_r:default_t:s0 45 Apr 14 19:00 /web total 0 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file1 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file2 -rw-r--r--. 1 root root unconfined_u:object_r:default_t:s0 0 Apr 14 19:00 file3
Notice the context did not change, which we expected.
-
Show the context of the newly created files and directories.
sudo semanage fcontext -C -l
Example Output:
[oracle@ol-selinux ~]$ sudo semanage fcontext -C -l SELinux fcontext type Context /web(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
-
Apply the changes to the context.
sudo restorecon -R -v /web
Example Output:
[oracle@ol-selinux ~]$ sudo restorecon -R -v /web Relabeled /web from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0 Relabeled /web/file1 from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0 Relabeled /web/file2 from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0 Relabeled /web/file3 from unconfined_u:object_r:default_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
-
Remove the new SELinux context.
sudo semanage fcontext -d "/web(/.*)?"
- This example passes the regular expression used when creating the context and places it at the beginning of the context record on file. Since it’s a regular expression, enclose it within quotes.
-
Apply the changes and verify the context returned to
default_t
.sudo restorecon -R -v /web; ls -ldZ /web; ls -lZ /web
Check out the man
pages for the utilities shown. Then use what you learned to keep SELinux in Enforcing
mode.
For More Information
See other related resources:
More Learning Resources
Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.
For product documentation, visit Oracle Help Center.