簡體   English   中英

權限被拒絕 - nginx 和 uwsgi 套接字

[英]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權限:

  1. nginx的用戶;
  2. 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

好的! 最后,您可以看到:

成功查看網頁信息


帶走消息

  1. uwsgi_params文件的位置並不重要;
  2. 由於我的nginx用戶和uwsgi用戶不相同,甚至不在同一個組中,所以我需要給helloworld.sock及其父目錄test/ 777權限;
  3. 如果您將helloworld.sock文件放在您的主目錄中,您將始終獲得Permission denied
  4. 有兩個地方需要設置socket文件路徑,一個在nginx conf文件中,對我來說是helloworld_nginx.conf 運行 uwsgi 時之一。
  5. 檢查 SELinux

這是我的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文件中的uidgid標志沒有應用於.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM