Easyrider
Easyrider

Reputation: 3269

Nginx, gunicorn, python-flask application. Https is lost on redirect

I am having some troubles with my application. During redirects my flask application lose the https and redirect to http instead.

I've been trying to find the solution but nothing works.

My nginx configuration for the application (location /) is as follows:

proxy_pass http://localhost:5400;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-port 443;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

(Some examples on the internet says to use "X-Forwarded-Proto". I've tried that without success. And also to use "ssl" or "https" as value on that parameters.

A simple print in the flask application (before_request:) shows that it is still http-requests made event though i use https between client and nginx.

print(request.environ["wsgi.url_scheme"])

What am I doing wrong?

Upvotes: 3

Views: 2100

Answers (2)

Paolo Casciello
Paolo Casciello

Reputation: 8202

Warning. Making unwanted HTTP redirects is a security flaw as in those requests the connection is not encrypted!!

The only solution here is to correctly configure NGINX and GUNICORN to allow Flask to use the correct headers.

NGINX config should contain at least following directives:

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_set_header        X-Forwarded-Host $http_host;
proxy_pass              http://appserver:5000;

And, this is the real solution here, GUnicorn must be started with the --forwarded-allow-ips parameter.

Following is how I start it in production, fixing also the real IP address in logs (beware to complain to the GDPR :P ):

PYTHONUNBUFFERED=FALSE gunicorn              \
                        --access-logfile '-' \
                        --access-logformat '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" "%({X-Real-IP}i)s"' \
                        -b :5000             \
                        --forwarded-allow-ips="*" \
                        app:app

You should NEVER send a request in HTTP. The first and only redirect should be the /.

Upvotes: 2

Richard Smith
Richard Smith

Reputation: 49672

If your application ignores the X-Forwarded headers for setting the scheme in http 3xx responses, you could try setting one or more proxy_redirect rules:

proxy_redirect http:// $scheme://;

See this document for details.

Upvotes: 3

Related Questions