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:

  1. Install these packages (Fedora):

    # dnf install policycoreutils policycoreutils-python-utils setools-console
    
  2. 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
    
  3. 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 ...
    
  4. 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 }
    
  5. 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

References