Security Enhanced Linux or SELinux is responsible for the implementation of mandatory access control mechanisms on major Linux distributions like Fedora, RHEL, and Rocky Linux. These access control mechanisms guarantee increased security on all processes and files within a Linux operating system distribution.
The way SELinux operates can be broken down into three modes:
- Enforcing: this mode implies that the SELinux policy is fully operational.
- Permissive: with this mode, no SELinux policy is enforced, however, SELinux prints associated warnings.
- Disabled: this mode indicates that no SELinux policy is in effect.
When web applications are not deployed from the default Apache directories (log or content), SELinux tends to be troublesome. When you try to run/test such web applications, SELinux will tend to prevent Apache from accessing logs and content not stored in the default Apache directory.
[ You might also like: How to Install SELinux to Harden Nginx Webserver ]
At this point, most users will find SELinux unbearable and do their best to disable it. However, a valid solution to this issue is creating custom SELinux policies for your files and directories. The advantage of this approach is that, if your context settings go missing, running a context restore will get your web app up and running again.
This article guide will address the following SELinux challenges:
- Web applications should be allowed to execute outside Apache’s default directory (/var/www/html).
- Apache is being blocked by SELinux when accessing content outside /var/www/html.
- Web applications read and write access restrictions.
- Web applications write access restrictions while uploading content from specific directories.
Installing Apache Web Server in Linux
This article requires Apache installed on your Linux operating system distribution. Refer to the following installation guide for different Linux package managers:
$ sudo apt install apache2 [On Debian, Ubuntu and Mint] $ sudo yum install httpd [On RHEL/CentOS/Fedora and Rocky Linux/AlmaLinux] $ sudo apk add apache2 [On Alpine Linux] $ sudo emerge -a apache [On Gentoo Linux] $ sudo pacman -S apache [On Arch Linux] $ sudo zypper install apache2 [On OpenSUSE]
After Apache installation, you can enable, start and verify the status using the following commands.
$ sudo systemctl enable apache2 $ sudo systemctl start apache2 $ sudo systemctl status apache2 OR $ sudo systemctl enable httpd $ sudo systemctl start httpd $ sudo systemctl status httpd
Installing SELinux in Linux
For users under Debian and Ubuntu distributions, or Linux distributions with AppArmor installed, consider uninstalling it first since it is also a Linux kernel implementation just like SELinux. They both function as Linux security modules and would collide/crash the system.
Check on AppArmor status, stop it, uninstall it, and reboot your system.
$ systemctl status apparmor $ sudo systemctl stop apparmor $ sudo apt remove apparmor $ sudo reboot
We can now proceed with the SELinux installation.
For RHEL-based distribution systems:
$ sudo dnf makecache $ sudo dnf install policycoreutils libselinux-utils libselinux libselinux-devel selinux-policy selinux-policy-devel
For Debian-based distribution systems:
$ sudo apt update $ sudo apt install policycoreutils selinux-utils selinux-basics libselinux1 libselinux1-dev
For openSUSE Leap and Tumbleweed Systems:
$ sudo zypper refresh $ sudo zypper install policycoreutils selinux-tools libselinux-devel libselinux1
Activate SELinux:
$ sudo selinux-activate
For Debian/Ubuntu users, setting SELinux to operate in enforcing mode will prompt the error “failed to load kernel module” during system reboot. We can therefore set it to operate in permissive mode.
$ sudo nano /etc/selinux/config
Reboot the machine:
$ sudo reboot
System relabeling should then take precedence:
After a successful system reboot, check SELinux Status:
$ sestatus
Hardening Apache with SELinux
Consider the following directory structure for web application projects:
To use Apache’s context type httpd_sys_content_t (files and directories read-only) on the parent directory and all sub-directories:
$ sudo semanage fcontext -a -t httpd_sys_content_t "/myapps(/.*)?"
Ignore the minor error associated with user sddm.
To use Apache’s context type httpd_log_t (generate and append log files) on the present logging directory:
$ sudo semanage fcontext -a -t httpd_log_t "/myapps/logs(/.*)?"
To use Apache’s context type httpd_cache_t (for caching) on the present cache directory:
$ sudo semanage fcontext -a -t httpd_cache_t "/myapps/cache(/.*)?"
To use httpd_sys_rw_content_t (files and directories read and write) on uploads directory:
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/myapps/app1/html/uploads(/.
To use httpd_sys_rw_content_t (files and directories read and write) on config.php file:
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/myapps/app1/html/config.php"
To apply the above-created SELinux policies, we will run:
$ sudo restorecon -Rv /myapps
Verify that the context types were applied:
$ ls -lZ /myapps
With these configurations, SELinux can secure and harden web applications run by Apache. For a better understanding of existing SELinux policies and default contexts, run:
$ sudo semanage fcontext -l