This article will demonstrate how to troubleshoot httpd selinux issues when selinux is enabled.
What is SELinux? SELinux is short for Security-Enhanced Linux and is a security architecture that gives system administrators more control over access on given system.
If you have landed on this page, you are likely dealing with access issues to the file system configured for an httpd install on Redhat, CentOS, Ubuntu, or other Linux flavors. Alternatively, you may be running httpd or apache on a non-standard port, causing httpd to not start correctly.
Apache 403 Forbidden
Apache File Permissions
Before diving into the specifics of SELinux and how it may be causing the Apache 403 Forbidden errors, let’s first verify file permissions are set correctly.
File permissions for the web root directory should be set as follows.
chmod -R 775 /path/to/webroot/directory
Change directory ownership to an account with root privileges and the www-data or apache group.
chown -R apache:apache/path/to/webroot/directory
Restart the apache service for changes to take affect
systemctl restart httpd
or…
service restart httpd
Apache Directory Configuration
Alternatively, verify the /etc/httpd/conf/httpd.conf file has the correct permissions for each <Directory> object. If you have modified this file in any way, compare it with the original. The web root directory should have the Require all granted permission.
After making the change, again restart apache or httpd.
Apache Default Directory Index
It could be that the default directory index was removed from your httpd.conf file. Open the file and confirm the following line exists.
DirectoryIndex index.html index.cgi index.pl index.php index.xhtml
Modify as you see fit for your installation. If no directory index is present, apache returns a 403 for any path not found.
Apache httpd SELinux
Okay, now for the section you came to this site for. Before diving into SELinux we wanted to walk you through the most basic steps for troubleshooting Apache 403 Forbidden errors.
SELinux should not cause you any issues with a standard apache installation. But as soon as you change the standard port, web root, or log path you will most likely encounter issues with apache starting up correctly, serving the files in your web root, or logging. The internals of SELinux isn’t for the faint of heart, but if you are deploying a non-standard installation of apache you are probably a skilled systems administrator ready to learn the internals of SELinux.
First of all, we recommend NOT disabling SELinux. While convenient, you are losing all of the security it provides you. Rather than taking the easy approach, let’s discover how to modify the SELinux policy to meet your requirements.
Before proceeding to modifying SELinux policies, you can test that this is the issue by temporarily setting SELinux to run in permissive mode.
setenforce 0
If that resolves your 403 Forbidden error or apache startup error, set SELinux back to enforcing mode and proceed with the following steps.
setenforce 1
- If httpd is failing to start, it’s likely because you’re attempting to run httpd on a non-standard port. To show what ports the SELinux policy is expecting for apache, run the following command.
semanage port -l | grep http
- In this case, change the SELinux type of port for the port you are using to match that of port 80. For this example, let’s assume it’s port 3131.
semanage port -a -t http_port_t -p tcp 3131
Now try to start apache again. If it starts and you are using a standard web root, you should be good to go. Else, you will have a running apache instance but receive the 403 Forbidden error.
- If you run curl localhost (assuming you have an index.html file in your web root) and receive a 403, we need to modify more SELinux settings.
<!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 this resource.</p>
</body></html>
- SELinux has an alert tool that will display the reason for access issues.
sealert -l "*"
- Compare types for the standard path and new web root path using the
matchpathcon
command.
# matchpathcon /var/www/html /var/nonstandard/html
/var/www/html system_u:object_r:httpd_sys_content_t:s0
/var/nonstandard/html system_u:object_r:var_t:s0
- Change the type of the non-standard web root directory to match the type of the default web root.
semanage fcontext -a -e /var/www /var/nonstandard
- Relabel the /var directory recursively
restorecon -Rv /var/
- Verify that the httpd service is running and then perform another curl localhost. You should receive a 200 along with the expected web page contents.
- If your non-standard web root is an NFS or CIFS mount, you have additional work to do! First, install the selinux-policy-devel package.
dnf install selinux-policy-devel
- Identify booleans relevant for NFS, CIFS, and Apache.
semanage boolean -l | grep 'nfs\|cifs' | grep httpd
- Now that you’ve identified the booleans for NFS and CIFS, get their current state.
getsebool -a | grep 'nfs\|cifs' | grep httpd
- Enable the booleans for NFS and CIFS. Use -P to make the change persistent across reboots.
setsebool httpd_use_nfs on
setsebool httpd_use_cifs on
Now you should have a working Apache instance with non-standard ports and web roots.
SELinux and httpd logging
On Redhat 8, if you are having issues logging httpd logs to a non standard directory, try the following commands.
ausearch -c 'rotatelogs' --raw | audit2allow -M my-rotatelogs
semodule -i my-rotatelogs.pp
If the non-standard directory for logs is an NFS mount, try the following command.
setsebool -P logrotate_use_nfs on
SELinux policy changes
Depending on your httpd installation and dependent systems you could be affected by numerous different access issues. The simplest way to detect and fix these issues is as follows.
Show selinux errors.
sealert -l "*"
A list of errors will be displayed. For example,
Raw Audit Messages
type=AVC msg=audit(1676412049.987:4379): avc: denied { module_request } for pid=370197 comm="rpc.statd" kmod="net-pf-10" scontext=system_u:system_r:rpcd_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclass=system permissive=0
If you scroll up you will see recommended local policy changes. For this specific one you will see:
If you believe that rpc.statd should be allowed module_request access on system labeled kernel_t by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'rpc.statd' --raw | audit2allow -M my-rpcstatd
# semodule -X 300 -i my-rpcstatd.pp
Run those two commands and the access issue should be resolved. Do this for each result in the sealert -l “*” result list.
Conclusion – httpd SELinux
This article has demonstrated how to troubleshoot httpd SELinux access issues as well as other common access issues with Apache on Linux. Let us know in the comments if none of these examples solved your issue. If you found this article helpful, please check out more of our content.
Leave a Reply