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 dnf package manager to install the httpd package.
sudo dnf install -y httpd
You should see output indicating the successful installation of the httpd package and its dependencies.
-
Create a custom directory for web content and an index.html file.
You will create a new directory named /custom and place a simple index.html file inside it. This will be your non-standard web document root.
sudo mkdir /custom
echo 'This is custom web content.' | sudo tee /custom/index.html
Verify the content of the index.html file.
cat /custom/index.html
This 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 /custom directory instead of the default /var/www/html.
Open the configuration file using nano.
sudo nano /etc/httpd/conf/httpd.conf
Inside the editor, find the lines DocumentRoot "/var/www/html" and <Directory "/var/www/html">. Change both occurrences of /var/www/html to /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 httpd service. Since you are in a container environment, systemctl is not available. You will start httpd directly.
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 message
Note: 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 httpd process.
ps aux | grep httpd
You should see several httpd processes 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 use localhost.
curl http://localhost/index.html
Note: In this particular environment, you may find that the web page is accessible even with the root_t context. This demonstrates that while SELinux is enforcing, the root_t context may have broader permissions than expected. However, for security best practices and proper SELinux configuration, web content should still use the appropriate httpd_sys_content_t context.
This is custom web content.
-
Check the current SELinux context of the custom directory.
Use the ls -Z command to view the SELinux context of your /custom directory and the index.html file.
ls -Zd /custom /custom/index.html
You will notice that they have the root_t context, 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.html
Compare this to the default Apache document root:
ls -Zd /var/www/html
You will see that /var/www/html has the httpd_sys_content_t context. This is the context you need to apply to your custom directory.
system_u:object_r:httpd_sys_content_t:s0 /var/www/html
-
Define a persistent SELinux file context rule for /custom.
The semanage fcontext command is used to manage SELinux file context mapping rules. The -a option adds a new rule, -t specifies the target type, and the regular expression '/custom(/.*)?' matches the /custom directory 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 restorecon command is used to restore the SELinux contexts of files and directories to their default values as defined by the policy. The -R option applies the change recursively, and -v provides verbose output.
sudo restorecon -Rv /custom
You should see output indicating that the contexts of /custom and /custom/index.html have 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:s0
Verify the contexts again using ls -Z.
ls -Zd /custom /custom/index.html
They should now have the httpd_sys_content_t context.
system_u:object_r:httpd_sys_content_t:s0 /custom
system_u:object_r:httpd_sys_content_t:s0 /custom/index.html
-
Access the web page again.
Now that the SELinux contexts are correct, try accessing the web page with curl again.
curl http://localhost/index.html
You should now see the content of your index.html file.
This is custom web content.
Finally, stop the Apache HTTP server process.
sudo pkill httpd
Verify that no httpd processes are running.
ps aux | grep httpd
You should only see the grep process itself.
labex ... grep httpd