Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProxyFix should use X-Forwarded-Port #1023

Closed
davidism opened this issue Oct 23, 2016 · 10 comments
Closed

ProxyFix should use X-Forwarded-Port #1023

davidism opened this issue Oct 23, 2016 · 10 comments
Milestone

Comments

@davidism
Copy link
Member

@davidism davidism commented Oct 23, 2016

Reporting this against Werkzeug, ignore the fact that I keep saying Flask. ;-)

If the app is behind a proxy and the proxy is listening on a non-standard port (ex. 8080), Flask will not generate valid urls unless SERVER_PORT is changed or HTTP_HOST includes the port.

ProxyFix should set SERVER_PORT = X-Forwarded-Port, or Flask's deploy docs should add proxy_set_header Host $host:$server_port;. Not really sure which one is correct, I've seen both mentioned.

@romeojulietthotel
Copy link
Contributor

@romeojulietthotel romeojulietthotel commented Nov 5, 2016

FYI, X- means experimental and the feature is a standard now rfc7239

@untitaker
Copy link
Member

@untitaker untitaker commented Nov 5, 2016

Yeah we should probably support the Forwarded header as well, though I have only seen the ad-hoc standard in practice.

@untitaker
Copy link
Member

@untitaker untitaker commented Nov 5, 2016

(Also X practically means "nonstandard", not "experimental")

@tuukkamustonen
Copy link

@tuukkamustonen tuukkamustonen commented May 14, 2018

Normally, sites are served in default ports (80 for HTTP, 443 for HTTPS) so X-Forwarded-Port is not needed even if protocol changes. But if an application is served on a non-default port, and if X-Forwarded-Host doesn't include port (when does it?), then X-Forwarded-Port should be needed.

AWS ELB/ALB set X-Forwarded-Port these days (https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html, https://forums.aws.amazon.com/thread.jspa?messageID=738145). I assume that also means that X-Forwarded-Host will NOT include the port, so support for X-Forwarded-Port should be added.

@c4milo
Copy link

@c4milo c4milo commented Oct 12, 2018

I just finished chasing a very annoying issue with application's redirects breaking because the external port was not being picked up by ProxyFix. X-Forwarded-Port should be supported. This is especially important inside enterprise environments.

@untitaker
Copy link
Member

@untitaker untitaker commented Oct 12, 2018

@c4milo This issue is already closed. X-Forwarded-Port is supported.

@AdrianVollmer
Copy link

@AdrianVollmer AdrianVollmer commented Jun 10, 2019

For some reason it does not appear to work for me. Consider this test script:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from flask import Flask, redirect, request
from werkzeug.middleware.proxy_fix import ProxyFix
import werkzeug

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)


@app.route('/')
def index():
    print("Werkzeug version:", werkzeug.__version__)
    print(request.headers)
    return redirect('/test')

app.run()

nginx is set up approriately. When I access the URL, I don't get redirected to the right port:

$ curl 192.168.11.2:8080 -Is | grep Location
Location: http://192.168.11.2/test

This is the output of the test script:

$ ./proxyfix-test.py                                                                      (vi)
 * Serving Flask app "proxyfix-test" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Werkzeug version: 0.15.4
Host: 192.168.11.2
X-Real-Ip: 192.168.11.2
X-Forwarded-For: 192.168.11.2:8080
X-Forwarded-Port: 8080
X-Forwarded-Proto: http
Connection: close
User-Agent: curl/7.64.0
Accept: */*


192.168.11.2:8080 - - [10/Jun/2019 11:00:42] "HEAD / HTTP/1.0" 302 -

Am I doing something wrong?

@davidism
Copy link
Member Author

@davidism davidism commented Jun 10, 2019

All ProxyFix does is adjust the WSGI variables and HTTP headers associated with proxying, it doesn't redirect you to different locations. If you want incorrect ports to redirect to the one you want, that would be done with Nginx, not with Flask, although I haven't heard of such a situation before.

@AdrianVollmer
Copy link

@AdrianVollmer AdrianVollmer commented Jun 10, 2019

Not sure if we are talking about the same problem. I'd expect the output of the curl command above to be Location: http://192.168.11.2:8080/test. ProxyFix already adjusts the server "from 127.0.0.1" to "192.168.11.2" . But it fails to adjust the port and thus the user's browser shows an error message, because there is not actually anything listening on port 80.

@davidism
Copy link
Member Author

@davidism davidism commented Jun 10, 2019

You didn't specify x_port=1 when setting up ProxyFix. See the docs. It only enables x_forwarded=1 by default, other headers need to be explicitly whitelisted.

@pallets pallets locked as resolved and limited conversation to collaborators Jun 10, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants