Was PHPs REMOTE_ADDR hinter einem VPN wirklich aussagt
Es ist ein Wert, den Ihr Webserver geliefert hat, kein Blick in den Tunnel. Gehen Sie den Anfrageweg durch, prüfen Sie, wer ihn umschreiben darf, und behalten Sie die Identität in der Anwendung.
Jemand fragt, warum ein VPN-Nutzer im Anwendungsprotokoll mit einer Adresse auftaucht, die zum Gateway gehört, oder mit einer Adresse, die sich nach dem Mittagessen geändert hat. Die Antwort beginnt damit, was dieser Wert ist: ein Eintrag, den der Webserver in die Anfrageumgebung geschrieben hat. Er ist keine Abfrage in den Tunnel, keine Zertifikatsidentität und kein Versprechen, dass die Nummer zu einer einzigen Person gehört. Wer ihn als eines dieser drei Dinge liest, erhält selbstsichere Antworten, die auf unterschiedliche Weise falsch sind.
Der Wert kommt vom Server, nicht vom Tunnel
PHP erhält die Anfrageumgebung von dem, was das Skript ausgeführt hat. Die Referenz zu den PHP-Servervariablen beschreibt diese Einträge als vom Webserver erzeugt, wobei die Verfügbarkeit davon abhängt, wie die Anfrage eingetroffen ist.
Ein Skript, das als Kommandozeilen-Hook des VPN läuft, ist ein völlig anderer Ausführungskontext. Es hat keine Web-Anfrage, keinen Client-Socket und kein REMOTE_ADDR; deshalb liefert kopierter Web-Code im Hook leere Werte statt falscher. Der Hook hat seine eigene Umgebung, die der Daemon befüllt, und sie ist separat dokumentiert. Wer dort nach REMOTE_ADDR greift, greift nach einer Variable, die nie gesetzt wurde.
Behalten Sie diesen Unterschied im Kopf, bevor Sie zwei Protokolle vergleichen. Womöglich vergleichen Sie eine Seitenanfrage mit einem Hook, und das ist überhaupt kein Vergleich. Prüfen Sie zuerst den Ausführungskontext und danach die Adresse.
Gehen Sie den Anfrageweg durch, bevor Sie der Nummer trauen
Die gemeldete Adresse ist der Peer der Verbindung, die der Webserver gesehen hat. Schieben Sie irgendetwas zwischen Client und Server, ändert sich der Peer. Übersetzung, Terminierung und Lastverteilung verschieben die Beobachtung jeweils um einen Hop weiter vom Nutzer weg.
Vier übliche Wege ergeben vier verschiedene Beobachtungen.
| Path to the listener | What can be reported |
|---|---|
| Client routed straight to the private listener, no translation | The client's tunnel address |
| Gateway translates the source before forwarding | The gateway's translated address |
| Reverse proxy terminates the client and opens its own backend connection | The proxy's backend address |
| Load balancer in front of two proxies | Whichever hop the server treats as its peer |
Schreiben Sie den Weg mit Zielname, Adressfamilie und jedem Übersetzungspunkt auf. Ohne diese Karte sehen ein korrekter und ein falscher Wert in einer Protokollzeile identisch aus. Zwei Zeilen Diagramm ersparen einen Nachmittag Diskussion.
Ersetzt wird nur, wo es konfiguriert ist
Ein Server oder Framework kann die Client-Adresse bewusst ersetzen. Das Remote-IP-Modul von Apache und das Real-IP-Modul von NGINX tun genau das, und der Wert, den PHP erhält, hängt von dieser Konfiguration sowie den Parametern ab, die an den Script-Handler übergeben werden.
REMOTE_ADDR ist also nicht durchweg der unberührte TCP-Peer. Es ist der Peer, wie der Server ihn nach Anwendung seiner eigenen Richtlinie zu melden beschlossen hat. Dieser Unterschied entscheidet, ob der Wert ein Beweis oder nur Dekoration ist.
Fragen Sie den Serververantwortlichen, welches Feld in dieser Installation maßgeblich ist und wie der ursprüngliche Peer erhalten bleibt, wenn ersetzt wird. Kann das niemand beantworten, ist das Protokoll noch kein Beweis für irgendetwas.
Weiterleitungs-Headern nicht blind vertrauen
Ein Aufrufer kann Weiterleitungs-Header selbst senden. Den ersten kommagetrennten Eintrag als verifizierte Nutzeradresse zu behandeln, bedeutet, jedem zu glauben, der sich verbindet, und das ist das Gegenteil dessen, wofür der Header gedacht ist. Der Header beschreibt eine Kette, und nur eine vertrauenswürdige Schicht kann für diese Kette bürgen.
Nutzen Sie die Trusted-Proxy-Unterstützung des Servers oder Frameworks mit der tatsächlichen Proxy-Kette in der Konfiguration, und lassen Sie sie Werte aus Quellen außerhalb dieser Kette verwerfen. Selbstgeschriebenes Parsing ist die Stelle, an der die meisten interessanten Fehler wohnen.
Eine vom Proxy gemeldete Adresse ändert auch nicht die Paketquelle, die eine vorgelagerte Firewall sieht. Halten Sie HTTP-Metadaten und Netzfilterung als getrennte Beobachtungen auseinander, denn sie beantworten verschiedene Fragen.
Für Entscheidungen die Identität der Anwendung nutzen
Für den Zugriff auf die Datensätze eines Nutzers verlassen Sie sich auf das authentifizierte Subjekt und die Autorisierungsregeln der Anwendung. Eine interne Adresse kann neu vergeben werden, und eine übersetzte Adresse kann für Hunderte gleichzeitige Nutzer stehen. Keine dieser Eigenschaften kann eine Adressprüfung reparieren.
Wenn der Betrieb eine Anfrage einer VPN-Sitzung zuordnen muss, verknüpfen Sie die beobachtete Adresse und den Zeitstempel nach dem dokumentierten Übersetzungsmodell mit den maßgeblichen Sitzungsdaten. Das ergibt eine Assoziation, die Sie verteidigen können; eine Adresse allein nicht.
Loggen Sie für die Diagnose die wenigen benötigten Felder statt des gesamten Server-Arrays, das Header und Authentifizierungsmaterial enthalten kann. Die nützliche Schlussfolgerung sagt, was dieser Wert in dieser Installation bedeutet, nicht, welcher Wert am meisten wie ein Client aussieht.