Nginx服务静态文件时出现403禁止访问的错误。

109

我只是想帮助别人。是的,你只是想使用nginx来提供静态文件,并且在nginx.conf中已经做好了一切:

location /static {
       autoindex on;
       #root /root/downloads/boxes/;
       alias /root/downloads/boxes/;
      }

但是,最终你失败了。你的浏览器显示“403禁止访问”...

----------------------------------------以下是答案:----------------------------------------

解决方法非常简单:


方法1:以 '/root/downloads/boxes/' 的所有者身份运行nginx

nginx.conf中:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;

是的,在第一行中"#user noboy;",只需删除"#",并将"nobody"更改为Linux/OS X中您自己的用户名,例如测试时更改为"root"。重新启动nginx。

注意:最好不要以root身份运行nginx!这里仅用于测试,对黑客来说是危险的。

更多参考,请参见nginx (engine X) – What a Pain in the BUM! [13: Permission denied]


方法2:将'/root/downloads/boxes/'所有者更改为'www-data'或'nobody'

终端中:

ps aux | grep nginx

获取正在运行的nginx的用户名。它应该是由nginx版本确定的'www-data''nobody'。然后在终端中输入以下命令(以'www-data'为例):

chown -R www-data:www-data /root/downloads/boxes/

------------------------------还有一件重要的事情需要注意:------------------------------

这些父级目录"/""/root""/root/downloads"应该授予'www-data''nobody'执行(x)权限。即:

ls -al /root
chmod o+x /root
chmod o+x /root/downloads

更多参考,请查看解决"403 Forbidden"错误Nginx所有文件都显示403禁止访问


2
你也可以将文件授权给nginx所在的组,这通常是做法,并且更加合乎逻辑。 - gitaarik
1
你重启了nginx吗?另外,NGINX有错误日志文件(通常在/var/log/nginx/),您可以在其中找到更多信息,例如检查错误和访问日志。顺便说一句,也许你应该在我的答案下发表评论,而不是在你的问题下。 - gitaarik
“user root” 在我的开发机上完美运行。 - necromancer
1
@no_answer_not_upvoted,嘿,小心“root”,如果黑客攻击你的nginx服务器,root将成为黑客。 - isaacselement
1
请不要以root身份运行nginx! - Poli
显示剩余2条评论
13个回答

92

您应该允许nginx读取该文件。这意味着您应该授予运行nginx进程的用户读取该文件的权限。

运行nginx进程的用户可以在nginx配置中使用user指令进行配置,通常位于nginx.conf文件的顶部:

user www-data

http://wiki.nginx.org/CoreModule#user

user的第二个参数是组名,但如果没有指定,它会使用与用户相同的组。因此在我的例子中,用户和组都是www-data

现在您想要通过nginx提供服务的文件应该具有正确的权限。Nginx应该具有读取文件的权限。您可以像这样将组www-data赋予文件读取权限:

chown :www-data my-file.html

http://linux.die.net/man/1/chown

使用 chown 命令可以更改文件的用户和组所有者。在此命令中,我仅更改了组,如果您也想更改用户,则应该在冒号前指定用户名,例如 chown www-data:www-data my-file.html。但正确设置组权限就足以使nginx能够读取该文件。


25
“用户root”解决了这个问题,并确保它永远不会再出现。(开始狂喜!;-) - necromancer
14
可能修复起来很容易,但以root身份运行程序可能存在危险。如果Nginx中存在漏洞,并以root身份运行,黑客可能能够完全接管操作系统。 - gitaarik
1
请注意我的过度呼吸的评论。是的,这是一个有效的关注点,但通常机器专用于nginx或没有关键信息,因此即使黑客接管了它也没什么大不了的。如果您在服务器上运行nginx并且该服务器还具有您公司的所有IP和电子邮件,则确实有效。 - necromancer
1
我顺便点了个赞,因为它有助于在你需要正确处理事情的时候。 - necromancer

47

由于Nginx直接处理静态文件,因此它需要访问适当的目录。我们需要为我们的主目录授予可执行权限,以便将其添加到Nginx用户组中。这样,我们就可以将可执行权限添加到主目录的组所有者中,仅为Nginx提供足够的访问权限以提供文件服务:

CentOS / Fedora

  sudo usermod -a -G your_user nginx

  chmod 710 /home/your_user 
设置 SELinux 为全局宽容模式,请运行:sudo setenforce 0。更多信息请访问 https://www.nginx.com/blog/using-nginx-plus-with-selinux/Ubuntu / Debian
  sudo usermod -a -G your_user www-data

  sudo chown -R :www-data /path/to/your/static/folder

4
谢谢!我在网上搜索了几个小时,只有你的答案有用。非常感谢!! - Logan Yang
3
由于“Ubuntu”解决方案,现在我无法通过ssh登录! - Miguel
1
Ubuntu的解决方案对我很有帮助,谢谢! - Bruce
1
在同一文件夹中,所有文件都具有相同的权限标志,但只有一个文件无法访问(出现nginx的权限被拒绝错误)。将SELinux设置为宽容模式解决了我的问题。 - Gary Wang

17

更改所有文件夹中的组所有者,请执行以下命令:

sudo chown -R :www-data static_folder

其中static_folder是文件夹名字。


一个非常直截了当的答案。 - Saksham Khurana

14

我在一个Django项目中遇到了这个问题。更改用户权限和组没有起作用。然而,将整个静态文件夹从我的项目移动到/var/www解决了问题。

将项目的静态文件复制到/var/www/static

# cp -r /project/static /var/www/static

将nginx指向正确的目录
(注意:保留HTML标签)
# sudo nano /etc/nginx/sites-available/default

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        location /static/ {
                root /var/www;
        }

        location / {
                include proxy_params;
                proxy_pass http://unix:/run/gunicorn.sock;
        }

}

测试Nginx配置并重新加载
# sudo nginx -t
# sudo systemctl reload nginx

2
每一个答案都不行,除了这个。非常感谢! - user
1
同样的,这个答案是唯一适用于我的答案。非常感谢你。 - Dhia Shalabi

11

对我来说是SElinux,我需要运行以下命令:(在AWS上运行的RHEL / Centos)

sudo setsebool -P httpd_can_network_connect on 
chcon -Rt httpd_sys_content_t /var/www/

谢谢!我在我的远程开发箱上使用的是Fedora,并且不习惯SELinux。这正是我正在寻找的评论 :) - Lyndsy Simon
2
只需运行 chcon -Rt httpd_sys_content_t /var/www/ 即可完美解决。 - noomz
在Centos 7上运行Flask和Nginx没有任何问题。最近更新到Almalinux后,出现了403禁止访问的问题,让我非常苦恼。更改用户权限没有起到任何好的作用。最终,这个命令对我有用,但是我将其用于静态文件夹而不是/var/ww/!谢谢! - Majte

9

在查阅了一些非常有用的答案后,我们决定将与权限相关的所有内容收集起来作为一份指南。具体而言,这是一种“最简单的解决方案,同时又具备最大的安全性”(即最小权限)。

  1. 假设我们将网站部署为用户admin,也就是说,她拥有网站目录及其内部的一切。我们不希望以该用户身份运行nginx(权限太大)。虽然可以用于测试,但不能用于生产环境。
  2. Nginx默认情况下将工作进程作为用户nginx运行,也就是说,配置文件包含user nginx这一行。
  3. 默认情况下,用户nginx属于同名组:nginx
  4. 我们希望给用户nginx最小的权限,而不改变文件所有权。这似乎是天真的选项中最安全的一个。
  5. 为了提供静态文件服务,文件夹层次结构中所需的最小权限(请参见组权限)应如下所示(使用命令namei -l /home/admin/WebProject/site/static/hmenu.css):

    dr-xr-xr-x root root /
    drwxr-xr-x root root home
    drwxr-x--- admin nginx admin
    drwx--x--- admin nginx WebProject
    drwx--x--- admin nginx site
    drwx--x--- admin nginx static
    -rwxr----- admin nginx hmenu.css

  6. 接下来,如何得到这个漂亮的图片呢?为了更改目录的组所有权,我们首先应用sudo chown :nginx /home/admin/WebProject/site/static,然后逐一从右侧剥离目录。

  7. 为了更改目录的权限,我们应用sudo chmod g+x /home/admin/WebProject/site/static,然后再次剥离目录。

  8. 更改/static目录中文件的组:sudo chown -R :nginx /home/admin/WebProject/site/static

  9. 最后,更改/static目录中文件的权限:sudo chmod g+r /home/admin/WebProject/site/static/*

(当然,可以创建一个专门的组并更改用户名,但这将使叙述变得复杂而不重要。)


5

在nginx中设置用户root可能非常危险。必须将权限设置到所有文件层次结构,这可能会很麻烦(想象一下文件夹的完整路径在10个以上的子文件夹中)。

我建议的做法是使用bindfs,在/usr/share/nginx/any_folder_name下为nginx配置的用户(通常是www-data)赋予权限,以便共享所需的文件夹。

在您的情况下,我会执行以下操作:

sudo bindfs -u www-data -g www-data /root/downloads/boxes/ /usr/share/nginx/root_boxes

它会将 /root/downloads/boxes 挂载到 /usr/share/nginx/root_boxes,所有权限都赋予用户 www-data。现在你可以在你的 location block 配置中设置该路径。
location /static {
   autoindex on;
   alias /usr/share/nginx/root_boxes/;
  }

1
在使用chmod等不同设置进行测试后,这对我来说似乎是最合适(也是最安全)的方式。最终对我起作用了。谢谢! :) - Phil
1
这个方法对我很有帮助。我改变了静态文件夹的所有权和权限,但显然我的工作路径不允许Nginx访问。我不想给www-data用户组在整个根目录向上的所有位置都授予权限。这是一个好的解决方案。 - RicHincapie

4

尝试使用@gitaarik提供的被接受的答案,如果仍然出现403 Forbidden404 Not Found并且你的目标位置是/,请继续阅读。

我也遇到了这个问题,但是上面提到的权限更改都没有解决我的问题。通过添加root指令来解决问题,因为我正在定义根位置(/),而不小心使用了alias指令,应该使用root指令。

配置被接受,但如果启用/的自动索引,则会出现403 Forbidden404 Not Found

location / {
  alias /my/path/;
  index index.html;
}

正确的定义:

location / {
  root /my/path/;
  index index.html;
}

3
你可以像我所做的那样操作: CentOS / Fedora
sudo usermod -a -G your_user_name nginx

chmod 710 /home/your_user_name 

Ubuntu / Debian

sudo usermod -a -G your_user_name www-data

sudo chown -R :www-data /path/to/your/static_folder

在您的nginx文件中,确保为您的站点提供服务的位置的static如下所示:
location /static/ {
        root /path/to/your/static_folder;
    }

1
对于那些按照@sandes在Ubuntu上的答案被锁定ssh的人,您需要以具有权限的用户身份重新获得访问权限并运行此命令。
sudo gpasswd -d www-data your_user

这将从组中删除www-data用户,并允许您重新登录。


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