![](/img/trans.png)
[英]Nginx+uWsgi+Django 'Permission denied while connecting to upstream' (socket)
[英]Permission denied - nginx and uwsgi socket
好吧,我目前正在尝试使用 nginx 和 uwsgi 为我的 django 应用程序提供服务。 我目前正在使用安装了 uwsgi 的虚拟环境。 但是,我目前在尝试访问该页面时收到 502 bad gateway 错误。
我遇到的错误。
2014/02/27 14:20:48 [crit] 29947#0: *20 connect() to unix:///tmp/uwsgi.sock failed (13: Permission denied) while connecting to upstream, client: 144.136.65.176, server: domainname.com.au, request: "GET /favicon.ico HTTP/1.1", upstream: "uwsgi://unix:///tmp/uwsgi.sock:", host: "www.domainname.com.au"
这是我的 nginx.conf
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
server unix:///tmp/uwsgi.sock; # for a file socket
#server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 80;
# the domain name it will serve for
server_name .domainname.com.au; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Django media
location /media {
alias /home/deepc/media; # your Django project's media files - amend as required
}
location /static {
alias /home/deepc/static; # your Django project's static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /home/deepc/.virtualenvs/dcwebproj/dcweb/uwsgi_params; # the uwsgi_params file you installed
}
}
这是我的 uwsgi.ini 文件
[uwsgi]
socket=/tmp/uwsgi.sock
chmod-socket=644
uid = www-data
gid = www-data
chdir=/home/deepc/.virtualenvs/dcwebproj/dcweb
module=dcweb.wsgi:application
pidfile=/home/deepc/.virtualenvs/dcwebproj/dcweb.pid
vacuum=true
从我在谷歌上读到的内容来看,www-data 组和 /tmp/ 目录存在权限问题。 但是,我对此很陌生,并尝试更改文件夹的权限级别无济于事。 有人能指出我正确的方向吗? 这是权限问题吗。
也可以将 sock 文件放在 tmp 目录中吗?
谢谢
我认为您只需要将套接字文件更改为 666(664 可以使用 www-data),或者将其删除并再次运行 uwsgi 服务器。
在我的 uwsgi.ini 中:
chmod-socket = 664
uid = www-data
gid = www-data
哇,这个问题几乎花了我一整天!
我使用uwsgi 2.0.14, nginx 1.10.1, django 1.10
综上所述,最重要的是确保以下两个用户都拥有socket
文件的rwx
权限:
nginx
的用户;uWSGI
的用户;所以,你可以一一检查。
首先,您可以通过刷新 url 来检查 Web 服务器nginx
是否具有权限,例如http://192.168.201.210:8024/morning/ ,而无需运行 uwsgi。 如果你看到/var/log/nginx/error.log
No such file or directory ,像这样:
2016/10/14 16:53:49 [crit] 17099#0: *19 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (2: No such file or directory) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
只需创建一个名为helloworld.sock
的文件,然后刷新 url 并再次检查日志文件,如果您在日志文件中看到Permission denied ,如下所示:
2016/10/14 17:00:45 [crit] 17099#0: *22 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
这意味着 Web 服务器nginx
没有读取、写入和执行的所有权限。 所以你可以授予这个文件的权限:
sudo chmod 0777 helloworld.sock
然后,刷新 url 并再次检查日志文件,如果您在日志文件中看到连接被拒绝,如下所示:
2016/10/14 17:09:28 [error] 17099#0: *25 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (111: Connection refused) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
这是一个好兆头,这意味着您的 Web 服务器nginx
从现在开始有权使用helloworld.sock
文件。
接下来运行uwsgi
和检查的用户uwsgi
有权使用helloworld.sock
。 首先,删除我们之前创建的文件helloworld.sock
。
运行 uwsgi: uwsgi --socket /usr/share/nginx/html/test/helloworld.sock --wsgi-file wsgi.py
如果您看到bind(): Permission denied [core/socket.c line 230] ,则表示uwsgi
没有绑定helloworld.sock
权限。 这是目录test
的问题, helloworld.sock
的父目录。
sudo chmod 0777 test/
现在,您可以成功运行uwsgi
。
但也许你还看到502 Bad Gateway ,太可怕了,我已经看了一整天了。 如果再次检查error.log
文件,您将再次看到:
2016/10/14 17:33:00 [crit] 17099#0: *28 connect() to unix:///usr/share/nginx/html/test/helloworld.sock failed (13: Permission denied) while connecting to upstream, client: 192.168.201.140, server: belter-tuesday.com, request: "GET /morning/ HTTP/1.1", upstream: "uwsgi://unix:///usr/share/nginx/html/test/helloworld.sock:", host: "192.168.201.210:8024"
怎么了???
查看helloworld.sock
文件的详细信息,可以看到:
srwxr-xr-x. 1 belter mslab 0 Oct 14 17:32 helloworld.sock
uWSGI
自动给这个文件755
权限。
您可以通过添加--chmod-socket
来更改它:
uwsgi --socket /usr/share/nginx/html/test/helloworld.sock --wsgi-file wsgi.py --chmod-socket=777
好的! 最后,您可以看到:
带走消息:
uwsgi_params
文件的位置并不重要;nginx
用户和uwsgi
用户不相同,甚至不在同一个组中,所以我需要给helloworld.sock
及其父目录test/
777
权限;helloworld.sock
文件放在您的主目录中,您将始终获得Permission denied 。socket
文件路径,一个在nginx conf文件中,对我来说是helloworld_nginx.conf
; 运行 uwsgi 时之一。 这是我的helloworld_nginx.conf
文件:
# helloworld_nginx.conf
upstream django {
server unix:///usr/share/nginx/html/test/helloworld.sock; # for a file socket
# server 127.0.0.1:5902; # for a web port socket (we'll use this first)
}
# configuration of the server
server {
# the port your site will be served on
listen 8024;
# the domain name it will serve for
server_name .belter-tuesday.com; # substitute your machine's IP address or FQDN
charset utf-8;
# max upload size
client_max_body_size 75M; # adjust to taste
# Finally, send all non-media requests to the Django server.
location /morning {
include uwsgi_params;
uwsgi_pass django;
}
}
在 CentOS 上,我尝试了所有这些东西,但仍然没有奏效。 最后,我找到了这篇文章:
https://www.nginx.com/blog/nginx-se-linux-changes-upgrading-rhel-6-6/
对于开发机器,我们只需运行:
semanage permissive -a httpd_t
但是对于真正的生产服务器,我还没有弄清楚。 您可能需要尝试上述文章中描述的其他内容。
这需要我花很多时间才能找到权限问题。 当然,问题在于权限。 默认用户是 nginx。 我做了什么:在/etc/nginx/nginx.conf
更改用户:
user www-data;
接下来将您的用户加入 www-data 组:
usermod -a -G www-data yourusername
下一组 uwsgi:
[uwsgi]
uid = yourusername
gid = www-data
chmod-socket = 660
然后重启nginx:
sudo systemctl restart nginx
最后重启uwsgi。
我解决了这个问题一段时间,发现uwsgi.ini
文件中的uid
和gid
标志没有应用于.sock
文件
您可以通过运行.sock
来测试这一点,然后使用 linux 命令ls -l
检查您的.sock
文件的权限。
我的解决方案是使用 sudo 运行uwsgi
:
sudo uwsgi --ini mysite_uwsgi.ini
使用包含标志的.ini
文件:
chmod-socket = 664
uid = www-data
gid = www-data
然后.sock
文件的权限就正确了, 502 Bad Gateway
错误终于消失了!
希望这可以帮助 :)
这个问题让我抓狂。 我的环境是centos7+nginx+uwsgi,使用unix socket连接。 接受的答案很棒,只需在其中添加一些要点。
ROOT 用户,快速测试
先关掉selinux,然后把chmod-socket改成666,最后用root启动uwsgi。
像这样
setenforce 0 #turn off selinux
chmod-socket = 666
uwsgi --ini uwsgi.ini
其他用户
如果使用自己创建的其他用户启动uwsgi,请确保home文件夹下的用户文件夹的权限为755,并且所有者和组对应。
例如
chmod-socket = 666
usermod -a -G nginx webuser #add webuser to nginx's group
cd /home/
chmod -R 755 webuser
chown -R webuser:webuser webuser
uwsgi --ini uwsgi.ini --gid webuser --uid webuser
另一篇给 CentOS 用户的好文章:
https://axilleas.me/en/blog/2013/selinux-policy-for-nginx-and-gitlab-unix-socket-in-fedora-19/
尽管答案对 CentOS 很有用,但问题出在 SELinux 之下。
我遵循了整篇文章,但是我相信以下命令解决了什么问题:
yum install -y policycoreutils-{python,devel}
grep nginx /var/log/audit/audit.log | audit2allow -M nginx
semodule -i nginx.pp
usermod -a -G user nginx
chmod g+rx /home/user/
请将 user 替换为您的实际用户以授予权限。 同样适用于 chmod 命令下的目录。
uwsgi.ini
[uwsgi]
uid = yourusername
gid = www-data
chmod-socket = 664
为什么? 因为有时应用程序需要读取或写入超出 Web 服务器可访问的文件系统。 我不想为了适应每一种情况而改变一大堆所有权和权限。 我宁愿让我的应用程序像我一样运行并做它需要做的事情。 将组设置为 www-data 并将套接字修改为 664 允许该组写入它,从而提供 Web 服务器和应用程序之间唯一必要的通信窗口。
在开发模式下,如果使用root,只需将wsgi.ini 或emperor.ini 设置如下:
uid=root
gid=root
你需要取消注释
#server 127.0.0.1:8001;
来自上游块,类似地在 uwsgi.ini 中进行更改
socket = 127.0.0.1:8001
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.