188

I am using the default config while adding the specific directory with nginx installed on my ubuntu 12.04 machine.

server {
        #listen   80; ## listen for ipv4; this line is default and implied
        #listen   [::]:80 default ipv6only=on; ## listen for ipv6

        index index.html index.htm;

        # Make site accessible from http://localhost/
        server_name localhost;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to index.html
                root /username/test/static;
                try_files $uri $uri/ /index.html;
                # Uncomment to enable naxsi on this location
                # include /etc/nginx/naxsi.rules
        }
...

...
}

I just want a simple static nginx server to serve files out of that directory. However, checking the error.log I see

2014/09/10 16:55:16 [crit] 10808#0: *2 stat() "/username/test/static/index.html" failed (13: Permission denied), client:, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "domain"
2014/09/10 16:55:16 [error] 10808#0: *2 rewrite or internal redirection cycle while internally redirecting to "/index.html

I've already done chown -R www-data:www-data on /username/test/static, I've set them to chmod 755. I don't know what else needs to be set.

techraf
  • 64,883
  • 27
  • 193
  • 198
user299709
  • 4,922
  • 10
  • 56
  • 88
  • 6
    Check if the `www-data` user can `cd` to the `/username/test/static` directory: `sudo -u www-data cd /username/test/static` – Maciej Sz Sep 10 '14 at 21:17
  • I am getting permission denied , but when i do ls -l it shows that its set to www-data user – user299709 Sep 10 '14 at 21:57
  • 2
    Could it be that /username is on encryptfs? I am having exactly the same issues with /home/username folder, where my site is located. If I move it out of encryptfs then all works fine. Still no solution for me... – Georgi Mar 27 '15 at 21:49

17 Answers17

320

Nginx operates within the directory, so if you can't cd to that directory from the nginx user then it will fail (as does the stat command in your log). Make sure the www-user can cd all the way to the /username/test/static. You can confirm that the stat will fail or succeed by running

sudo -u www-data stat /username/test/static

In your case probably the /username directory is the issue here. Usually www-data does not have permissions to cd to other users home directories.

The best solution in that case would be to add www-data to username group:

gpasswd -a www-data username

and make sure that username group can enter all directories along the path:

chmod g+x /username && chmod g+x /username/test && chmod g+x /username/test/static

For your changes to work, restart nginx

nginx -s reload
Freedom_Ben
  • 11,247
  • 10
  • 69
  • 89
Maciej Sz
  • 11,151
  • 7
  • 40
  • 56
  • Does it mean for every new directory added under the root, chmod has to be done to the new directories? –  Apr 26 '15 at 16:24
  • 2
    @ElgsQianChen keep in mind that this is OS level permission system, so in POSIX systems it depends on your [`umask`](https://en.wikipedia.org/wiki/Umask). If you need a more generic solution, that doesn't require `chmod`ing every new directory, then there is a solution. It requires reverse group association (`username` to `www-data` group) and the use of `setgid`. Feel free to post a new question for more elaborate description and I'll be happy to answer. – Maciej Sz Apr 27 '15 at 12:16
  • 1
    What if my path is in /root/ directory? Is it safe to do chmod g+x on /root ? And adding www-data to root group ? – Oleg Abrazhaev May 24 '16 at 05:59
  • 1
    On Fedora 24 my issue came about with... ACL permissions... another layer... YEY! – Ray Foss Sep 29 '16 at 00:28
  • 3
    Well my `nginx` user can able to access my website directory but still it says permission denied on the error logs. – Rahil Wazir Nov 09 '16 at 09:27
  • 1
    omg thank you thank you.! `gpasswd -a www-data username` was the answer. – Joshua F. Rountree Jan 22 '17 at 07:26
  • Why to username group? in my case username group does not exist. Then which should I use? – Darius.V Mar 26 '19 at 07:49
  • Thanks, I have tried almost one night. `sudo -u nginx stat /root/app/html` helped me, and I found the parent folder `/root/` does not have execute permission on others. – Donghua Liu Sep 25 '19 at 01:09
  • Though, gpasswd -a www-data username worked for me. But deleting the files & directories & taking a fresh copy of it worked as well. – user3785966 Apr 22 '20 at 08:19
  • you're a god amongst men – Eric Martins Jul 19 '22 at 00:27
  • 1
    Security-wise, is adding `www-data` to the `username` group considered to be safe? – Farzan Nov 04 '22 at 01:11
  • I've literally spent 6 hours trying to figure out what's wrong with my nginx configuration.. omg thanks a lot! – Vitaly Kharlakov Aug 15 '23 at 15:22
201

Nginx need to have +x access on all directories leading to the site's root directory.

Ensure you have +x on all of the directories in the path leading to the site's root. For example, if the site root is /home/username/siteroot:

chmod +x /home/
chmod +x /home/username
chmod +x /home/username/siteroot
Sairam Krish
  • 10,158
  • 3
  • 55
  • 67
119

I've just had the same problem on a CentOS 7 box.

Seems I'd hit selinux. Putting selinux into permissive mode (setenforce permissive) has worked round the problem for now. I'll try and get back with a proper fix.

Andrew Richard Miller
  • 1,291
  • 1
  • 8
  • 4
  • 6
    This is the exact "not documented" behavior I was trying to understand for these last 3 days... – Achilles Jun 20 '15 at 08:49
  • 3
    Here is a post about this behavior: http://axilleas.me/en/blog/2013/selinux-policy-for-nginx-and-gitlab-unix-socket-in-fedora-19/ – Achilles Jun 20 '15 at 08:57
  • 5
    So, I found myself back here... This time I find I copied the file in question from my home directory to the html directory, and updated the ownership. Same issue as 2015... Better fix: `ls -Z myFile.js` will show the SELinux context: `-rw-r--r--. nginx nginx unconfined_u:object_r:user_home_t:s0 myFile.js` Use `chcon -v --type=httpd_sys_content_t myFile` to change the SELinux content. – Andrew Richard Miller Jan 29 '18 at 14:32
  • 8
    Yup; I had the same issue. `sudo setenforce 0` fixed it for me. – Overload119 Nov 10 '18 at 20:13
  • Tried every single solution online for days.. this worked in a second #facepalm – Aswin Ramakrishnan Jan 04 '19 at 14:08
  • NGINX has some pretty great docs about this here: https://www.nginx.com/blog/using-nginx-plus-with-selinux/#Issue-2:-File-Access-is-Forbidden – Nick Swope Nov 29 '19 at 07:01
  • 1
    Just a note, if you want selinux completely disabled, you'll need to change the `SELINUX` value to `disabled` in `/etc/selinux/config`, followed by a reboot. When it's set to `permissive`, it can still run checks behind the scenes (using valuable CPU), but take no action. – Oliver Tappin Dec 28 '19 at 20:19
  • I've never had any benefit from SElinux, and I've frequently had problems like this with it. :/ – msb Jun 20 '20 at 02:00
  • the easy 'proper fix' is to only serve files from inside /usr/share/nginx/ which is permitted by default. if you absolutely need to serve files stored in another directory have a look at 'Issue 2: File Access is Forbidden' here: https://www.nginx.com/blog/using-nginx-plus-with-selinux/ – user1259710 Jan 24 '22 at 17:27
  • Thanks Andrew Richard Miller, It's very helpful. – thach.nv92 Feb 17 '22 at 02:24
39

On CentOS 7.0 I had this Access Deined problem caused by SELinux and these steps resolved the issue:

yum install -y policycoreutils-devel
grep nginx /var/log/audit/audit.log | audit2allow -M nginx
semodule -i nginx.pp

Update: Just a side-note from what I've learned while using digitalocean's virtual Linux servers, or as they call them Droplets. Using SELinux requires a decent amount of RAM. It's most probably like you won't be able to run and manage SELinux on a droplet with less than 2GB of RAM.

Achilles
  • 1,554
  • 1
  • 28
  • 36
  • 2
    Thanks very much for this. It did solve my problem (also on CentOS 7) to begin with, but then I was blocked by a second denial elsewhere, so resorted to `setenforce 0`. However, when looking back at what this solution actually does, I realised that I needed to re-run the commands to update the permissions for the nginx user. That seemed to work and I could set SELinux back to enforcing. – danj1974 Aug 21 '15 at 10:57
  • Well, this may be a bit too late. Still, it's worth mentioning that when you keep SELinux enforcing; it is imperative to remember, software like Nginx insert their own set of rules like default ports, default paths, read/write access to paths, etc. into SELinux. If you don't want any trouble, you must follow those rules (like putting your HTML/PHP files into /var/www) or else prepare to overcome problems originating deep in the SELinux context. This can be helpful [CentOS < 8]: https://www.getpagespeed.com/server-setup/nginx/nginx-selinux-configuration – Achilles Jan 08 '20 at 09:06
37

You may have Security-Enhanced Linux running, so add rule for that. I had permission 13 errors, even though permissions were set and user existed..

chcon -Rt httpd_sys_content_t /username/test/static

Artjom Kurapov
  • 6,115
  • 4
  • 32
  • 42
33

To check the default Nginx users:

sudo ps aux| grep nginx

You will get an output like this:

root       69558  0.0  0.0  66276  1708 ?        Ss   10:14   0:00 
nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data   69559  0.0  0.1  66516  5540 ?        S    10:14   0:00 nginx: worker process
www-data   69560  0.0  0.1  66516  6944 ?        S    10:14   0:00 nginx: worker process
root       69794  0.0  0.0   8168   672 pts/1    S+   10:19   0:00 grep --color=auto nginx

Also, check the nginx.conf file using any text editor of your choice: I will be using vim:

vim /etc/nginx/nginx.conf

enter image description here

Solution:

  1. Change the www-data user in the nginx.conf file to root, in case you are on root user. enter image description here
  1. The Second solution is to add the user www-data to root group.
Boanerges
  • 1,265
  • 12
  • 9
8

This is how i fixed this

sudo chmod o+x /home/ec2-user
  • 1
    This worked for me. But more explaination of the issue would have been best. – Vishnu Kyatannawar Nov 16 '21 at 20:00
  • 1
    This is the only thing that worked for me. I kept getting "chmod: changing permissions of '/home/': Operation not permitted" when trying the answers from above. Big thanks. – Nunchuk Dec 04 '22 at 03:53
  • 1
    my nginx user could not change directory to required destination. above command worked for me. – mrtechmaker Jan 09 '23 at 15:52
6

I finally found my way through. In short, let's say your username is joe and you hold a website under your personal filesystem /home/joe/path/to/website.

You literally have to tell the system that nginx is your pal.
Place nginx in joe group :

sudo gpasswd -a nginx joe

After that if it still doesn't work, check right access of /home/joe directory. That's probably the reason why nginx can't reach the file because even if he is your friend now you have to open him the door to your house :

sudo chmod g+x /home/joe

That's it. That's literally all you have to do to give nginx access to your local files :)

I don't think there are security concerns with this method because nginx is the high authority and only an admin can change the group. nginx can now read what's in joe directories. It's only a security breach if the holder of the nginx account is different with the user you open directory access from, but in my case I'm the holder of both parties, that is in a local context.

vdegenne
  • 12,272
  • 14
  • 80
  • 106
4

Symptom:

Could not upload images to WordPress Media Library.

Cause:

(CentOS) yum update

Error:

2014/10/22 18:08:50 [crit] 23286#0: *5332 open() "/var/lib/nginx/tmp/client_body/0000000003" failed (13: Permission denied), client: 1.2.3.4, server: _, request: "POST /wp-admin/media-new.php HTTP/1.1", host: "example.com", referrer: "http://example/wp-admin/media-new.php"

Solution:

chown -R www-data:www-data /var/lib/nginx

PJ Brunet
  • 3,615
  • 40
  • 37
4

I faced this problem, I solved it to give permissions to nginx user and group something like this:

chown -R nginx:nginx /username/test/static
julian salas
  • 3,714
  • 1
  • 19
  • 20
  • 1
    actually worked, notice that if you are running nginx in docker container and your nginx.conf file starts with user nginx; so in your dockerfile you should have copy ./nginx.conf /etc/nginx/nginx.conf RUN chown -R nginx:nginx /usr/share/nginx/html/ to give your user the write privilege – Amr Jan 15 '21 at 13:55
3

Change your nginx.conf user property to www-static files owener.

#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user your_user_name;

# same other config
2

By default the static data, when you install the nginx, will be in /var/www/html. So you can just copy your static folder into /var/html/ and set the

root /var/www/<your static folder>

in ngix.conf (or /etc/nginx/sites-available/default)

This worked for me on ubuntu but I guess it should not be much different for other distros.

Hope it helps.

Patrik Bego
  • 4,009
  • 1
  • 26
  • 24
2

In my case, the folder which served the files was a symbolic link to another folder, made with

ln -sf /origin /var/www/destination

Even though the permissions (user and group) where correct on the destination folder (the symbolic link), I still had the error because Nginx needed to have permissions to the origin folder whole's hierarchy as well.

0

I had the same issue, I am using Plesk Onyx 17 with Centos7. I could see this error in proxy_error_log under the affected domain's logs. All the dirs/files in /var/www/vhosts/ are owned by respective users (domain owners) and you can see that all of them are in psacln group. So solution was to add nginx also to this group, so he can see what he needs:

usermod -aG psacln nginx

And indeed, restart nginx and reload page with Ctrl+F5.

0

I found a work around: Moved the folder to nginx configuration folder, in my case "/etc/nginx/my-web-app". And then changed the permissions to root user "sudo chown -R root:root "my-web-app".

Dheeraj
  • 1
  • 1
0

This is usually the privilege problem... For me, its because i use the /root/** as the nginx root, it need higher privilege. An easy way is just move the project into a directory created by yourself.

sch001
  • 71
  • 4
-4

You can also add which user will run the nginx. In the nginx.conf file, make the following changes:

user root;

You can add the above line as the first line in your nginx conf. You can write the name of any user who has the permission to write in that directory.