Ich habe gerade eine Flask-App auf Webfaction bereitgestellt und festgestellt, dass request.remote_addr immer 127.0.0.1 ist. was natürlich nicht viel nützt.

Wie kann ich die tatsächliche IP-Adresse des Benutzers in Flask on Webfaction ermitteln?

Vielen Dank!

26
Ignas Butėnas 7 Okt. 2012 im 21:09

5 Antworten

Beste Antwort

Wenn sich vor Flask ein Proxy befindet, erhält so etwas die echte IP in Flask:

if request.headers.getlist("X-Forwarded-For"):
   ip = request.headers.getlist("X-Forwarded-For")[0]
else:
   ip = request.remote_addr

Update: Sehr guter Punkt, den Eli in seinem Kommentar erwähnt hat. Es kann einige Sicherheitsprobleme geben, wenn Sie dies einfach verwenden. Lesen Sie Elis Beitrag, um weitere Informationen zu erhalten.

39
Community 2 Apr. 2016 im 17:33

Das Problem ist, dass es wahrscheinlich eine Art Proxy vor Flask gibt. In diesem Fall befindet sich die "echte" IP-Adresse häufig in request.headers['X-Forwarded-For'].

3
Rob Wouters 7 Okt. 2012 im 17:12

Werkzeug Middleware

Die Dokumentation von Flask ist ziemlich spezifisch bezüglich des empfohlenen Reverse-Proxy-Server-Setups:

Wenn Sie Ihre Anwendung über einen dieser [WSGI] -Server hinter einem HTTP-Proxy [Reverse] bereitstellen, müssen Sie einige Header neu schreiben, damit die Anwendung [ordnungsgemäß] funktioniert. Die beiden problematischen Werte in der WSGI-Umgebung sind normalerweise REMOTE_ADDR und HTTP_HOST ... Werkzeug liefert einen Fixer, der einige gängige Setups löst, aber Sie möchten möglicherweise Ihre eigene WSGI-Middleware für bestimmte Setups schreiben.

Und auch über Sicherheitsaspekte:

Beachten Sie bitte, dass es ein Sicherheitsproblem ist, eine solche Middleware in einem Nicht-Proxy-Setup zu verwenden, da sie den eingehenden Headern, die möglicherweise von böswilligen Clients gefälscht werden, blind vertraut.

Der vorgeschlagene Code (der die Middleware installiert), mit dem request.remote_addr die Client-IP-Adresse zurückgibt, lautet:

from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, num_proxies=1)

Beachten Sie num_proxies, das standardmäßig 1 ist. Dies ist die Anzahl der Proxyserver vor der App .

Der tatsächliche Code lautet wie folgt (letzter werkzeug==0.14.1 zum Zeitpunkt des Schreibens):

def get_remote_addr(self, forwarded_for):
    if len(forwarded_for) >= self.num_proxies:
        return forwarded_for[-self.num_proxies]

Webfraktion

In der Dokumentation von Webfaction zum Zugriff auf REMOTE_ADDR heißt es ::

... die IP-Adresse ist als erste IP-Adresse in der durch Kommas getrennten Liste im HTTP_X_FORWARDED_FOR -Header verfügbar.

Sie sagen nicht, was sie tun, wenn eine Client-Anfrage bereits einen X-Forwarded-For - Header enthält, aber nach dem gesunden Menschenverstand würde ich davon ausgehen, dass sie ihn ersetzen. Daher sollte für Webfaction num_proxies auf 0 gesetzt werden.

Nginx

Nginx ist expliziter in Bezug auf $proxy_add_x_forwarded_for:

Das Client-Anforderungsheaderfeld "X-Forwarded-For" mit der angehängten Variablen $remote_addr, durch Komma getrennt. Wenn das Feld "X-Forwarded-For" im Clientanforderungsheader nicht vorhanden ist, entspricht die Variable $proxy_add_x_forwarded_for der Variablen $remote_addr.

Für Nginx vor der App sollte num_proxies standardmäßig 1 belassen werden.

4
saaj 28 Juni 2018 im 17:11

Sie können request.access_route verwenden, um auf die IP-Liste zuzugreifen:

if len(request.access_route) > 1:
    return request.access_route[-1]
else:
    return request.access_route[0]

Aktualisieren:

Sie können dies einfach schreiben:

    return request.access_route[-1]
3
itmard 12 Juli 2016 im 22:33

Umschreiben der Antwort der Ignas:

headers_list = request.headers.getlist("X-Forwarded-For")
user_ip = headers_list[0] if headers_list else request.remote_addr

Denken Sie daran, Elis Beitrag über Spoofing-Überlegungen zu lesen.

5
ankostis 12 Jän. 2018 im 15:51