NGINX的SSL代理传递导致Docker网关故障

时间:2019-06-03 00:21:13

标签: docker ssl nginx

背景

我的设置基于以下教程:

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文件中发生的事情... (破坏者:没有)

  1. 转到http://localhost
  2. 重定向到https://localhost
  3. 从浏览器警告有关自签名证书;接受警告并继续
  4. 网站呈现良好,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;

}

1 个答案:

答案 0 :(得分:1)

根据您的错误

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"

我要说的是,您可能在Nginx和Django之间存在某种协议不匹配的情况。 Django可能期望使用非安全通信(http)。您的nginx配置表明您已将其配置为通过https:

与Django通信
proxy_pass https://mysite;

我的建议是确保Nginx和Django之间的通信使用相同的协议,即http或https。

您要使用http还是https决定。关于http是否在这里安全,存在两种不同的思想。

首先想到的是,在这种情况下http是安全的,因为通信是在同一台机器内进行的。

第二个思路是确保所有通信的安全,并使用https。但是,如果您同意这种思路,则必须确保Web服务器与数据库之间的通信也使用安全协议。毕竟,您的安全性仅取决于最薄弱的链接。

我倾向于倾向于第一个思想流派。尽管不一定适合您。