For Linux users that have exposed themselves to RHEL-based distributions like RHEL, Fedora, AlmaLinux, and Rocky Linux, SELinux is not a new concept to them as it mostly comes pre-installed on their systems.
Why SELinux is Important?
SELinux or Security Enhanced Linux is a Linux security system attributed to role access. If you have worked with RHEL-based distributions, SELinux has probably tried to block most of your user-initiated actions (especially web-based configurations) until you almost (or successfully) opted to disable it.
However, disabling SELinux is strongly discouraged as it translates to weakening your server security footprints. The alternative approach to disabling SELinux is ensuring its configurations are correctly implemented. By understanding SELinux configurations, we can enable it to play nicely with other Linux-installed packages.
[ You might also like: How to Password Protect Directory in Nginx Web Server ]
This article will walk us through basic configurations that we can implement in SELinux for it to not only play nice with the Nginx web server but also harden it.
Installing Nginx Web Server in Linux
This article requires Nginx installed on your Linux operating system distribution. Refer to the following installation guide for different Linux package managers:
$ sudo apt install nginx [On Debian, Ubuntu and Mint] $ sudo yum install nginx [On RHEL/CentOS/Fedora and Rocky Linux/AlmaLinux] $ sudo apk add nginx [On Alpine Linux] $ sudo emerge -a nginx [On Gentoo Linux] $ sudo pacman -S nginx [On Arch Linux] $ sudo zypper install nginx [On OpenSUSE]
After nginx installation, you can enable, start and verify the status using the following commands.
$ sudo systemctl enable nginx $ sudo systemctl start nginx $ sudo systemctl nginx status
Installing SELinux in Linux
On Linux distributions like Debian, Ubuntu, Arch Linux, and Manjaro, you might need to remove/uninstall AppArmor before proceeding with the installation of SELinux as they are both Linux Security Module interface implementations of the Linux Kernel, and therefore cannot co-exist simultaneously.
$ sudo systemctl status AppArmor $ sudo systemctl stop AppArmor
After removing it via your Linux distribution package manager, reboot it before proceeding to install SELinux:
$ sudo apt remove --assume-yes --purge apparmor $ sudo reboot
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
$ sudo selinux-activate
Set SELinux to permissive mode to avoid errors like “failed to load kernel module” during system boot on Debian and Ubuntu systems.
$ sudo nano /etc/selinux/config
This mode will only print warnings.
$ sudo reboot
System relabeling should take place during bootup.
After a successful system reboot, check SELinux Status:
Hardening Nginx with SELinux
By default, SELinux labels Nginx (plus files and ports) with the httpd_t domain type. We can tell SELinux to let Nginx run in permissive mode (without restrictions). However, all SELinux-related errors will be logged by Linux.
$ semanage permissive -a httpd_t
On Debian and Ubuntu, don’t be triggered by “user sddm not in password file” as its a cosmetic (minor) warning.
The above-enforced SELinux policy not only applies to Nginx but also php-fpm.
Checking SELinux Violations
We will run the command:
$ sudo grep nginx /var/log/audit/audit.log | audit2allow -m nginx
The absence of policy violations will lead to the following output:
Otherwise, an SELinux policy will be built. The generated policy cannot be directly inherited as it only helps in identifying Nginx configuration errors.
SELinux and PHP-FPM
Use the following command to retrieve PHP-FPM-related errors:
$ sudo grep -R php-fpm /var/log/audit/audit.log
The final step to hardening our Nginx web server is enabling it to run in SELinux enforcing mode:’
$ sudo semanage permissive -d httpd_t
For extensive documentation on SELinux, refer to its manual page:
$ man selinux
SELinux ensures that Nginx operates on ideal security standards and policies.