【发布时间】:2019-10-18 13:40:51
【问题描述】:
背景
我的设置基于以下教程:
Dockerizing Django with Postgres, Gunicorn, and NGINX
TL;DR:(斜体:教程未涵盖;个人冒险)- 3 Docker 服务用于:nginx -> django -> postgres(箭头表示依赖)
- Nginx 代理将请求传递到 Django 服务中暴露的端口。
- HTTP(非 SSL)请求工作
- 通过重定向 http -> https 需要 SSL 连接
详情
我已经生成了一个自签名证书来测试本地 NGINX 的 ssl 重定向,然后再尝试让它在生产中的 VPS 上工作。我对使用 NGINX 很陌生,所以我不完全确定出了什么问题或如何诊断问题。
这是我希望在下面提供的 NGINX 文件中发生的事情... (剧透:它不会):
- 转到http://localhost
- 被重定向到https://localhost
- 来自浏览器的关于自签名证书的警告;接受警告并继续
- 网站渲染良好,SSL 重定向工作正常!
但事实并非如此。我得到一个 502 Bad Gateway,NGINX 输出以下日志:
prod_1 | 192.168.144.1 - - [03/Jun/2019:00:01:44 +0000] "GET / HTTP/1.1" 502 158 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0" "-"
prod_1 | 2019/06/03 00:01:44 [error] 8#8: *1 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 192.168.144.1, server: , request: "GET / HTTP/1.1", upstream: "https://192.168.144.3:8000/", host: "localhost"
谁能告诉我发生了什么或如何解决它?我觉得即使在 SSL 重定向之外,我的 conf 文件也可能存在一大堆问题,但我真的不知道如何识别任何问题。 conf文件在下面...
upstream mysite {
server web:8000;
}
# redirect http traffic to https
server {
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
location / {
proxy_pass https://mysite;
proxy_ssl_server_name on;
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-Proto $scheme;
proxy_redirect off;
}
location /assets/ {
alias /usr/src/site/assets/;
}
location /media/ {
alias /usr/src/site/media/;
}
ssl_certificate /etc/ssl/certificates/site.crt;
ssl_certificate_key /etc/ssl/certificates/site.key;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
ssl_prefer_server_ciphers on;
}
【问题讨论】:
-
您的上游 (Django) 是否安全?我的猜测是 Django 是 http 的,但是你已经将 nginx 配置为通过 https 连接到它。
-
@chuex 我必须调查一下,我没有意识到我必须设置 Django 以确保安全。为此,我需要在 NGINX conf 文件方面做一些具体/额外的事情吗?除此之外,我将研究有关 SSL 连接的 Django 文档
-
你不一定要让 Django 安全。我只需将 nginx 配置为通过 http 而不是 https 连接到它。
-
@chuex 你是说
proxy_pass $http://mysite;吗?这不会撤消 SSL 连接吗? -
我的建议是匹配协议。如果 Django 是 http,那么你会希望 nginx 使用 http 与它对话。如果 Django 是 https,那么同样你需要 nginx 通过 https 与之对话。是的,http 在 nginx 和 Django 之间不太安全。关于 localhost 上的通信有两种思想流派——一种是使用 https 来保证安全,另一种是 localhost 已经是安全的。例如,您的 Django 实例是否使用 SSL 与本地数据库通信?如果不是,那么 Django 是否以明文方式与 nginx 对话是否重要?无论如何,这是另一个问题。