简体   繁体   中英

Nginx Reverse proxy not working with Gunicorn over LetsEncrypt SSL connection

I've EC2 Ubuntu 18.04 Server with Python Flask framework running on Gunicorn application server with Nginx reverse proxy listening on port 80 & 443. I've added LetsEncrypt for the domain using certbot.

The website works fine without ssl. With LetsEncrypt ssl configuration on Nginx the server fails to load the page. My previous supervisor and Nginx configuration without ssl support is as follows and Nginx works with gunicorn with no issues.

server {
        listen 80;
        server_name example.com www.example.com;

        location /static {
                alias /home/ubuntu/myapp-backend/myapp/static;
        }

        location / {
                proxy_pass http://localhost:8000;
                include /etc/nginx/proxy_params;
                proxy_redirect off;
        }
}
[program:myapp]
directory=/home/ubuntu/myapp-backend
command=/home/ubuntu/myapp-backend/venv/bin/gunicorn -w 5 run:app
user=ubuntu
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stderr_logfile=/var/log/myapp/myapp.err.log
stdout_logfile=/var/log/myapp/myapp.out.log

When I change the Nginx configuration to include LetsEncrypt support while listening on port 80 & 443, the website doesn't show up.. It shows indefinite 301 redirects requests.

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location /static {
            alias /home/ubuntu/myapp-backend/myapp/static;
    }

    location / {
            proxy_pass http://localhost:8000;
            include /etc/nginx/proxy_params;
            proxy_redirect off;
    }
}

When I load the site example.com , it redirects to https:\\www.example.com . However the website homepage doesn't load or show any response from server/Nginx. When I login to the server and run curl -v localhost:8000 , the the gunicorn works fine.

curl -v localhost:8000
* Rebuilt URL to: localhost:8000/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.58.0
> Accept: */*
>
< HTTP/1.1 500 INTERNAL SERVER ERROR
< Server: gunicorn/19.9.0
< Date: Sat, 28 Sep 2019 14:14:47 GMT
< Connection: close
< Content-Type: text/html; charset=utf-8
< Content-Length: 27911
<
<!doctype html>
...

There was earlier Stackoverflow question on gunicorn over ssl with ssl parameters which can be added to supervisor config. I believe the error must be with on Nginx configuration on port 443 or Gunicorn supervisor config info. If you could have a look, I would appreciate it.

You have too many server blocks

The second block in your configration with SSL, catches connections to 443 and redirects them to the https:// URL. Thus causing the infinite loop:

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    return 301 https://www.example.com$request_uri;
}

This 301 should only be returned when the user hits the server on port 80 . That's what the first server block in this config file actually does.

Remove this whole block and it should probably work. You already have the third server block configured to (correctly) catch traffic to 443 and proxy it to gunicorn.

There was earlier Stackoverflow question on gunicorn over ssl with ssl parameters which can be added to supervisor config. I believe the error must be with on Nginx configuration.

You are terminating SSL at nginx, then proxying to gunicorn in plain HTTP (which is the correct way to operate with nginx involved). The question you linked there is about adding native SSL support to gunicorn, so that gunicorn terminates SSL. This would only be required if your internet based users connect directly to the gunicorn server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM