Nginx错误:连接php5-fpm.sock失败(13:Permission denied)

326

我将nginx升级到1.4.7,把php也升级到5.5.12,然后就出现了502错误。在升级之前一切都正常。

nginx-error.log

2014/05/03 13:27:41 [crit] 4202#0: *1 connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied) while connecting to upstream, client: xx.xxx.xx.xx, server: localhost, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm.sock:", host: "xx.xx.xx.xx"

nginx.conf

user  www www;
worker_processes  1;

        location / {
            root   /usr/home/user/public_html;
            index  index.php index.html index.htm;
        }
        location ~ [^/]\.php(/|$) {
            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
            fastcgi_pass unix:/var/run/php5-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param  SCRIPT_FILENAME    /usr/home/user/public_html$fastcgi_script_name;
            include fastcgi_params;
        }

3
这份错误报告解释了为什么会出现这种情况:https://bugs.php.net/bug.php?id=67060 - Matt Cooper
1
所有从Ubuntu 14升级到16的用户需要将sock更改为unix:/var/run/php/php7.0-fpm.sock。 - Karussell
Ubuntu 20.04 检查 /usr/home/user/public_html 权限和用户是否与 /etc/nginx/nginx.conf、/etc/nginx/conf.d/www.conf 和其他配置文件(如 php)中的用户相同 - 在我的情况下,用户应该是相同的。 - Jakub Ujvvary
27个回答

664

在php升级后,我遇到了一个类似的错误。PHP修复了一个安全漏洞,其中o对套接字文件有rw权限。

  1. 打开/etc/php5/fpm/pool.d/www.conf/etc/php/7.0/fpm/pool.d/www.conf,具体取决于您的版本。
  2. 取消所有权限行的注释,例如:

    listen.owner = www-data
    listen.group = www-data
    listen.mode = 0660
    
  3. 重新启动 fpm - sudo service php5-fpm restart 或者 sudo service php7.0-fpm restart

注意: 如果您的 Web 服务器运行的用户不是 www-data,则需要相应地更新 www.conf文件。


14
考虑到这会让每个人都能够写入套接字,我不禁认为这是一个可怕的解决方案。 - Shadur
13
这种方法修复了 https://bugs.php.net/bug.php?id=67060 中解决的不安全的默认配置 - 考虑使用 artooro 建议的 listen.owner 修复。 - Chris Burgess
2
非常混乱。为什么不编辑您的答案以使其正确,(转到 /etc/...),然后再评论一下有一种不太安全的方法,只能在重新启动之前起作用(转到 /var/...)。 - SamGoody
1
@Tecnocat 为什么它不够安全?我认为它们是一样的。www-data 和 660。所以,我不明白哪里出了问题? - Xander
24
sudo usermod -aG www-data nginx 允许nginx访问文件。其中,sudo表示以管理员身份执行命令,usermod是修改用户属性的命令,-aG表示将用户添加到指定的用户组,www-data是一个用户组的名称,nginx是要被添加到该用户组的用户名。 - anthumchris
显示剩余12条评论

114

目前提到的所有修复方法基本上都会再次启用安全漏洞。

我最终所做的是将以下几行添加到我的PHP-FPM配置文件中。

listen.owner = www-data
listen.group = www-data

确保www-data实际上是nginx工作进程正在运行的用户。对于Debian,默认情况下是www-data。

以这种方式进行操作不会启用此更改本应修复的安全问题


19
查看 nginx 用户名的命令为 ps aux | grep nginx - SamGoody
2
在Ubuntu上的路径为/etc/php5/fpm/php.ini。 - Reality Extractor
2
@RealityExtractor 我不这么认为。那个文件只包含一般的PHP设置,与FPM进程管理器无关。 - Martijn Heemels
4
对我来说,我还得手动删除/var/run/php5-fpm.sock,因为它已经被www-data创建了。只是提醒一下... - Giel Berkers
1
这是安全方面的适当修复。 - jschorr
显示剩余6条评论

47

@Xander的解决方案是有效的,但重启后不会持久化。

我发现我必须在/etc/php5/fpm/pool.d/www.conf中将listen.mode更改为0660

来自www.conf的示例:

; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions. 
; Default Values: user and group are set as the running user
;                 mode is set to 0660
;listen.owner = www-data
;listen.group = www-data
;listen.mode = 0660

编辑:根据@Chris Burgess的建议,我已将其更改为更安全的方法。

我删除了对listen.mode、.group和.owner的注释:

listen.owner = www-data
listen.group = www-data
listen.mode = 0660

/var/run仅包含自上次启动以来运行系统的信息,例如当前登录用户和正在运行的守护程序。(http://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard#Directory_structure)。

附注:

我的php5-fpm -v报告:PHP 5.4.28-1+deb.sury.org~precise+1。该问题也发生在最近的更新之后。


5
这种方法恢复了 https://bugs.php.net/bug.php?id=67060 中解决的不安全的默认配置——考虑使用 artooro 建议的 listen.owner 修复。 - Chris Burgess
如果设置了listen.acl_groups,则忽略listen.ownerlisten.group。我将listen.acl_groups设置为空,然后502 /权限问题消失了。在取消注释上述的 listen. 行后发现问题仍然存在,运行 systemctl status php-fpm 后出现警告:“WARNING:[pool www] ACL set,listen.owner ='nobody' 被忽略”。 - idoimaging

41

如果您已经尝试了本篇文章中的所有方法,但仍然无法让PHP正常工作,以下内容可能对您有所帮助:

请确保您在/etc/php5/fpm/pool.d/www.conf文件中取消注释以下这些行:

listen.owner = www-data
listen.group = www-data
listen.mode = 0660

请确保 /etc/nginx/fastcgi_params 文件看起来像这样:

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  PATH_INFO          $fastcgi_script_name;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

我在/etc/nginx/fastcgi_params文件中缺少这两行内容,请确保它们已经存在!

fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
fastcgi_param  PATH_INFO          $fastcgi_script_name;

然后,重新启动php5-fpm和nginx。应该就可以了。


3
非常感谢!我已经失去了所有希望,这救了我一命。 - Diego Castro
2
你是我的英雄,你拯救了这一天! - jeppeb
2
没有言语可以形容我有多感激!在更新软件包后,一切都崩溃了,而这个解决了问题。 - Nikola Prokopić
1
我想给你不止一个 + - g9m29

31

实际上,"listen.mode" 应该设置为 "0660" 而不是 "0666",因为其他组和其他用户对此没有写权限或只读权限都不是一个好选择。

因此,请尝试查找您的 Web 服务器运行的用户/组。我使用的是 CentOS,它以用户“nginx”运行。因此,请在您的 php-fpm.conf 中添加以下内容:

listen.owner = nginx
listen.group = nginx
listen.mode = 0660

最后重新启动php-fpm


就我个人而言,在我的Ubuntu 12.04系统中,用户和组是www-data - Brad
1
在CentOS中,对我来说,将用户设置为“nobody”,将组设置为“nginx”是有效的。可能不是一个重大的改进,但我更喜欢尽可能地给予有限的权限。 - Kzqai

30

检查正在运行nginx的用户。在Ubuntu 12.04中,nginx是由非www-data组成员的nginx用户运行的。

usermod -a -G www-data nginx

并重新启动nginx和php5-fpm守护进程可解决该问题。


这个修复方案看起来是最干净、最安全的。在Ubuntu 14.04、Nginx 1.7.10、PHP 5.5.9-1ubuntu4.6 (fpm-fcgi)上运行正常。 - anthumchris

16

在您的php配置中扩展权限的替代方法是更改在nginx配置中指定的用户。

在上面的nginx.conf摘录的第一行中,分别将用户和组指定为www和www。

user  www www;

同时,你的php配置文件很可能指定了www-data的用户和组:

listen.owner = www-data
listen.group = www-data

你可以更改nginx.conf文件中的一行为以下任何一项:

user www-data www;
user www-data www-data; # or any group, really, since you have the user matching
user www www-data; # requires that your php listen.mode gives rw access to the group

非常感谢!更改nginx.conf是必要的。 - LCB

15

我遇到了类似的错误。

所有的建议都没有帮助。

唯一的解决方法是将www-data替换为nginx:

我遇到了相似的错误。

所有的建议都没有起到作用。

唯一有效的方案是将www-data替换为nginx:

$ sudo chown nginx:nginx /var/run/php/php7.2-fpm.sock

/var/www/php/fpm/pool.d/www.conf

user = nginx
group = nginx
...
listen.owner = nginx
listen.group = nginx
listen.mode = 0660

嘿@Alexander,你需要使用chown命令将所有者更改为nginx。这对我帮助很大。 - Pratik Ghela
当然,我使用了chown命令,评论中有一个错误,谢谢。 - Alexander Gavriliuk
这对于php 7.4也适用。谢谢。 - mahfuz
什么是nginx?它不是一个用户。 - rickster26ter1
这适用于Centos 7和php-fpm 7.4。 - vahid sabet

10
在我的情况下,问题是Nginx Web服务器以用户nginx身份运行,而进程池以用户www-data身份运行。
我通过更改/etc/nginx/nginx.conf文件中Nginx正在运行的用户来解决了这个问题(在您的系统上可能不同,我的是Ubuntu 16.04.1)。
将:user nginx; 更改为:user www-data; 然后重新启动Nginx:service nginx restart

7
考虑到您的个人FPM池,如果有的话,也必须加以考虑。
我今天一直无法弄清楚为什么这些答案都不起作用。对我来说,这是一个“设置并忘记”的情况,我已经忘记了listen.user和listen.group在每个池中都是重复的。
如果您像我一样使用池来管理不同的用户帐户,每个用户帐户拥有自己的FPM进程和套接字,则仅将默认的listen.owner和listen.group配置选项设置为'nginx'将根本不起作用。显然,让'nginx'拥有所有这些进程和套接字也是不可接受的。
对于每个池,请确保:
listen.group = nginx

否则,您可以不更改池的所有权和其他属性。

谢谢。如果Nginx适用于不同的用户帐户,应该像这样更改“listen.group = nginx”。 - MURATSPLAT

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