Security is a paramount concern in the digital world, and operating systems play a critical role in maintaining data and systems' integrity, confidentiality, and availability. One powerful security feature that stands out in the realm of Linux-based operating systems, notably Red Hat Enterprise Linux (RHEL), is Security-Enhanced Linux (SELinux).
This article is the first in a two-part series that will cover all aspects of SELinux, including different modes (enforcing), benefits, how it impacts running web applications on RHEL servers, creating custom policies, deploying the same configuration across a fleet of servers, and packaging SELinux policies in containers.
In this article, we will delve into SELinux on RHEL, focusing on understanding its core concepts, benefits, and how it enhances the security of applications running on the system.
SELinux basics
SELinux is a mandatory access control (MAC) security mechanism integrated into the Linux kernel. Unlike traditional discretionary access control (DAC), SELinux enforces access control based on administrator-defined policies, while traditional DAC permits users to access resources based on ownership and group membership. In this way, security breaches are minimized and malicious software is limited in its ability to do damage.
At the core of SELinux lies the fundamental concept of labels. Each process, file, and network port within SELinux is allocated a label delineating security context. These labels encompass a type and a role, affording SELinux the capability to impose access controls meticulously. This intricate label structure comprises user, role, type, and level designations, collectively known as the components of MLS.
Benefits of SELinux
- Minimize Attack Surface: SELinux significantly reduces potential vulnerabilities by strictly adhering to the principle of least privilege. If an unauthorized entity gains access to the system, SELinux effectively limits its ability to exploit vulnerabilities and spread throughout the system.
- Process Segregation: SELinux effectively confines processes to distinct domains, preventing any unwanted interference with other processes and resources. This segregation helps limit the potential harm that a compromised process could cause.
- Enhanced Application Security: Applications within an SELinux-enabled environment are protected from attempts to access system resources beyond their designated boundaries. This safeguard ensures the consistent and secure behavior of applications.
- Precise Access Management: SELinux enables administrators to finely define access controls tailored to their system's specific requirements. This precise control enhances security without limiting the system's functionality.
SELinux modes
SELinux operates in three distinct modes: enforcing, permissive, and disabled.
- Enforcing: In this mode, SELinux actively enforces the defined security policies. Any violation triggers an immediate response, such as blocking unauthorized access or generating an alert.
- Permissive: In permissive mode, SELinux logs violations while enforcing policies and without actively blocking them. This mode is useful for identifying policy gaps before transitioning to full enforcement.
- Disabled: SELinux is turned off in disabled mode, and DAC becomes the primary access control mechanism. While this might be necessary for specific legacy applications, it's not recommended for systems requiring strong security.
Check the status of SELinux
Prerequisites:
- RHEL server or workstation.
- The selinux-policy-targeted, libselinux-utils, and policycoreutils packages installed on your system.
- The selinux=0 or enforcing=0 kernel parameters are not used.
As previously mentioned, SELinux has three modes. To check the SELinux mode status, you can use two commands: getenforce
and sestatus
. By default, SELinux is set to enforcing mode in RHEL.
To check the current SELinux status, use the following command:
[root@localhost selinux]# sestatus
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: 33
or:
[root@localhost selinux]# getenforce
Enforcing
Note: Ensure that you execute these and the following commands only when logged in as the root user in the terminal.
Changing permissions of SELinux
You can change SELinux modes temporarily or permanently using the setenforce
command. It's important to note that changes made with setenforce
are temporary and will revert to their previous state after the next system reboot.
To enable enforcing mode:
#setenforce 1
To disable the SELinux enforcing mode, use the setenforce 0
command:
#setenforce 0
To make permanent changes, execute the following commands. You can switch SELinux mode to enforcing, permissive, or disabled. When SELinux runs in enforcing mode, it labels all files and processes, reducing the chances of server exploitation and enhancing security.
1. To make permanent changes, open the configuration file in a text editor located at /etc/selinux/config.
# vim /etc/selinux/config
2. Scroll down and set the value of 'SELinux' to 'enforcing'.
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
3. Applying the changes, requires a system reboot:
#reboot
After booting, SELinux relabels all files and directories within the system, adding SELinux contexts to the files. To recheck the SELinux mode, use the sestatus
and getenforce
commands.
How labeling works
All files, directories, and processes on an SELinux system are labeled with contexts. Labels are also applied to resources such as TCP and UDP ports. Modifying the assigned labels through SELinux's policy definitions is still possible if a specific port type has not been utilized yet.
Labeling format: user_u:role_r:type_t:level
- User_u : Is the SELinux user.
- User_r : Is the SELinux role.
- User_t : Is the SELinux type.
To check available SELinux users, roles, and types, use the following command to list them all.
$ seinfo -u
$ seinfo -r
$ seinfo -t
You can view the labels attached to files and directories with the following command:
# ls -lZ
drwxr-xr-x. 1 user user unconfined_u:object_r:user_home_t:s0 56 Aug 23 14:47 SElinux
Inspect the labels of currently running processes.
#ps axZ | grep httpd
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 12141 pts/0 R+ 0:00 grep --color=auto httpd
Examine the labels of sockets, using following command:
#netsat -taZ | grep httpd
tcp6 0 0 [::]:http [::]:* LISTEN 26151/httpd system_u:system_r:httpd_t:s0
A consequence of these labels is that RHEL can restrict access to every component, encompassing files, directories, processes, and sockets. SELinux utilizes them as entry criteria. Access will be denied if they do not match the existing label.
Test SELinux
To assess how SELinux policies and contexts function, we need to deploy a sample application. This application is a basic HTTPd-hosted static website containing sample images and text about Red Hat Developer. Download the RHEL ISO file.
1. Install the HTTPd server on the RHEL system using the following command:
$ sudo yum install httpd
2. Enable the HTTPd server and verify the status to ensure it's running.
$ sudo systemctl start httpd && sudo systemctl status httpd
3. Create a new index.html file in the following directory for the static website, effectively setting it up as a sample application.
# cd /var/www/html/ && touch index.html
4. Open the index.html file using the Vim editor and paste the following content:
# vim index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Red Hat Developers</title>
</head>
<body>
<header>
<h1>Welcome to Red Hat Developers portal</h1>
<a href="https://developers.redhat.com">
<img src="https://github.com/nageshredhat/local-openshift/blob/main/rh-dev.jpg?raw=true" alt="Red Hat Developers Logo">
</a>
</header>
<main>
<p>
Red Hat Developers is a platform for developers to access resources, tools, and information about Red Hat technologies.
</p>
<p>
Visit the <a href="https://developers.redhat.com">Red Hat Developers</a> website to learn more.
</p>
</main>
<footer>
<p>© 2023 Red Hat, Inc. All rights reserved.</p>
</footer>
</body>
</html>
5. To test the application, open your web browser and visit localhost:80. You will be directed to the webpage shown in Figure 1.
Execute anonymous activities on the RHEL system. This task is initiated by SELinux, and the outcomes align with the system's expected behavior.
6. Create a new index.html file and overwrite the existing one with it.
#cd /home/user && touch index.html
7. Paste this same content for index.html and make modifications to the file to distinguish it as a new website, as follows.
$ vim index.html
8. Move the duplicated index.html to the original location of index.html using the mv
command, as follows:
# mv index.html /var/www/html/
9. In your web browser, open the URL: http://localhost:80. However, instead of the Red Hat Developers website, you will encounter a forbidden error (Figure 2).
10. The issue is caused by the labels attached to the files. The label assigned to the previous index.html differs from the one assigned to the current index.html file.
# ls -lZ
total 4
-rw-r--r--. 1 nagesh nagesh unconfined_u:object_r:user_home_t:s0 827 Aug 24 07:30 index.html
11. To correct the label of index.html, check the error using the following journalctl
command. This command provides error messages and potential solutions.
# journalctl -b 0
In the red-colored text, you will encounter an error related to the '/var/www/html/' file along with a solution, as shown in Figure 3.
12. You can correct the label of the index.html file using the restorecon
command. Once the file is relabeled, the website will be functional again. Please execute the following command to resolve the issue.
[root@fedora html]# /sbin/restorecon -v /var/www/html/index.html
Relabeled /var/www/html/index.html from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
13. When you return to your web browser, you will notice that the website has been restored and is displaying the Red Hat Developer page once again (Figure 4).
Find more resources
In this article, we delved into SELinux, its advantages, fundamental principles, highlighting its pivotal role in safeguarding running applications. We demonstrated a notable example of SELinux mitigating web exploitation and preventing vulnerabilities. The next article demonstrates how to create and deploy custom SELinux policies to secure containers and servers.
For a deeper and practical understanding of Red Hat Enterprise Linux, you can engage in thoughtfully curated hands-on labs by Red Hat. Red Hat Universal Base Images (UBI) are container-based and operating system images with complementary runtime languages and packages. Try Red Hat UBI on curated Red Hat UBI hands-on lab.
Furthermore, you have the option to obtain tailored Red Hat Enterprise Linux images designed for AWS, Google Cloud Platform, Microsoft Azure, and VMware, facilitating their seamless deployment on your chosen platform.
Last updated: September 22, 2023