【问题标题】:Nginx 403 forbidden for all files禁止所有文件使用 Nginx 403
【发布时间】:2011-10-11 08:11:33
【问题描述】:

我在 CentOS 5 机器上安装了带有 PHP-FPM 的 nginx,但我很难让它为我的任何文件提供服务——无论是否是 PHP。

Nginx 以 www-data:www-data 运行,默认的“Welcome to nginx on EPEL”站点(由 root:root 拥有,具有 644 权限)加载正常。

nginx 配置文件有一个 /etc/nginx/sites-enabled/*.conf 的包含指令, 我有一个配置文件 example.com.conf ,因此:

server {
 listen 80;

 Virtual Host Name
 server_name www.example.com example.com;


 location / {
   root /home/demo/sites/example.com/public_html;
   index index.php index.htm index.html;
 }

 location ~ \.php$ {
  fastcgi_pass   127.0.0.1:9000;
  fastcgi_index  index.php;
  fastcgi_param  PATH_INFO $fastcgi_script_name;
  fastcgi_param  SCRIPT_FILENAME  /home/demo/sites/example.com/public_html$fastcgi_script_name;
  include        fastcgi_params;
 }
}

尽管 public_html 归 www-data:www-data 所有,拥有 2777 文件权限,但此站点无法提供任何内容 -

 [error] 4167#0: *4 open() "/home/demo/sites/example.com/public_html/index.html" failed (13: Permission denied), client: XX.XXX.XXX.XX, server: www.example.com, request: "GET /index.html HTTP/1.1", host: "www.example.com"

我发现了许多其他用户从 nginx 获得 403 的帖子,但我看到的大多数帖子要么涉及使用 Ruby/Passenger 进行更复杂的设置(过去我实际上已经成功),要么仅在以下情况下收到错误涉及到上游的PHP-FPM,所以他们似乎帮助不大。

我在这里做了什么傻事吗?

【问题讨论】:

标签: nginx centos http-status-code-403 php


【解决方案1】:

一个经常被忽视的权限要求是用户需要在文件的每个父目录中拥有 x 权限才能访问该文件。检查 /、/home、/home/demo 等的权限以获取 www-data x 访问权限。我的猜测是 /home 可能是 770 并且 www-data 不能通过它来访问任何子目录。如果是,请尝试 chmod o+x /home(或任何拒绝请求的目录)。

编辑:要轻松显示路径上的所有权限,您可以使用namei -om /path/to/check

【讨论】:

  • 这里也一样。在我安装 CentOS 6 时,/home/user 目录默认设置为 700。
  • 这家伙也讲了:(chmod -4 +x /mypath为我工作)nginxlibrary.com/403-forbidden-error
  • 有人能解释一下为什么这种行为与不需要每个父目录都具有“x”权限的 apache 不同吗?!?
  • 没有什么不同。 apache 不需要父目录的 x 权限的唯一原因是它是否以 root 身份运行。
  • 我最终将 www-data 用户添加到我的个人用户组,并对我的根用户文件夹执行 chmod 710。像魅力一样工作。 (在基于 debian 的发行版上)
【解决方案2】:

我尝试了不同的情况,只有当所有者设置为 nginx (chown -R nginx:nginx "/var/www/myfolder") - 它开始按预期工作。

【讨论】:

  • 也为我工作。我怀疑会发生这种情况,因为即使 nginx 以 root 身份启动,它也会在 nginx.conf 文件中指定的用户下生成进程,即“user nginx;”默认。将用户更改为拥有文档根目录的用户也应该按照 Anderson 的建议进行。
  • 先生。安德森?不!安德龙 ;)
  • 抱歉,Andron 先生 ;) 我似乎无法再编辑之前的评论了...
  • 当然,没问题。现在我就像安德森 :) 并且需要写一些童话故事......
  • 这不是安全问题吗?
【解决方案3】:

如果验证父文件夹权限后仍看到permission denied,则可能是SELinux限制访问。

检查 SELinux 是否正在运行:

# getenforce

在下次重启前禁用 SELinux:

# setenforce Permissive

重启 Nginx 看看问题是否依然存在。允许 nginx 为您的 www 目录提供服务(确保在测试之前重新打开 SELinux。即setenforce Enforcing

# chcon -Rt httpd_sys_content_t /path/to/www

更多详情请查看我的answer here

【讨论】:

  • 我无法弄清楚为什么每当我启动 nginx 时,在我检查权限并确保它以 root 身份启动后,它会显示 open() "/usr/share/nginx/logs/xxxxxx.com-error_log" failed (13: Permission denied)。我遇到了这个,发现 SELinux 已启用。我禁用了它,现在它可以正常工作了。谢谢!
  • 这也是 CentOS 7 的默认行为。
  • 我和其他评论的人一样。我准备把我的电脑扔出窗外。 Nginx 配置正确,权限设置正确,我什至将所有内容都设置为 777,但仍然出现权限被拒绝错误。
  • 更好的 SELinux 命令是:semanage fcontext -a -t httpd_sys_rw_content_t "/path/to/www(/.)?"* 和 restorecon - v /path/to/www 这将自动赋予此路径中的所有文件正确的 SELinux 权限。此外,当添加新文件时。如果您只需要阅读权限,请使用 httpd_sys_content_t。
  • 在 Centos 7(启用 SELinux)上,对我来说最简单的修复是 setsebool httpd_read_user_content on(对于从主目录托管的静态文件,修改为世界可读) - 虽然我猜是 @KapiteinWitbaard 的方法以上更安全。
【解决方案4】:

我错误地运行了setfacl 命令,在这个问题上发现了一个细微的变体。我跑了:

sudo setfacl -m user:nginx:r /home/foo/bar

我放弃了这条路线,转而将 nginx 添加到 foo 组中,但是自定义 ACL 阻止了 nginx 访问文件的尝试。我通过运行清除了它:

sudo setfacl -b /home/foo/bar

然后 nginx 就可以访问这些文件了。

【讨论】:

    【解决方案5】:

    我通过添加用户设置解决了这个问题。

    在 nginx.conf 中

    worker_processes 4;
    user username;
    

    用 linux 用户名更改“用户名”。

    【讨论】:

    • 我相信这个答案比公认的答案更安全。您不必搞乱主文件夹的权限(其中可能包含敏感信息),如果您使用 nginx 进行开发,则无需将奇怪的文件权限上传到 SCM。
    • 在主目录上添加的权限是执行而不是读取,因此(理论上)不会泄露敏感信息(在这种情况下,可能是向上递归并知道www-data 可访问的另一个目录中的敏感文件的位置)。您还会注意到,在最初的问题中,我的 nginx 作为“www-data”运行 - 这里的配置值已经根据需要设置。
    • 还必须添加用户组:用户用户组。
    • 也为我工作(就像将目录更改为 nginx:nginx 一样)。不过,我更喜欢这个解决方案,所以我可以让我的文档根目录由 nginx 以外的其他用户拥有。感谢安德森指出这一点。
    • 我相信这是最好的解决方案
    【解决方案6】:

    我遇到了这个错误,我终于用下面的命令解决了。

    restorecon -r /var/www/html
    

    当您将某物从一个地方移动到另一个地方时会导致该问题。当你移动它时,它会保留原始的 selinux 上下文,所以如果你在 /home 或 /tmp 中解压某些东西,它会得到一个与其位置匹配的 selinux 上下文。现在您将其 mv 到 /var/www/html 并且它使用上下文说它属于 /tmp 或 /home 并且策略不允许 httpd 访问这些文件。

    如果你 cp 文件而不是 mv 文件,selinux 上下文会根据你要复制到的位置而不是它的来源来分配。运行 restorecon 会将上下文恢复为默认值并对其进行修复。

    【讨论】:

    • 感谢@jsina,这对我帮助很大
    • 妈的,+1,我也是。
    • 这也是我的问题。
    【解决方案7】:

    老问题,但我有同样的问题。我尝试了上面的每个答案,没有任何效果。为我解决的问题是删除域并再次添加它。我正在使用 Plesk,并且在域已经存在之后安装了 Nginx。

    首先对 /var/www/backups 进行了本地备份。所以我可以很容易地把文件复制回来。

    奇怪的问题....

    【讨论】:

      【解决方案8】:

      我们在使用 Plesk Onyx 17 时遇到了同样的问题。解决方案是将 nginx 用户添加到 psacln 组中,而不是搞砸权限等,其中所有其他域所有者(用户)都是:

      usermod -aG psacln nginx
      

      现在 nginx 有权访问 .htaccess 或任何其他必要的文件以正确显示内容。

      另一方面,还要确保 Apache 在 psaserv 组中,以提供静态内容:

      usermod -aG psaserv apache
      

      之后不要忘记在 Plesk 中重新启动 Apache 和 Nginx! (并使用 Ctrl-F5 重新加载页面)

      【讨论】:

      • 这是正确答案,在大多数设置中很可能是usermod -aG username www-data
      【解决方案9】:

      如果您使用的是 PHP,请确保服务器块中的 indexNGINX 指令包含 index.php:

      index index.php index.html;

      欲了解更多信息,请查看官方文档中的index directive

      【讨论】:

        【解决方案10】:

        我遇到了同样的问题,但上述解决方案没有帮助。

        所以,经过一番努力,我发现 sestatus 被设置为强制阻止所有端口,并通过将其设置为允许所有问题得到解决。

        sudo setenforce 0
        

        希望这对像我这样的人有所帮助。

        【讨论】:

        • 虽然这可能已经解决了您的问题 - 恭喜! - 有点难过 :-( 见 stopdisablingselinux.com - 你能找到不同的解决方法吗?
        【解决方案11】:

        如果您使用的是 SELinux,只需输入:

        sudo chcon -v -R --type=httpd_sys_content_t /path/to/www/
        

        这将解决权限问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-24
          • 1970-01-01
          • 2019-06-07
          • 2019-04-17
          • 2018-12-17
          • 2017-12-05
          相关资源
          最近更新 更多