When nginx meets SELinux: 403 Forbidden
This error happens when:
-
The nginx service is running on a SELinux system.
-
The nginx service is started by systemd, not manually from shell by user.
-
A server defines an alternative root directory (assuming the original root directory is
/usr/share/nginx/html
):server { ... root /srv/nginx; ... }
The error is: Browsing the index page will give a 403 Forbidden error.
Diagnose
If nginx user, file owner, group and permission are all correctly configured, then the problem may be caused by SELinux.
To diagnose:
-
Install these packages (Fedora):
# dnf install policycoreutils policycoreutils-python-utils setools-console
-
Check contexts of the old and new root directories:
# ls -Zd1 /usr/share/nginx/html /srv/nginx
Output:
unconfined_u:object_r:var_t:s0 /srv/nginx/ system_u:object_r:httpd_sys_content_t:s0 /usr/share/nginx/html
-
Check the context of the nginx process:
# ps -efZ | grep nginx
Output:
system_u:system_r:httpd_t:s0 ... nginx: master process ... system_u:system_r:httpd_t:s0 ... nginx: worker process ...
-
Search SELinux rules (for the old root directory):
# sesearch -s httpd_t -t httpd_sys_content_t -c file -A
Output:
allow httpd_t httpd_sys_content_t:file { getattr ioctl lock map open read }
-
Search SELinux rules (for the new root directory):
# sesearch -s httpd_t -t var_t -c file -A
Output: None.
The problem is obvious: The new root directory has a context that the nginx process cannot access.
Solution
Fix context on the new root directory:
# semanage fcontext -a -s system_u -t httpd_sys_content_t '/srv/nginx(/.*)?'
# restorecon -RFv /srv/nginx