Warum deine iPhone-App eine IP anzeigt und der Server eine andere protokolliert
Eine Interface-Adresse, ein Socket-Endpunkt und die Quelle, die ein Server protokolliert, beantworten unterschiedliche Fragen. Ein VPN fügt Kontext hinzu; es macht daraus keine einzige Nummer.
Es kommen Support-Tickets, in denen steht, die App zeige eine Adresse an, während der Server eine andere protokolliert habe, und dann wird gefragt, welche von beiden lügt. Keine von beiden; es sind zwei Beobachtungen zweier verschiedener Dinge. Eine an ein Interface gebundene Adresse, eine an einen Socket gebundene Adresse und eine Quelladresse, die ein entfernter Dienst sieht, beantworten drei getrennte Fragen. Ein VPN fügt dem Telefon einen Netzwerkkontext hinzu und fasst diese drei nicht zu einer geräteweiten Nummer zusammen. Lies die Feldnamen im Ticket, bevor du die Adressen liest.
Was das Ticket meist beschreibt
Stell dir ein Telefon im Wi-Fi mit einem aufgebauten Tunnel vor. Das Wi-Fi-Interface trägt eine LAN-Adresse, das Tunnel-Interface trägt eine zugewiesene innere Adresse, und eine Anfrage, die durch den Tunnel hinausgeht, erreicht einen öffentlichen Dienst mit welcher Quelle auch immer eine Übersetzung unterwegs übersteht. Eine App, die die innere Adresse ausgibt, und ein Server, der die übersetzte Quelle protokolliert, berichten beide korrekt, und die beiden Werte werden nie übereinstimmen.
Die drei Beobachtungen unterscheiden sich darin, was sie beweisen können, nicht nur darin, was sie beschreiben.
| Observation | What it describes | What it cannot prove |
|---|---|---|
| An address on a local interface | One configured attachment: Wi-Fi, cellular or a tunnel | The source a remote site receives |
| A socket's local endpoint | The binding used by that one connection | The address after translation further along |
| The peer address at a service | What arrived at that observation point | Any other interface on the phone |
Halte diese Tabelle neben dem Code, der diese Werte in ein Ticket füllt, denn die meiste Verwirrung hier ist eine Spaltenverwechslung und kein Netzwerkfehler.
Was ein Socket-Aufruf beantworten kann und was nicht
Auf API-Ebene meldet getsockname den lokalen Endpunkt, der gerade an einen bestimmten Socket gebunden ist. Bei einem verbundenen Socket ist das die Quelle, die der Kernel für diese Verbindung gewählt hat, was schon spezifischer ist als jede Interface-Auflistung. Es ist keine Suche nach einer öffentlichen Adresse, und der Aufruf auf einem ungebundenen Socket sagt dir fast nichts. Was auch immer er zurückgibt, kann später auf dem Pfad noch umgeschrieben werden, also ist nur die eigene Beobachtung des Dienstes maßgeblich dafür, was der Dienst empfangen hat.
Auf Apple-Plattformen hat die Interface-Seite eine eigene Oberfläche: Tunnel-Einstellungen listen die Adressen auf, die dem Tunnel-Interface zugewiesen sind. Sie zu lesen sagt dir, wie der Tunnel konfiguriert wurde, und es sagt dir nicht, welchen Pfad eine bestimmte Anfrage genommen hat, weil Routing und Regeln pro App das für jede Verbindung entscheiden.
Split-Tunneling macht die Lücke sichtbar. Eine Anfrage kann durch den Tunnel hinausgehen, während die nächste, auf ein anderes Ziel oder eine andere Adressfamilie gerichtet, es nicht tut, also können zwei Ergebnisse derselben App Sekunden auseinander ehrlich und verschieden sein.
Wähle die Beobachtung, die zur Frage passt
Wähle gezielt, statt alles zu instrumentieren. Für das, was das Backend sieht, protokolliere die Quelle im Backend, und wo ein Reverse-Proxy davorsteht, lies die Client-Adresse aus dem Weiterleitungs-Header, den dein Deployment tatsächlich setzt, und nicht aus irgendetwas, das der Client gesendet hat.
Ob der Tunnel konfiguriert ist, liest du am Interface ab. Ob der Verkehr dieser App ihn genutzt hat, findest du heraus, indem du Verkehr aus dieser App an ein Ziel sendest, das du kontrollierst, und die Quelle an beiden Enden vergleichst.
Regeln pro App verdienen einen eigenen Satz. Ein Browser-Ergebnis ist ein Beleg über diesen Browser, und ein verwalteter Tunnel pro App kann zwei Apps auf demselben Telefon im selben Moment auf verschiedene Pfade legen. Abdeckung zu prüfen heißt, Verkehr aus der betreffenden App zu senden, in der betreffenden Adressfamilie.
Interface-Namen sind kein Detektor
Verwende auch keinen Interface-Namen als VPN-Prüfung. Die Namen sind kein öffentlicher Vertrag, und ein Telefon kann mehrere Anbindungen haben, während nur eine davon deine Anfrage trägt.
Benenne das Feld nach der Beobachtung, die es enthält. local_interface_address, socket_local_endpoint und service_observed_source sind sperrig und eindeutig, und eindeutig ist, was du willst, wenn der Wert eine Woche später in einem Support-Ticket landet. Eine einzige Spalte namens device IP sammelt alle drei ein und wird dann vertraut, als wäre sie eine.
Halte Identität aus der Adressspalte heraus
Ein geteilter VPN-Ausgang ist keine Nutzeridentität, und eine private Adresse ist kein Zugangsnachweis. Beide beschreiben einen Pfad und keine Person, und eines von beiden als Authentifizierung zu behandeln macht aus einem Routing-Unfall eine Autorisierungsentscheidung.
Wenn jemand fragt, welche Adresse das Telefon hat, ist die nützliche Antwort eine Frage danach, welche Verbindung und welcher Beobachter. Die Definition von getsockname lohnt sich für den mittleren Fall als Zitat, weil sie die Socket-Frage klärt, ohne vorzugeben, die anderen beiden zu klären.
Schreib dann auf, welche der drei dein Produkt tatsächlich anzeigen muss, und lösche die anderen beiden aus der Oberfläche.