Nginx: stat()失败(13:权限被拒绝)

194

我在使用默认配置的同时,在我的ubuntu 12.04机器上安装了nginx,并添加了特定目录。

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
        }
...

...
}

我只想要一个简单的静态nginx服务器,用于从那个目录中提供文件服务。但是,通过检查error.log,我发现

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

我已经在/username/test/static上执行了chown -R www-data:www-data,并将其设置为chmod 755。我不知道还需要设置什么。


6
请检查 www-data 用户是否可以进入 /username/test/static 目录:sudo -u www-data cd /username/test/static - Maciej Sz
我得到了“权限被拒绝”的错误,但是当我执行ls -l命令时,它显示设置为www-data用户。 - user299709
2
可能是/username在encryptfs上吗?我在/home/username文件夹中遇到了完全相同的问题,我的网站就在那里。如果我将其移出encryptfs,则一切正常。 对我来说仍然没有解决方案... - Georgi
17个回答

337

Nginx运行在指定的目录下,所以如果无法从nginx用户切换到该目录,则会失败(就像日志中的stat命令一样)。确保www-user可以一直cd/username/test/static目录。您可以通过运行以下命令来确认stat命令是否成功:

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

在您的情况下,/username 目录可能是问题所在。通常情况下,www-data 没有权限 cd 到其他用户的主目录。

在这种情况下,最好的解决方案是将 www-data 添加到 username 组中:

gpasswd -a www-data username

并确保用户名组可以进入路径上的所有目录:

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

要使更改生效,请重新启动 nginx。

nginx -s reload

2
@ElgsQianChen 请注意这是操作系统级别的权限系统,在 POSIX 系统中,它取决于您的 umask 设置。如果您需要一个更通用的解决方案,而不需要在每个新目录上运行 chmod 命令,则有一种解决方案。它需要反向组关联(将“用户名”分配到“www-data”组)和使用 setgid。如果需要更详细的说明,请随时发布新问题,我很乐意回答。 - Maciej Sz
1
在Fedora 24上,我的问题出现在ACL权限上...又多了一层...太好了! - Ray Foss
3
我的 nginx 用户可以访问我的网站目录,但错误日志仍然显示权限被拒绝。 - Rahil Wazir
3
哦,谢谢你!gpasswd -a www-data username就是答案。 - Joshua F. Rountree
1
从安全角度来看,将www-data添加到username组中是否被认为是安全的? - Farzan
显示剩余7条评论

212

Nginx需要对通往网站根目录的所有目录具有+x权限。

确保您对通向网站根目录的路径中的所有目录都具有+x权限。例如,如果网站根目录为/home/username/siteroot:

chmod +x /home/
chmod +x /home/username
chmod +x /home/username/siteroot

3
谢谢Krish!它起作用了,并且有一个清晰的解释。 - Ninja
3
我已经仔细检查了一切,但是没有成功!这就是我错过的东西。 - Mojtaba Rezaeian
1
这是正确的答案,因为它解释了问题的根本原因!默认情况下需要(+x访问权限),但不需要(+r访问权限)。 - Yuriy Litvin
谢谢。在我尝试了一切之后,这个解决方案对我起了作用。 - undefined

120

我在一个CentOS 7机器上遇到了同样的问题。

似乎是被selinux阻止了。现在将selinux设置为寬容模式(setenforce permissive)已经解决了这个问题。我会尝试找到一个更好的解决方案再回来。


6
这正是我过去三天一直试图理解的“未记录”行为... - Achilles
3
这是一篇关于以下行为的帖子:http://axilleas.me/en/blog/2013/selinux-policy-for-nginx-and-gitlab-unix-socket-in-fedora-19/。 - Achilles
6
所以,我发现自己又回到了这里...... 这一次,我发现我将有问题的文件从我的个人目录复制到了HTML目录,并更新了所有权。和2015年遇到的问题一样...... 更好的解决方法: ls -Z myFile.js会显示SELinux上下文: -rw-r--r--. nginx nginx unconfined_u:object_r:user_home_t:s0 myFile.js 使用 chcon -v --type=httpd_sys_content_t myFile 来更改SELinux内容。 - Andrew Richard Miller
8
是的,我也遇到了同样的问题。使用“sudo setenforce 0”命令解决了我的问题。 - Overload119
1
请注意,如果您想完全禁用SELinux,则需要在/etc/selinux/config中将SELINUX值更改为disabled,然后重新启动。当设置为“permissive”时,它仍然可以在后台运行检查(使用有价值的CPU),但不采取任何措施。 - Oliver Tappin
显示剩余5条评论

39

我在CentOS 7.0上遇到了由SELinux引起的访问被拒绝问题,以下步骤解决了这个问题:

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

更新: 我在使用DigitalOcean的虚拟Linux服务器时了解到一些内容,或者他们称之为Droplets。使用SELinux需要相当数量的RAM。很可能你无法在少于2GB的内存的Droplet上运行和管理SELinux。


2
非常感谢您的帮助。这确实解决了我的问题(在CentOS 7上也是如此),但随后我又被另一个拒绝所阻止,因此不得不使用setenforce 0。然而,当回顾这个解决方案实际上做了什么时,我意识到我需要重新运行命令以更新nginx用户的权限。这似乎起作用了,我可以将SELinux设置回强制执行。 - danj1974
好吧,这可能有点晚了。不过还是值得一提的是,当您保持SELinux强制执行时,务必记住像Nginx这样的软件将其自己的规则(如默认端口,默认路径,对路径的读/写访问权限等)添加到SELinux中。如果您不想遇到任何麻烦,必须遵循这些规则(例如将HTML / PHP文件放入/var/www);否则,准备克服在SELinux上下文中深层次产生的问题。 这可以帮助[CentOS <8]:https://www.getpagespeed.com/server-setup/nginx/nginx-selinux-configuration - Achilles

37

您可能正在运行安全增强型Linux,因此需要为其添加规则。

即使权限已设置且用户存在,我仍然遇到了13个错误的权限问题。

chcon -Rt httpd_sys_content_t /username/test/static

注:该命令用于更改文件或目录的SELinux上下文。

谢谢!在CentOS 6.10(最终版)上工作过。 - marw
1
在CentOS 7.5.1804(核心版)上工作。 - Niek

33

查看默认的Nginx用户:

sudo ps aux| grep nginx

你将会得到这样的输出:

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

同时,使用您选择的任何文本编辑器检查nginx.conf文件:我将使用vim:

vim /etc/nginx/nginx.conf

图片描述

解决方案:

  1. 如果您是root用户,可以在nginx.conf文件中将www-data用户更改为root。 图片描述
  1. 第二种解决方法是将用户www-data添加到root组中。

2
经过超过10小时的搜索,这就是对我有效的方法,谢谢。 - Abayomi Olowu
3
这是一个安全的操作吗?我可以在生产环境中使用它吗? - Eugene Zalivadnyi
2
这取决于很多事情,但出于安全考虑,我会使用第二种方法。将nginx设置为根目录不是一个好主意。 - Boanerges
1
非常感谢您深入挖掘后给出的答案,它对我非常有帮助。 - JIGNESH PATEL
1
终于,在与此问题苦苦斗争了几天后,修复了文件和文件夹权限,包括 SELinux 权限。这是我在 docker+nginx 挂载卷设置中唯一有效的方法。 - Rumen Rumenov
显示剩余2条评论

11

这是我修复问题的方法

sudo chmod o+x /home/ec2-user

1
这对我有用。但更详细地解释问题会更好。 - Vishnu Kyatannawar
1
这是唯一对我起作用的方法。当我尝试以上答案时,我一直收到“chmod: changing permissions of '/home/': Operation not permitted”的错误提示。非常感谢。 - Nunchuk
1
我的nginx用户无法更改目录到所需的目标位置。以上命令对我起作用了。 - mrtechmaker
这个方法是有效的,直觉上我们可以说将代理服务器设置为根用户的接受答案将是一个很大的风险,这里有一个关于这个问题的讨论 - https://serverfault.com/a/1010924 - undefined
整整花了一天的时间试图修复这个问题,没有任何人工智能帮助我哈哈。这个方法有效。谢谢!请将ec2-user替换为您适当的用户名。 - undefined

6
我终于找到了解决方案。简而言之,假设你的用户名为joe,并且你在个人文件系统下拥有一个网站路径/home/joe/path/to/website
你需要告诉系统nginx是你的好伙伴。 将nginx放入joe组中:
sudo gpasswd -a nginx joe

如果仍然无法工作,请检查 /home/joe 目录的正确访问权限。这可能是 nginx 无法访问文件的原因,因为即使他现在是你的朋友,你也必须为他打开你家门:

sudo chmod g+x /home/joe

就这样。你只需要做这些就可以让 nginx 访问你本地的文件啦 :)

我认为这种方法没有安全方面的问题,因为 nginx 拥有高权限,只有管理员才能更改该组。现在,nginx 可以读取 joe 目录中的内容。只有当 nginx 帐户的持有者与您开放目录访问权限的用户不同时,才会存在安全漏洞。但在我的情况下,我是双方的持有人,即在本地环境中。


将主文件夹更改为可执行文件(chmod g+x)在我的情况下有效。 - MyounghoonKim

4

症状:

无法上传图片至WordPress媒体库。

原因:

(CentOS) yum update

错误:

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"

解决方案:
运行以下命令更改/var/lib/nginx目录的所有者为www-data用户组。 chown -R www-data:www-data /var/lib/nginx

4

我遇到了这个问题,解决方法是给nginx用户和组授予权限,类似于以下内容:

chown -R nginx:nginx /username/test/static

1
实际上是有效的,注意如果您正在Docker容器中运行nginx,并且您的nginx.conf文件以user nginx;开头,则在您的Dockerfile中应该有copy ./nginx.conf /etc/nginx/nginx.conf RUN chown -R nginx:nginx /usr/share/nginx/html/以授予用户写入权限。 - Amr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接