Meetarp
Meetarp

Reputation: 2461

SSL proxy pass with NGINX leading to bad gateway through Docker

Background

My setup is based on the following tutorial:

Dockerizing Django with Postgres, Gunicorn, and NGINX

TL;DR: (italics: not covered by tutorial; personal adventure)

Details

I've generated a self-signed certificate to test out ssl redirects with NGINX locally before trying to get it to work on a VPS in production. I'm quite new to working with NGINX and so I'm not entirely sure what's going wrong or how to diagnose problems.

Here's what I want to happen with the NGINX file I've provided below... (spoilers: it doesn't):

  1. Go to http://localhost
  2. Get redirected to https://localhost
  3. Warning from browser about a self-signed cert; accept warning and proceed
  4. Site rendered fine, SSL redirect working!

But this isn't the case. I get a 502 Bad Gateway, and NGINX outputs the following logs:

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"

Can anyone tell me what's going on or how to fix it? I feel like there's probably a whole bunch wrong with my conf file even outside of the SSL redirect, but I don't really know how to identify any problems. The conf file is below...

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;

}

Upvotes: 6

Views: 5567

Answers (1)

chue x
chue x

Reputation: 18803

Based on your error

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"

I would say it's likely that you have some kind of protocol mismatch between Nginx and Django. It's likely that Django is expecting non-secure communication (http). Your nginx configuration indicates that you have configured it to communicate with Django via https:

proxy_pass https://mysite;

My suggestion is to make sure that the communication between Nginx and Django is using the same protocol, either http or https.

Whether you want to use http or https is up to you. There are two differing schools of thought on whether http is secure here.

The first school of thought is that http IS secure in this scenario, since the communication is within the same machine.

The second school of thought is to secure all communications, and to use https. However if you agree with this line of thinking, you will have to make sure that the communication between your web server and database is also using a secure protocol. After all, you are only as secure as your weakest link.

I tend to lean towards the first school of thought. Though this is not necessarily what is appropriate for you.

Upvotes: 2

Related Questions