ubuntu 通过nginx访问uwsgi套接字时,域无法打开

nukf8bse  于 12个月前  发布在  Nginx
关注(0)|答案(1)|浏览(273)
  • 我的服务器部署在Amazon EC2云上。
  • 操作系统Ubuntu 22.04

我有一个简单的uwsgi应用程序与vendriment.我保存在主文件夹中的项目,sudo用户ubuntu.对于测试我使用简单的代码:

def application(environ, start_response):
   start_response('200 OK', [('Content-Type', 'text/html')])
   return [b"<h1 style='color:blue'>Hello There!</h1>"]

字符串
首先,我在环境中启动应用程序,使用此命令进行测试:
第一个月
在示例安全组(在AWS上)中,我临时打开了端口8080,以检查一切是否正常。
接下来我创建了这个配置:

[uwsgi]
socket = main.sock
chmod-socket = 664
protocol = http
module = main
chdir = /home/ubuntu/operatorAPI
master = true
processes = 5
vacuum = true
die-on-term = true
logto = /home/ubuntu/operatorAPI/log/uwsgi_operator_api.log


然后我创建了服务/etc/systemd/system/operator_api.service

[Unit]
Description=uWSGI instance to serve operator api
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/operatorAPI
Environment="PATH=/home/ubuntu/operatorAPI/venv/bin"
ExecStart=/home/ubuntu/operatorAPI/venv/bin/uwsgi --ini uwsgi.ini

[Install]
WantedBy=multi-user.target


并为nginx创建了一个配置。

server {
    listen 80;
    server_name uniapi.example.com;

   access_log /home/ubuntu/operatorAPI/log/nginx_access.log; 
   error_log /home/ubuntu/operatorAPI/log/nginx_error.log;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/home/ubuntu/operatorAPI/main.sock;
    }
}


然后我重新启动nginx,启动服务并检查登录到域。它没有工作。在nginx日志中我读到:

2023/11/22 12:56:03 [crit] 48800#48800: *126 connect() to unix:/home/ubuntu/operatorAPI/main.sock failed (13: Permission denied) while connecting to upstream, client: *****, server: uniapi.example.com, request: "GET / HTTP/1.1", upstream: "uwsgi://unix:/home/ubuntu/operatorAPI/main.sock:", host: "uniapi.example.com"


由于nginx日志显示了这一点,这意味着我的域正确指向我的服务器(我特意用这个替换了域地址,因为我不想在stackoverflow上显示它)
我检查了套接字确实是在指定的地址创建的。写权限664。
然后,为了测试服务是否真的工作,我决定更改uwsgi设置,而不是将套接字设置为地址0.0.0.0:44444。

[uwsgi]
socket = 0.0.0.0:44444
protocol = http
module = main
chdir = /home/ubuntu/operatorAPI
master = true
processes = 5
vacuum = true
die-on-term = true
logto = /home/ubuntu/operatorAPI/log/uwsgi_operator_api.log


在那之后,我重新启动了服务,并通过IP和端口登录。一切正常。
在nginx中,我替换了这个uwsgi_pass 0.0.0.0:44444;
但是我仍然不能通过域访问这个。只有裸IP和端口。
我也改变了用户在服务根,但它没有帮助。

**P.S.**最有趣的是,我已经在另一个主机上做了类似的事情(不是亚马逊),而且都在那里工作了。也许亚马逊需要做一些额外的事情?

v1l68za4

v1l68za41#

在POSIX兼容的文件系统中,要打开一个文件,进程需要从根目录(/)开始,对文件路径中的所有目录都具有执行权限(x)。
在EC2使用的Ubuntu发行版中,/home/ubuntu/是用户ubuntu的主目录。默认情况下,与所有主目录一样,它由ubuntu:ubuntu拥有,并且不向其他人给予任何权限。
UWSGI进程的setuid是ubuntu,因此它可以遍历目录并打开套接字。
Nginx进程被设置为www-data:www-data,所以它没有/home/ubuntu的执行权限,因此,它下面没有目录或文件。
将Unix套接字放置到主目录是一个坏主意。根据Filesystem Hierarchy Standard,套接字应该到/run或其子目录:
维护临时UNIX域套接字的系统程序必须将它们放置在此目录或上面列出的适当的目录中。
/run是符合标准的发行版上的一个临时的、仅可写入根目录的目录:
此目录包含自引导以来描述系统的系统信息数据。在引导过程开始时,必须清除此目录下的文件(根据需要删除或截断)。
/run不应该对非特权用户可写;如果任何用户都可以在此目录中写入,这将是一个主要的安全问题。用户特定的子目录应该只由每个目录的所有者可写。
请注意,尽管标准中说的是“文件”,但实际上许多发行版将其挂载在tmpfs(内存文件系统)上,这也使得目录(不仅仅是文件)在重启时消失。
要将其用于套接字,您需要在 Boot 时重新创建它。
一种方法是在/etc/tmpfiles.d中创建一个条目,该条目将在每次系统引导时创建一个可由www-data写入的子文件夹,并将套接字放在该子文件夹下。
或者,如果您希望将所有内容都保留在systemd中,请将RuntimeDirectory条目添加到服务定义中。

相关问题