Introduction
In this lab, you will gain hands-on experience managing SELinux security in RHEL. You will learn to change SELinux enforcement modes, both temporarily and persistently, and configure Apache with custom SELinux file contexts. The lab also covers adjusting SELinux policy for user home directories using booleans and provides practical steps for troubleshooting and resolving SELinux denials for Apache web servers and custom web content.
Change SELinux Enforcement Mode
In this step, you will learn how to manage SELinux modes, both temporarily and persistently. SELinux (Security-Enhanced Linux) is a security mechanism that provides mandatory access control (MAC) for the Linux kernel. It defines the access rights for processes, files, and other system resources.
SELinux operates in three primary modes:
- Enforcing: SELinux policy is enforced. Accesses denied by the policy are blocked and logged. This is the default and most secure mode.
- Permissive: SELinux policy is not enforced. Accesses denied by the policy are logged but not blocked. This mode is useful for troubleshooting and testing new policies.
- Disabled: SELinux is turned off. No policy is loaded or enforced. This mode is generally not recommended for production systems.
You will practice changing the SELinux mode using command-line tools and by modifying configuration files.
First, let's check the current SELinux enforcement mode.
Check the current SELinux enforcement mode.
You can use the
getenforcecommand to quickly see the current SELinux mode.getenforceYou should see
Enforcingas the output, indicating that SELinux is currently enforcing its policies.EnforcingChange the SELinux mode to
permissivetemporarily.The
setenforcecommand allows you to change the SELinux mode at runtime. A value of0sets the mode topermissive, and1sets it toenforcing. This change is temporary and will not persist across reboots.sudo setenforce 0Now, verify the change using
getenforceagain.getenforceThe output should now be
Permissive.PermissiveChange the SELinux mode back to
enforcingtemporarily.To revert the temporary change, use
setenforce 1.sudo setenforce 1Verify the mode once more.
getenforceThe output should be
Enforcingagain.EnforcingChange the default SELinux mode to
permissivepersistently.To make SELinux mode changes persistent across reboots, you need to modify the
/etc/selinux/configfile. This file defines the default SELinux mode for the system.Open the configuration file using
nano.sudo nano /etc/selinux/configInside the
nanoeditor, find the line that starts withSELINUX=and change its value fromenforcingtopermissive.## 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=permissive ## SELINUXTYPE= can take one of these three values: ## targeted - Targeted processes are protected, ## for the majority of users. ## minimum - Modification of targeted policy ## uses current settings and adds to it. ## mls - Multi Level Security protection. SELINUXTYPE=targetedPress
Ctrl+Xto exit, thenYto confirm saving, andEnterto write to the same file.After saving the file, you can confirm the change in the configuration file using
grep.grep '^SELINUX' /etc/selinux/configThe output should show
SELINUX=permissive.SELINUX=permissive SELINUXTYPE=targetedImportant Note: Changing
/etc/selinux/configdoes not immediately change the active SELinux mode. It only sets the mode that will be applied after the next system reboot. To see the current active mode, you still need to usegetenforce.getenforceIt should still show
Enforcingbecause the system has not been rebooted yet.EnforcingChange the default SELinux mode back to
enforcingin the configuration file.Now, let's change the persistent mode back to
enforcing. This is the recommended and most secure setting for SELinux.Open the configuration file again.
sudo nano /etc/selinux/configChange the
SELINUX=parameter back toenforcing.## 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 three values: ## targeted - Targeted processes are protected, ## for the majority of users. ## minimum - Modification of targeted policy ## uses current settings and adds to it. ## mls - Multi Level Security protection. SELINUXTYPE=targetedSave and exit the file (
Ctrl+X,Y,Enter).Confirm the change in the configuration file.
grep '^SELINUX' /etc/selinux/configThe output should now show
SELINUX=enforcing.SELINUX=enforcing SELINUXTYPE=targetedAt this point, the system's active SELinux mode is still
Enforcing(if you didn't reboot after step 4), and the persistent setting is alsoEnforcing.
Configure Apache with Custom SELinux File Contexts
In this step, you will learn how to configure Apache to serve web content from a non-standard directory and manage its SELinux file contexts. By default, SELinux policies restrict Apache (httpd) to serving files only from specific directories, primarily /var/www/html. If you place web content in a different location, SELinux will prevent Apache from accessing it, even if file system permissions are correct. This is where SELinux file contexts come into play.
An SELinux file context is a label applied to a file or directory that defines its security attributes. For Apache to serve content from a custom location, that location and its contents must have the correct SELinux context, typically httpd_sys_content_t. You will use semanage fcontext to define a persistent rule and restorecon to apply it.
First, you need to install the Apache HTTP server.
Install the Apache HTTP server.
Use the
dnfpackage manager to install thehttpdpackage.sudo dnf install -y httpdYou should see output indicating the successful installation of the
httpdpackage and its dependencies.Create a custom directory for web content and an
index.htmlfile.You will create a new directory named
/customand place a simpleindex.htmlfile inside it. This will be your non-standard web document root.sudo mkdir /custom echo 'This is custom web content.' | sudo tee /custom/index.htmlVerify the content of the
index.htmlfile.cat /custom/index.htmlThis is custom web content.Configure Apache to use the new document root.
Apache's main configuration file is
/etc/httpd/conf/httpd.conf. You need to edit this file to point Apache to your new/customdirectory instead of the default/var/www/html.Open the configuration file using
nano.sudo nano /etc/httpd/conf/httpd.confInside the editor, find the lines
DocumentRoot "/var/www/html"and<Directory "/var/www/html">. Change both occurrences of/var/www/htmlto/custom.The relevant sections should look like this after modification:
# ## DocumentRoot: The directory out of which you will serve your ## documents. By default, all requests are taken from this directory, but ## symbolic links and aliases may be used to point to other locations. # DocumentRoot "/custom" # ## Relax access to content within /var/www. # <Directory "/custom"> AllowOverride None ## Allow open access: Require all granted </Directory>Save and exit the file (
Ctrl+X,Y,Enter).Start and enable the Apache web service.
After modifying the configuration, you need to start the
httpdservice. Since you are in a container environment,systemctlis not available. You will starthttpddirectly.sudo /usr/sbin/httpd -DFOREGROUND &The
&symbol runs the command in the background, allowing you to continue using the terminal. You should see output similar to this, indicating Apache is starting.[1] 5094 AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::216:3eff:fe00:63b%eth0. Set the 'ServerName' directive globally to suppress this messageNote: The warning message about the server's fully qualified domain name is normal in this lab environment and can be safely ignored.
To verify that Apache is running, you can check for the
httpdprocess.ps aux | grep httpdYou should see several
httpdprocesses running.root ... /usr/sbin/httpd -DFOREGROUND apache ... /usr/sbin/httpd -DFOREGROUND ...output omitted...Attempt to access the web page.
Now, try to access your web page using
curl. Since you are on the same machine, you can uselocalhost.curl http://localhost/index.htmlNote: In this particular environment, you may find that the web page is accessible even with the
root_tcontext. This demonstrates that while SELinux is enforcing, theroot_tcontext may have broader permissions than expected. However, for security best practices and proper SELinux configuration, web content should still use the appropriatehttpd_sys_content_tcontext.This is custom web content.Check the current SELinux context of the custom directory.
Use the
ls -Zcommand to view the SELinux context of your/customdirectory and theindex.htmlfile.ls -Zd /custom /custom/index.htmlYou will notice that they have the
root_tcontext, which is not the recommended context for Apache web content.system_u:object_r:root_t:s0 /custom system_u:object_r:root_t:s0 /custom/index.htmlCompare this to the default Apache document root:
ls -Zd /var/www/htmlYou will see that
/var/www/htmlhas thehttpd_sys_content_tcontext. This is the context you need to apply to your custom directory.system_u:object_r:httpd_sys_content_t:s0 /var/www/htmlDefine a persistent SELinux file context rule for
/custom.The
semanage fcontextcommand is used to manage SELinux file context mapping rules. The-aoption adds a new rule,-tspecifies the target type, and the regular expression'/custom(/.*)?'matches the/customdirectory itself and all files and subdirectories within it.sudo semanage fcontext -a -t httpd_sys_content_t '/custom(/.*)?'This command adds the rule to the SELinux policy, but it does not immediately change the contexts of existing files.
Apply the new SELinux contexts to the files.
The
restoreconcommand is used to restore the SELinux contexts of files and directories to their default values as defined by the policy. The-Roption applies the change recursively, and-vprovides verbose output.sudo restorecon -Rv /customYou should see output indicating that the contexts of
/customand/custom/index.htmlhave been relabeled.Relabeled /custom from system_u:object_r:root_t:s0 to system_u:object_r:httpd_sys_content_t:s0 Relabeled /custom/index.html from system_u:object_r:root_t:s0 to system_u:object_r:httpd_sys_content_t:s0Verify the contexts again using
ls -Z.ls -Zd /custom /custom/index.htmlThey should now have the
httpd_sys_content_tcontext.system_u:object_r:httpd_sys_content_t:s0 /custom system_u:object_r:httpd_sys_content_t:s0 /custom/index.htmlAccess the web page again.
Now that the SELinux contexts are correct, try accessing the web page with
curlagain.curl http://localhost/index.htmlYou should now see the content of your
index.htmlfile.This is custom web content.Finally, stop the Apache HTTP server process.
sudo pkill httpdVerify that no
httpdprocesses are running.ps aux | grep httpdYou should only see the
grepprocess itself.labex ... grep httpd
Adjust SELinux Policy for User Home Directories with Booleans
In this step, you will learn how to adjust SELinux policy using Booleans to allow Apache to serve web content from users' home directories. By default, SELinux prevents services like Apache from accessing files in user home directories for security reasons. However, there are specific scenarios, such as personal web pages, where this functionality is desired.
SELinux Booleans are true/false settings that allow administrators to modify the behavior of the SELinux policy without writing complex custom policies. They provide a flexible way to enable or disable certain security features. For example, there's a Boolean specifically for allowing Apache to access user home directories.
Enable Apache's user directory feature.
Apache has a module called
mod_userdirthat allows users to publish web content from apublic_htmldirectory within their home directory (e.g.,~/public_html). This feature is typically configured in/etc/httpd/conf.d/userdir.conf. By default, this feature is often disabled.Open the configuration file using
nano.sudo nano /etc/httpd/conf.d/userdir.confInside the editor, you will find lines related to
UserDir. You need to comment out the line that disablesUserDirand uncomment the line that enables it forpublic_html.Change:
UserDir disabled #UserDir public_htmlTo:
#UserDir disabled UserDir public_htmlSave and exit the file (
Ctrl+X,Y,Enter).Create a
public_htmldirectory and anindex.htmlfile in your home directory.You will create the
public_htmldirectory and anindex.htmlfile inside it. This is where your personal web content will reside.mkdir ~/public_html echo 'This is labex user content.' > ~/public_html/index.htmlVerify the content of the
index.htmlfile.cat ~/public_html/index.htmlThis is labex user content.Informational: When you created the
~/public_htmldirectory, it was automatically configured withuser_home_tand~/(your home directory) withhome_dir_tSELinux contexts. The Apache web server process (httpd_t) cannot read files labeleduser_home_torhome_dir_tby default due to SELinux policy.Start the Apache web service.
Start the
httpdservice. Remember,systemctlis not available in this container environment, so you will starthttpddirectly.sudo /usr/sbin/httpd -DFOREGROUND &You may see a warning message about the server's fully qualified domain name, which can be safely ignored in this lab environment.
Verify that Apache is running.
ps aux | grep httpdroot ... /usr/sbin/httpd -DFOREGROUND apache ... /usr/sbin/httpd -DFOREGROUND ...output omitted...Attempt to access the user's web page and observe the SELinux denial.
Now, try to access your personal web page using
curl. The URL for user directories typically follows the formathttp://localhost/~username/.curl http://localhost/~labex/index.htmlYou will likely receive a "Forbidden" error, indicating that Apache is still unable to access the content due to SELinux.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>403 Forbidden</title> </head><body> <h1>Forbidden</h1> <p>You don't have permission to access /~labex/index.html on this server.<br /> </p> </body></html>Check SELinux Booleans related to home directories for
httpd.The
getseboolcommand allows you to view the current state of SELinux Booleans. You can filter the output usinggrepto find Booleans related tohttpdand home directories.sudo getsebool -a | grep httpd | grep homeYou should see
httpd_enable_homedirs --> off, indicating that this Boolean is currently disabled.httpd_enable_homedirs --> offEnable the
httpd_enable_homedirsBoolean persistently.The
setseboolcommand is used to change the state of SELinux Booleans. The-Poption makes the change persistent across reboots.sudo setsebool -P httpd_enable_homedirs onVerify that the Boolean is now
on.sudo getsebool -a | grep httpd | grep homehttpd_enable_homedirs --> onSet the correct file permissions for the home directory.
Even with the SELinux boolean enabled, Apache needs proper file system permissions to access your home directory and the
public_htmldirectory. By default, user home directories are not accessible to the Apache user.chmod 711 ~ chmod 755 ~/public_html chmod 644 ~/public_html/index.htmlAccess the web page again.
Now that both the
httpd_enable_homedirsBoolean is enabled and the file permissions are correct, try accessing your personal web page withcurlagain.curl http://localhost/~labex/index.htmlYou should now see the content of your
index.htmlfile.This is labex user content.Troubleshooting: If you still encounter access issues even after enabling the boolean and setting file permissions, this demonstrates the multi-layered nature of Linux security. In some environments, additional factors such as:
- Apache configuration directives in
/etc/httpd/conf.d/userdir.conf - SELinux file contexts on the home directory structure
- Additional Apache modules or security settings
may need to be addressed. The key learning point is understanding how SELinux booleans work in conjunction with traditional file permissions and application-specific configurations.
- Apache configuration directives in
Stop the Apache HTTP server process.
Finally, stop the Apache HTTP server process.
sudo pkill httpdVerify that no
httpdprocesses are running.ps aux | grep httpdlabex ... grep httpd
Troubleshoot SELinux Denials for Apache Web Server
In this step, you will learn how to identify and troubleshoot SELinux security denials, specifically focusing on issues that might prevent the Apache web server from functioning correctly. When SELinux blocks an operation, it logs an "Access Vector Cache" (AVC) denial message. These messages are crucial for understanding why an operation failed and how to resolve it.
You will use tools like auditd (the Linux Auditing System daemon) and sealert to analyze these denial messages. auditd collects system calls and events, including SELinux denials, and stores them in /var/log/audit/audit.log. The sealert tool, part of the setroubleshoot-server package, can parse these logs and provide human-readable explanations and suggested solutions for SELinux denials.
First, you need to ensure auditd and setroubleshoot-server are installed.
Install
auditdandsetroubleshoot-server.sudo dnf install -y audit setroubleshoot-serverYou should see output indicating the successful installation of these packages.
Start the Apache web server and create a problematic file.
To simulate an SELinux denial, you will create a file with an incorrect SELinux context and try to serve it with Apache.
First, ensure Apache is running.
sudo /usr/sbin/httpd -DFOREGROUND &Now, create a new directory and an
index.htmlfile within it. This time, you will intentionally set an incorrect SELinux context for this file to trigger a denial.sudo mkdir /testweb echo 'This is a test page.' | sudo tee /testweb/index.htmlBy default,
/testweb/index.htmlwill likely have theroot_tcontext. Let's confirm.ls -Z /testweb/index.htmlsystem_u:object_r:root_t:s0 /testweb/index.htmlNow, let's configure Apache to serve from
/testweb. Open/etc/httpd/conf/httpd.conf.sudo nano /etc/httpd/conf/httpd.confChange
DocumentRootand the<Directory>directive to/testweb.DocumentRoot "/testweb" <Directory "/testweb"> AllowOverride None Require all granted </Directory>Save and exit (
Ctrl+X,Y,Enter).Restart Apache to apply the configuration changes. Since you are in a container, you need to kill the old process and start a new one.
sudo pkill httpd sudo /usr/sbin/httpd -DFOREGROUND &Attempt to access the web page.
Try to access the web page using
curl.curl http://localhost/index.htmlImportant Note: In this environment, you may find that the web page is accessible even with the
root_tcontext, similar to what we observed in Step 2. This demonstrates that while SELinux is enforcing, theroot_tcontext has broader permissions than more restrictive contexts.This is a test page.However, for the purpose of learning SELinux troubleshooting techniques, we will proceed as if there were a denial. In more restrictive SELinux environments or with different policy configurations, accessing files with inappropriate contexts would indeed generate denials.
Learn about investigating SELinux denials using
ausearch.The
ausearchcommand is used to query the audit logs. You can search for SELinux AVC denials (-m AVC) that occurred today (-ts today).sudo ausearch -m AVC -ts todayNote: Since the web page was accessible in our environment, you may not see any recent AVC denials related to this specific test. However, this command would normally output detailed audit log entries if there were denials. In a typical denial scenario, you would look for entries related to
httpdand/testweb/index.html.A typical AVC denial entry would look like this:
---- time->... type=AVC msg=audit(...): avc: denied { getattr } for pid=... comm="httpd" path="/testweb/index.html" dev="overlay" ino=... scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:root_t:s0 tclass=file permissive=0 ...output omitted...The key parts in an AVC denial would be:
denied { getattr }: The operation that was denied (getting attributes of the file).comm="httpd": The process that was denied (Apache HTTP server).path="/testweb/index.html": The file that was accessed.scontext=system_u:system_r:httpd_t:s0: The SELinux context of the source (Apache).tcontext=system_u:object_r:root_t:s0: The SELinux context of the target (yourindex.htmlfile).tclass=file: The type of target (a file).
This output clearly shows that
httpd_t(Apache) was deniedgetattraccess to a file withdefault_tcontext.Learn about using
sealertfor SELinux analysis.sealertcan parse the audit logs and provide more user-friendly information. You can either runsealert -ato analyze all recent denials or usesealert -l <UUID>if you have a specific UUID from asetroubleshootmessage in/var/log/messages.sudo sealert -a /var/log/audit/audit.logNote: Since we haven't encountered actual denials in this environment, running
sealertmay not show results related to our/testwebexample. However, in a scenario where SELinux denials occur,sealertwould analyze the audit log and present a summary.A typical
sealertoutput for an httpd context issue would look like this:SELinux is preventing /usr/sbin/httpd from getattr access on the file /testweb/index.html. ***** Plugin catchall_labels (83.8 confidence) suggests ******************* If you want to allow httpd to have getattr access on the index.html file Then you need to change the label on /testweb/index.html Do ## semanage fcontext -a -t FILE_TYPE '/testweb/index.html' where FILE_TYPE is one of the following: httpd_sys_content_t, httpd_sys_script_exec_t, httpd_unconfined_script_exec_t, ... ***** Plugin httpd_can_network_connect (93.8 confidence) suggests ********* If you want to allow httpd to connect to the network (for example, to a database) Then you must set the httpd_can_network_connect boolean to on. Do ## setsebool -P httpd_can_network_connect on ...output omitted...The
sealertoutput would be very helpful in real denial scenarios. It would explicitly state the problem and suggest solutions, such as changing the label withsemanage fcontext -a -t FILE_TYPE '/testweb/index.html'and listinghttpd_sys_content_tas a suitableFILE_TYPE.Finally, stop the Apache HTTP server process.
sudo pkill httpdVerify that no
httpdprocesses are running.ps aux | grep httpdlabex ... grep httpd
Resolve SELinux Issues for Custom Web Content
In this final step, you will apply the knowledge gained from the previous troubleshooting exercise to resolve the SELinux denial that prevented Apache from serving content from the /testweb directory. You will use semanage fcontext to define the correct SELinux context for your custom web content and restorecon to apply it.
This process reinforces the understanding of how SELinux contexts work and how to correctly configure them for services like Apache.
Ensure Apache is running and the configuration is in place.
First, ensure that Apache is configured to serve from
/testweband is running. If you stopped Apache in the previous step, start it again.sudo /usr/sbin/httpd -DFOREGROUND &Verify that the
DocumentRootin/etc/httpd/conf/httpd.confis set to/testweb. If not, modify it as done in the previous step.grep "DocumentRoot" /etc/httpd/conf/httpd.confDocumentRoot "/testweb"Also, confirm that
/testweb/index.htmlexists and has theroot_tcontext.ls -Z /testweb/index.htmlsystem_u:object_r:root_t:s0 /testweb/index.htmlAccess the web page to confirm current behavior.
Let's verify that the web page is currently accessible with the
root_tcontext.curl http://localhost/index.htmlAs we've seen before, the page is accessible even with the
root_tcontext.This is a test page.While this works, we will proceed to demonstrate the proper SELinux configuration for web content.
Define the correct SELinux file context for
/testweb.The correct SELinux context for web content served by Apache is
httpd_sys_content_t. You need to add a persistent rule usingsemanage fcontext.sudo semanage fcontext -a -t httpd_sys_content_t '/testweb(/.*)?'This command tells SELinux that any files or directories within
/testweb(including/testwebitself) should be labeled withhttpd_sys_content_t.Apply the new SELinux contexts to the files.
After defining the rule, you must apply it to the existing files using
restorecon.sudo restorecon -Rv /testwebYou should see output indicating that the contexts have been relabeled.
Relabeled /testweb from system_u:object_r:root_t:s0 to system_u:object_r:httpd_sys_content_t:s0 Relabeled /testweb/index.html from system_u:object_r:root_t:s0 to system_u:object_r:httpd_sys_content_t:s0Verify the contexts again using
ls -Z.ls -Z /testweb/index.htmlsystem_u:object_r:httpd_sys_content_t:s0 /testweb/index.htmlAccess the web page again to confirm proper configuration.
Now that the SELinux contexts are correctly applied according to best practices, try accessing the web page with
curlone more time.curl http://localhost/index.htmlThe content should still be accessible, and now it's properly configured with the recommended SELinux context.
This is a test page.This demonstrates that while the
root_tcontext may work in this environment, using the properhttpd_sys_content_tcontext follows SELinux best practices and ensures compatibility across different security configurations.Finally, stop the Apache HTTP server process.
sudo pkill httpdVerify that no
httpdprocesses are running.ps aux | grep httpdlabex ... grep httpd
Summary
In this lab, you learned to manage SELinux security in RHEL. You began by understanding and practicing how to change SELinux enforcement modes, both temporarily using setenforce and persistently by modifying /etc/selinux/config. This included verifying the current mode with getenforce and understanding the implications of Enforcing, Permissive, and Disabled modes.
Furthermore, you gained practical experience in configuring Apache with custom SELinux file contexts using semanage fcontext and restorecon to ensure proper web server operation. You also learned to adjust SELinux policy for user home directories by enabling specific SELinux booleans with setsebool. Finally, the lab covered essential troubleshooting techniques for SELinux denials, specifically for the Apache web server, by analyzing audit logs with ausearch and audit2allow to identify and resolve access issues for custom web content.



