Why does Nginx return a 403 even though all permissions are set properly?

I have Nginx setup and displaying the test page properly. If I try to change the root path, I get a 403 Forbidden error, even though all permissions are identical. Additionally, the nginx user exists.

nginx.conf:

user nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log;

pid        /run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    index   index.html index.htm;

    server {
        listen       80;
        server_name  localhost;
        root         /var/www/html; #changed from the default /usr/share/nginx/html
    }
}

namei -om /usr/share/nginx/html/index.html

f: /usr/share/nginx/html/index.html
dr-xr-xr-x root root /
drwxr-xr-x root root usr
drwxr-xr-x root root share
drwxr-xr-x root root nginx
drwxr-xr-x root root html
-rw-r--r-- root root index.html

namei -om /var/www/html/index.html

f: /var/www/html/index.html
dr-xr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-xr-x root root html
-rw-r--r-- root root index.html

error log

2014/03/23 12:45:08 [error] 5490#0: *13 open() "/var/www/html/index.html" failed (13: Permission denied), client: XXX.XX.XXX.XXX, server: localhost, request: "GET /index.html HTTP/1.1", host: "ec2-XXX-XX-XXX-XXX.compute-1.amazonaws.com"


Solution 1:

I experienced the same problem and it was due to SELinux.

To check if SELinux is running:

# getenforce

To disable SELinux until next reboot:

# setenforce Permissive

Restart Nginx and see if the problem persists. If you would like to permanently alter the settings you can edit /etc/sysconfig/selinux

If SELinux is your problem you can run the following to allow nginx to serve your www directory (make sure you turn SELinux back on before testing this. i.e, # setenforce Enforcing)

# chcon -Rt httpd_sys_content_t /path/to/www

If you're still having issues take a look at the boolean flags in getsebool -a, in particular you may need to turn on httpd_can_network_connect for network access

# setsebool -P httpd_can_network_connect on

For me it was enough to allow http to serve my www directory.

Solution 2:

First of all you have to run following command to allow nginx to access filesystem

sudo setsebool -P httpd_read_user_content 1

You can check if the files or directory with following command:

ls -Z

If it is still not accessible, you can try changing the SELinux property of the files and folder with following command:

chcon -Rt httpd_sys_content_t /path/to/www

However, above command cannot apply to files under FUSE or NFS system.

To enable serving files from FUSE mounts, you can use:

setsebool httpd_use_fusefs 1

To enable serving files from NFS mounts, you can use:

setsebool httpd_use_nfs 1

Solution 3:

I ran into the same problem. If you're using Fedora/RedHat/CentOS, this might help you:

  • According to SELinux: setsebool -P httpd_read_user_content 1

Hope this helps.

Solution 4:

There are 2 possible reasons for denied access:

  1. Access is denied by DAC. Double check user, group and file permissions. Make sure the nginx process, when running as the user specified in its config file, can access the new html root path.

  2. Access is denied by MAC. The most widely used of such is SELinux. To check whether it caused the problem, you can stop the nginx process and run this command:

    setenforce Permissive
    

    Then start nginx again to see if access is granted.

    Alternatively, you can check the file context:

    setenforce Enforcing
    ls -Zd /usr/share/nginx/html /var/www/html
    

    If the two contexts differ, you may need to change the context for the new html root path:

    chcon -R -t httpd_sys_content_t /var/www/html
    

    Restart nginx and see if it works fine. If so, you can make the change permanent:

    semanage fcontext -a -t httpd_sys_content_t '/var/www/html(/.*)?'
    restorecon -Rv /var/www/html
    

    Some of these commands need to be run as root.

Solution 5:

This is an addition to Prowlas answer but I dont have enough reputation to commment: If the /path/to/www is a home directory of a user. You should try:

setsebool -P httpd_enable_homedirs=1

This solved my problem

Source: http://forums.fedoraforum.org/archive/index.php/t-250779.html