Varför din iPhone-app visar en IP och servern loggar en annan
En gränssnittsadress, en socket-slutpunkt och den källa en server registrerar svarar på olika frågor. En VPN lägger till kontext; den gör dem inte till ett enda tal.
Det kommer supportärenden som säger att appen visar en adress medan servern loggade en annan, och sedan frågar vilken av dem som ljuger. Ingen av dem; det är två observationer av två olika saker. En adress bunden till ett gränssnitt, en adress bunden till en socket och en källadress som en fjärrtjänst ser svarar på tre separata frågor. En VPN lägger till en nätverkskontext på telefonen och slår inte ihop de tre till ett enda tal för hela enheten. Läs fältnamnen i ärendet innan du läser adresserna.
Vad ärendet brukar beskriva
Föreställ dig en telefon på Wi-Fi med en tunnel uppe. Wi-Fi-gränssnittet har en LAN-adress, tunnelgränssnittet har en tilldelad inre adress, och en förfrågan som går ut genom tunneln når en offentlig tjänst från vilken källa som helst som överlever en eventuell översättning på vägen. En app som skriver ut den inre adressen och en server som loggar den översatta källan rapporterar båda korrekt, och de två värdena kommer aldrig att stämma överens.
De tre observationerna skiljer sig i vad de kan bevisa, inte bara i vad de beskriver.
| 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 |
Håll den tabellen bredvid koden som fyller dessa värden i ett ärende, för det mesta av förvirringen här är en kolumnförväxling och inte ett nätverksfel.
Vad ett socket-anrop kan och inte kan svara på
På API-nivå rapporterar getsockname den lokala slutpunkten som för närvarande är bunden till en viss socket. För en ansluten socket är det den källa som kärnan valde för den anslutningen, vilket redan är mer specifikt än någon gränssnittslista. Det är inte en uppslagning av offentlig adress, och att anropa det på en obunden socket säger dig nästan ingenting. Vad det än returnerar kan senare skrivas om på vägen, så bara tjänstens egen observation är auktoritativ om vad tjänsten tog emot.
På Apple-plattformar har gränssnittssidan en egen yta: tunnelinställningarna listar de adresser som är tilldelade tunnelgränssnittet. Att läsa dem säger dig hur tunneln konfigurerades, och det säger dig inte vilken väg en viss förfrågan tog, eftersom routning och regler per app avgör det för varje anslutning.
Delad tunnling gör gapet synligt. En förfrågan kan gå ut genom tunneln medan nästa, riktad mot en annan destination eller adressfamilj, inte gör det, så två resultat från samma app med sekunders mellanrum kan vara ärliga och olika.
Välj den observation som passar frågan
Välj medvetet i stället för att instrumentera allt. För det backend ser, logga källan i backend, och där en omvänd proxy står framför, läs klientadressen från vidarebefordringshuvudet som din driftsättning faktiskt sätter, och inte från något klienten skickade.
För att veta om tunneln är konfigurerad, läs gränssnittet. För att veta om den här appens trafik använde den, skicka trafik från den appen till en destination du kontrollerar och jämför källan i båda ändar.
Regler per app förtjänar sin egen mening. Ett webbläsarresultat är bevis om den webbläsaren, och en hanterad tunnel per app kan sätta två appar på samma telefon på olika vägar i samma ögonblick. Att verifiera täckning innebär att skicka trafik från den aktuella appen, i den aktuella adressfamiljen.
Gränssnittsnamn är inte en detektor
Använd inte heller ett gränssnittsnamn som VPN-kontroll. Namnen är inte ett offentligt kontrakt, och en telefon kan ha flera anslutningar medan bara en av dem bär din förfrågan.
Namnge fältet efter den observation det håller. local_interface_address, socket_local_endpoint och service_observed_source är klumpiga och entydiga, och entydigt är vad du vill ha när värdet hamnar i ett supportärende en vecka senare. En enda kolumn som heter device IP samlar alla tre och sedan litas det på den som om den vore en.
Håll identitet utanför adresskolumnen
En delad VPN-utgång är inte en användaridentitet, och en privat adress är inte en åtkomstuppgift. Båda beskriver en väg och inte en person, och att behandla någon av dem som autentisering gör en routningsolycka till ett auktoriseringsbeslut.
När någon frågar vilken adress telefonen har, är det användbara svaret en fråga om vilken anslutning och vilken observatör. Definitionen av getsockname är värd att citera för mittfallet, eftersom den avgör socket-frågan utan att låtsas avgöra de två andra.
Skriv sedan ned vilken av de tre din produkt faktiskt behöver visa, och ta bort de två andra från gränssnittet.