it-swarm.com.de

nginx real_ip_header und X-Forwarded-For scheinen falsch zu sein

Die Wikipedia-Beschreibung des HTTP-Headers X-Forwarded-For Lautet:

X-Forwarded-For: Client1, Proxy1, Proxy2, ...

Die Nginx-Dokumentation für die Direktive real_ip_header Lautet teilweise:

Diese Anweisung legt den Namen des Headers fest, der zum Übertragen der Ersatz-IP-Adresse verwendet wird.
Im Fall von X-Forwarded-For verwendet dieses Modul die letzte IP im X-Forwarded-For-Header zum Ersetzen. [Hervorhebung von mir]

Diese beiden Beschreibungen scheinen im Widerspruch zueinander zu stehen. In unserem Szenario ist der X-Forwarded-For - Header genau wie beschrieben - die "echte" IP-Adresse des Clients ist der Eintrag ganz links. Ebenso besteht das Verhalten von nginx darin, den rechten - höchsten Wert zu verwenden - der offensichtlich nur einer unserer Proxyserver ist.

Mein Verständnis von X-Real-IP Ist, dass angenommen wird, dass verwendet wird, um das tatsächliche Client-IP-Adresse - nicht der Proxy. Vermisse ich etwas oder ist das ein Fehler in Nginx?

Und darüber hinaus hat jemand Vorschläge, wie der Header X-Real-IP Den linken - höchsten Wert anzeigen kann, wie durch angezeigt die Definition von X-Forwarded-For?

62
Kirk Woll

Ich glaube, der Schlüssel zur Lösung von X-Forwarded-For-Problemen, wenn mehrere IPs verkettet sind, ist die kürzlich eingeführte Konfigurationsoption real_ip_recursive (hinzugefügt in nginx 1.2.1 und 1.3.0). Aus dem nginx realip docs :

Wenn die rekursive Suche aktiviert ist, wird eine ursprüngliche Clientadresse, die mit einer der vertrauenswürdigen Adressen übereinstimmt, durch die letzte nicht vertrauenswürdige Adresse ersetzt, die im Feld für den Anforderungsheader gesendet wurde.

nginx hat standardmäßig die letzte IP-Adresse in der Kette abgerufen, da dies die einzige war, von der angenommen wurde, dass sie vertrauenswürdig ist. Mit aktiviertem neuen real_ip_recursive und mehreren set_real_ip_from Optionen können Sie jedoch mehrere vertrauenswürdige Proxys definieren und die letzte nicht vertrauenswürdige IP abrufen.

Zum Beispiel mit dieser Konfiguration:

set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

Und ein X-Forwarded-For-Header führt zu:

X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1

nginx wählt nun 123.123.123.123 als IP-Adresse des Clients aus.

Warum nginx nicht nur die IP-Adresse ganz links auswählt und Sie explizit vertrauenswürdige Proxys definieren müssen, um ein einfaches IP-Spoofing zu verhindern.

Angenommen, die tatsächliche IP-Adresse eines Clients lautet 123.123.123.123. Nehmen wir auch an, der Client hat nichts Gutes vor und versucht, seine IP-Adresse als 11.11.11.11 zu fälschen. Sie senden eine Anfrage an den Server, wobei dieser Header bereits vorhanden ist:

X-Forwarded-For: 11.11.11.11

Da Reverse-Proxys dieser X-Forwarded-For-Kette einfach IPs hinzufügen, nehmen wir an, dass sie am Ende so aussieht, wenn Nginx dazu kommt:

X-Forwarded-For: 11.11.11.11, 123.123.123.123, 192.168.2.1, 127.0.0.1

Wenn Sie einfach die Adresse ganz links abrufen, kann der Client seine IP-Adresse leicht fälschen. Mit dem obigen Beispiel nginx config vertraut nginx jedoch nur den letzten beiden Adressen als Proxys. Dies bedeutet, dass nginx 123.123.123.123 korrekt als IP-Adresse auswählt, obwohl diese gefälschte IP tatsächlich ganz links ist.

105
Nick M

Das Parsen des X-Forwarded-For Header ist in der Tat im nginx real_ip Modul fehlerhaft.

len = r->headers_in.x_forwarded_for->value.len;
ip = r->headers_in.x_forwarded_for->value.data;

for (p = ip + len - 1; p > ip; p--) {
  if (*p == ' ' || *p == ',') {
    p++;
    len -= p - ip;
    ip = p;
    break;
  }
}

Es beginnt ganz rechts in der Header-Zeichenfolge. Sobald ein Leerzeichen oder Komma angezeigt wird, hört es auf zu suchen und klebt den Teil rechts neben das Leerzeichen oder Komma in der IP-Variablen. Es wird also die neueste Proxy-Adresse als ursprünglicher Client Adresse behandelt.

Es spielt nicht Nizza gemäß der Spezifikation; Dies ist die Gefahr, dass es in einem RFC nicht schmerzlich offensichtlich formuliert wird.

Nebenbei : Es ist schwer, eine gute Primärquelle für das Format zu finden, das ursprünglich von Squid definiert wurde - a Dig durch ihre Dokumentation bestätigt die Reihenfolge; ganz links ist der ursprüngliche Client, ganz rechts ist der letzte Anhang. Ich bin sehr versucht, dieser Wikipedia-Seite ein [Zitat benötigt] hinzuzufügen. One anonyme Bearbeitung scheint die Autorität des Internets zu diesem Thema zu sein.

Wenn möglich, können Ihre Zwischenproxys aufhören, sich am Ende des Headers hinzuzufügen, und nur die echte Clientadresse belassen?

9
Shane Madden

X-Real-IP ist die IP-Adresse des tatsächlichen Clients, mit dem der Server spricht (der "echte" Client des Servers), der im Fall einer Proxy-Verbindung der Proxyserver ist. Aus diesem Grund enthält X-Real-IP die letzte IP im X-Forwarded-For-Header.

5
user558061

Eher eine Warnung als eine Antwort ...

Ich habe versucht, einige Nginx-Cache-Server an mehreren Kartenpositionen hinzuzufügen, ohne zu bemerken, dass mein Hauptserver (Datenquelle) befindet sich bereits hinter einem lokal ausgeführten Nginx-Cache-Server, manchmal ist der lokale Server für die Ausführung von Apache und Nginx konfiguriert wird davor gestellt, um als Cache zu fungieren.

Das Hinzufügen eines zweiten separaten Nginx-Cache-Servers würde zu zwei Cache-Servern führen, sodass Ihr HTTP_X_REAL_IP Oder HTTP_X_FORWARDED_FOR Falsch angezeigt wird und die IP-Adresse eines Servers anstelle der Besucher-IP anzeigt.

In meinem Fall habe ich behoben, dass durch Einstellen des neuen Cache-Servers Daten direkt vom Apache-Port (in meinem Fall Port 7080) genommen wurden, wobei der lokale Nginx-Cache am Quell-/Hauptserver umgangen wurde.

Eine andere Lösung wäre, das HTTP_X_REAL_IP Auf dem lokalen Cache-Server zu entfernen.

Ich habe übrigens Plesk Panel ausgeführt.

0
adrianTNT