Nginx 配置子域名表现出奇怪的行为

Nginx 配置子域名表现出奇怪的行为

我在 digital ocean 上运行了两个相同的 droplet。两者都运行带有 nginx、gunicorn 和 Django 的 Ubuntu 14.04。

我正在尝试将我的子域名停放在其中一个 droplet 的 IP 上。在另一个 droplet 上,我已成功停放子域名,并且一切正常。

目前,问题 droplet 似乎只能通过 droplet 的 IP 地址正确连接。通过访问 IP 地址,可以完美地看到 gunicorn 实例,并且:9000不需要 gunicorn 端口的代理即可访问它。

通过访问我在域名注册商中添加了指向此 droplet 的 IP 的 A 记录的子域名,我看到了 nginx 欢迎页面,提示 nginx 需要更多配置。

通过访问子域并附加 gunicorn 端口,:9000我受到了 Django 应用程序的欢迎,但它并不像访问 droplet 的 IP 地址那样提供静态文件。此外,如果我访问 IP 地址并附加端口,:9000它会产生同样的效果。

我在两个 droplet 上的 nginx 配置是相同的,唯一的区别是其中的 IP 地址server_name

server {
    server_name *.*.*.*;
    access_log off;

    location /static {
        alias /opt/venv/static;
    }

    location /media {
        alias /opt/venv/media;
    }

    location / {
            proxy_pass http://$server_name:9000;
            proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $server_name;
    }
}

我也尝试将 server_name 设置为子域,但无济于事。

我是不是漏掉了什么?为什么这个功能在一个 droplet 上有效,而在另一个 droplet 上无效?

编辑:添加了 gunicorn 的配置

command = '/opt/venv/bin/gunicorn'
pythonpath = '/opt/venv/fjarrtoolbox'
bind = '127.0.0.1:9000'
workers = 3

答案1

这一行:

proxy_pass http://$server_name:9000;

应该:

proxy_pass http://127.0.0.1:9000;

该更改将通过本地环回接口有效且安全地将流量路由到后端。

此外,Gunicorn 应配置为绑定到端口 127.0.0.1,因为它仅供通过 Nginx 访问。如果没有必要,将其公开会引发更多问题。

以下是您当前配置可能出现的问题。有人可能会使用第三方主机名向您的服务器发送请求,如下所示:

curl -H 'Host: example.com' http://1.2.3.4/Hello

server_name将接受与任何主机名匹配的请求,因此请求将被处理,然后请求将被代理到“example.com”的端口“9000”。假设这是其他人的 Gunicorn 服务器,该服务器也开放了端口 9000。现在可能会有攻击流量发送到该 Gunicorn 服务器,这些流量来自您的 IP 地址,因为您正在运行一种开放代理。

这就是为什么最好对主机使用明确的值server_nameproxy_pass以及为什么后端服务器应该明确绑定到端口 127.0.0.1。

相关内容