ChatGPT解决这个技术问题 Extra ChatGPT

禁止所有文件使用 Nginx 403

我在 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 由具有 2777 文件权限的 www-data:www-data 所有,但该站点无法提供任何内容 -

 [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,因此它们似乎没有什么帮助。

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


k
kolbyjack

一个经常被忽视的权限要求是用户需要在文件的每个父目录中拥有 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 的发行版上)
C
Community

如果您在验证父文件夹的权限后仍然看到 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(对于从主目录托管的静态文件,chmod'ed 为世界可读) - 虽然我猜@KapiteinWitbaard 的上述方法更安全。
s
sshow

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

在 nginx.conf

worker_processes 4;
user username;

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


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

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

restorecon -r /var/www/html

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

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


谢谢@jsina,这对我帮助很大
该死的,+1,我也是。
这也是我的问题。
A
Andron

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


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

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

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

这将解决权限问题。


添加有关此命令的作用的解释会很有帮助。
D
David

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

不过,首先对 /var/www/backups 进行了本地备份。所以我可以轻松地复制回文件。

奇怪的问题....


S
Slavomir Miskovec

我们在使用 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
H
Harshal Y.

我面临同样的问题,但上述解决方案没有帮助。

因此,经过大量的努力,我发现 sestatus 被设置为强制阻止所有端口,并通过将其设置为允许所有问题都得到了解决。

sudo setenforce 0

希望这可以帮助像我这样的人。


虽然这可能解决了您的问题 - 恭喜! - 有点难过 :-( 见 stopdisablingselinux.com - 你能找到不同的解决方法吗?
d
danvk

通过错误地运行 setfacl 命令,我对这个问题进行了轻微的修改。我跑了:

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

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

sudo setfacl -b /home/foo/bar

然后 nginx 能够访问这些文件。


F
Francisco Zanatta

如果您使用的是 PHP,请确保 server 块中的 index NGINX 指令包含 index.php:

index index.php index.html;

有关详细信息,请查看官方文档中的 index directive


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅