Eine Anfrage, die in Ihrer Anwendung eintrifft, trägt zwei Arten von Adressbelegen: die Gegenstelle, welche die Netzwerkverbindung geöffnet hat, und ein HTTP-Feld, das die Adresse eines früheren Clients behauptet. Sie beantworten unterschiedliche Fragen. Die Socket-Gegenstelle wird beobachtet, während der Header von demjenigen behauptet wird, der ihn geschrieben hat, und keiner sollte den anderen stillschweigend in einem Protokoll oder einer Zugriffsregel ersetzen. Der Vergleich unten hält beide getrennt und zeigt dann die einzige Anordnung, in der der Header brauchbar wird.

Beschreiben Sie den Pfad, bevor Sie etwas vergleichen:

Client -> approved reverse proxy -> application origin

In dieser Anordnung ist die Socket-Gegenstelle des Ursprungs normalerweise der Proxy, und ein Weiterleitungs-Header kann die Behauptung des Proxys über den Client tragen. Sein Wert stammt aus der kontrollierten Beziehung zu diesem Proxy, nicht aus dem Namen des Headers.

Zwei Arten von Adressbelegen

Die Socket-Gegenstelle ist eine Tatsache über eine TCP-Verbindung: Etwas hat einen Handshake von jener Adresse abgeschlossen. Es ist nicht zwangsläufig der Mensch, das Gerät oder das Konto, das Ihnen wichtig ist, denn ein VPN oder ein Tor-Ausgang kann rechtmäßig die Quelle sein, die ein Dienst beobachtet. Sie bleibt die einzige Adresse, die der Host selbst verifiziert hat, und darin liegt ihr ganzer Wert.

Ein Weiterleitungsfeld sind Metadaten über eine Kette. X-Forwarded-For, X-Real-IP und das standardisierte Feld Forwarded kann jeder Client schreiben, der einen Endpunkt erreicht, der sie zurückspiegelt, sodass ihre Verlässlichkeit ganz davon abhängt, wem es erlaubt war, sie zu setzen.

Behalten Sie beide im Anforderungskontext unter getrennten Namen. Eine Anwendung, die die Gegenstelle mit dem Header überschreibt, verliert die Fähigkeit, später einen Vertrauensfehler zu rekonstruieren, und genau dann brauchen Sie sie.

Ein Header leitet die Verbindung nie um

Eine Adresse in ein Weiterleitungsfeld zu schreiben, ändert nicht die Quelle der TCP-Verbindung, die am Server ankommt, und es ändert auch nirgends auf dem Pfad das Routing. Gewöhnliches VPN-Routing oder Quell-NAT liefert Verkehr ganz ohne HTTP-Header. Ebenso schreibt ein Transit-Gateway eine ordnungsgemäß geschützte HTTPS-Auswechslung nicht um, ohne die Anordnung des TLS-Endpunkts zu ändern.

Der umgekehrte Fehler ist ebenso verbreitet: HTTPS macht einen vom Client gelieferten Weiterleitungs-Header nicht wahr. Es schützt den Transport einer falschen Behauptung genauso gut wie den einer wahren.

Wenn ein Kollege eine Header-Änderung vorschlägt, um ein Routingproblem zu beheben, ist die Diagnose bereits schiefgegangen. Reparieren Sie den Pfad oder die Proxy-Konfiguration, die den Header schreibt.

Benennen Sie den Proxy, der behaupten darf

Zwei Regeln machen ein Weiterleitungsfeld brauchbar, und beide sind Konfiguration statt Code. Der Rand normalisiert oder verwirft alles, was von außen kommt, nach seinem eigenen dokumentierten Verhalten für diese Felder. Der Ursprung nimmt dann eine Ersatzadresse aus dem Proxy-Pfad, den Sie benannt haben, und aus nichts anderem. Die zweite Regel gilt nur, solange Clients den Ursprung nicht auf anderem Weg erreichen können, denn ein Ursprung, der sowohl direkte als auch weitergeleitete Anfragen beantwortet, weiß nicht, welchen der beiden er bedient.

NGINX-Modul für die echte IP zeigt die Trennung deutlich. set_real_ip_from benennt die Absender, deren Behauptung zählt, und real_ip_header sagt, welches Feld sie trägt; das erste übt das Vertrauen aus, das zweite sagt nur, wo man nachsehen soll.

set_real_ip_from 10.20.0.0/24;
real_ip_header X-Forwarded-For;
# real_ip_recursive off - take the rightmost value in the field
# real_ip_recursive on  - walk the list back past every trusted address

Eine Direktive zur Header-Auswahl allein begründet noch nichts darüber, wer den Wert gesendet hat.

Transportsicherheit muss den ganzen Weg zwischen den Komponenten laufen, denen Sie vertrauen. Ein Rand, der korrekt normalisiert, verliert diesen Wert in dem Moment, in dem ein ungeschützter Hop weiter unten jemand anderem erlaubt, die Behauptung während der Übertragung zu ändern.

Behandeln Sie Ketten mit mehreren Hops bewusst

Mehrere Proxys brauchen ein ausdrückliches Kettenmodell. Nehmen Sie nicht den linken oder rechten kommagetrennten Wert, nur weil ein Blogbeitrag es getan hat; finden Sie heraus, welcher Ihrer Proxys anhängt, welcher ersetzt und welcher das eingehende Feld bewahrt. NGINX etwa kann die Liste rückwärts gegen seine vertrauenswürdige Menge durchlaufen und bei der ersten Adresse anhalten, die es nicht besitzt, und das ist die Regel jenes Produkts und kein Gesetz, dem jedes Framework folgt. Lesen Sie die Dokumentation Ihres eigenen Proxys mit denselben zwei Fragen: Welchen Wert wählt er, und welchen Absendern glaubt er?

Schreiben Sie die Kette auf: Hop-Reihenfolge, welcher Hop das Feld setzt und welcher Hop eingehende Kopien entfernt. Halten Sie diese Notiz dann neben der Proxy-Konfiguration fest, nicht nur im Ticket. Testen Sie es dann, indem Sie eine Anfrage mit einem gefälschten Header durch den genehmigten Validierungsprozess senden und bestätigen, dass der Ursprung ihn ignoriert.

Wenn Sie einen Hop hinzufügen, überprüfen Sie dieses Dokument erneut. Ein neuer Lastverteiler vor dem vertrauenswürdigen Proxy kann ändern, welche Adresse gewinnt, ohne dass jemand die Anwendung bearbeitet.

Behalten Sie beide Beobachtungen im Protokoll

Wo Diagnostik zulässig ist, protokollieren Sie die Verbindungsgegenstelle und die normalisierte Client-Adresse als zwei getrennte Felder und ergänzen Sie nur die Weiterleitungs-Metadaten, die der Zweck tatsächlich braucht. Beweisen Sie dann die Bereitstellung mit zwei Anfragen: einer über den Proxy, die beide Werte sinnvoll erfassen sollte, und einem Versuch direkt zum Ursprung, der abgelehnt werden muss.

Denken Sie daran, was das Paar bedeutet. Der Header fügt Kontext hinzu, den eine Komponente liefert, der Sie vertrauen wollten; die Gegenstelle bleibt die einzige Adresse, die Ihr Host tatsächlich gesehen hat. Keine von beiden ist ein Beweis für individuelle Identität, und ein Entwurf, der eine von ihnen als Beweis behandelt, wird sich über jemanden irren.

Ähnliche Artikel