我在 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_name
,proxy_pass
以及为什么后端服务器应该明确绑定到端口 127.0.0.1。