Du föreställer dig att VPN-servern läser adressen till din bärbara dator från paketet och skriver den i en logg. Det den läser är vad det sista NAT-hoppet satte i det yttre huvudet, och på en telefon som används som hotspot är det ofta en adress som delas med hundratals andra abonnenter. Din maskins egen 192.168.x.x korsar aldrig internet i det huvudet, och tunneladressen delas ut av servern först när anslutningen redan är uppe. När en serverlogg och ip addr på den bärbara datorn därför inte stämmer är ingen av dem fel; de beskriver olika lager av en och samma session.

Tre adresser, och bara en av dem står i loggen

Förvirringen uppstår när tre adresser slås ihop till en. Var och en har en annan ägare, lever i ett annat huvud och når servern via en annan väg.

AddressWho assigns itWhere it sitsVisible to the VPN server
Device address, e.g. 192.168.1.24Your router via DHCPOuter header, before translationNo, rewritten in place
Translated address and portRouter, ISP CGNAT, or bothOuter header, after translationYes, this is the tuple it logs
Tunnel address, e.g. 10.8.0.6The VPN server itselfInner header, after decapsulationYes, but it chose it

Bara den mellersta raden är okänd vid anslutningen. Servern skriver den i peertabellen, statusfilen eller flödesloggen beroende på daemon: WireGuard kallar den slutpunkten, en OpenVPN-statusfil kallar den Real Address, och strongSwan rapporterar den som IKE_SA:ns fjärrvärd. Värdet uppdateras varje gång ett paket kommer från en annan källa, så det ändras utan att någon startar om något.

Den nedersta raden är det som folk felaktigt läser som ett identitetspåstående. Den markerar en plats i serverkonfigurationen, inte en person, eftersom servern valde den ur sin egen pool. Två användare kan få samma tunneladress olika dagar, och en kan ha två av dem från två enheter.

Varför den loggade tupeln ändras medan tunneln ligger uppe

Adressöversättning är en tabell med en timer, inte en permanent bindning. En hemrouter behåller sin UDP-mappning en stund efter det sista paketet, en operatörsgateway återanvänder portar enligt sitt eget schema, och en telefon som hoppar från Wi-Fi till LTE kommer tillbaka med en helt annan källa. Linux conntracks standardvärden är ett användbart riktmärke här: nf_conntrack_udp_timeout är 30 sekunder och streamingvarianten 120, så en tyst tunnel kan tappa mappningen långt innan användaren märker det.

Tunneln överlever eftersom protokollet autentiserar peeren, inte adressen. WireGuard är tillståndslös efter handskakningen, så varje autentiserat paket uppdaterar den sparade slutpunkten och en ny bindning läks vid nästa paket; därför finns persistent-keepalive = 25, för att hålla mappningen varm under inaktivitet. OpenVPN:s --float gör samma sak och låter en autentiserad klient fortsätta från en ny adress och port. På 2.4- och 2.5-byggen där float är avstängt som standard återställer en ny bindning sessionen och klienten ansluter igen.

IPsec tar sig dit med fler rörliga delar. IKEv2 upptäcker översättningen genom att jämföra käll- och målhasharna i NAT-detekteringsnyttolasterna, byter till UDP 4500-inkapsling och följer keepalives till den nya tupeln. När keepalives blockeras står SA kvar på papperet medan trafik i en riktning tystnar.

Vad servern kan tillskriva, och vad den inte kan

Myten som är värd att döda är att översättningen döljer dig för operatören. Den ändrar etiketten, inte observationen. En gateway bakom operatörens NAT ser 100.64.0.0/10-rymden eller en offentlig adress som många abonnenter delar, och kan ändå knyta flödet till ett certifikatsubjekt, en offentlig WireGuard-nyckel, en tilldelad tunneladress, byteräknare och ett tidsfönster. Inget av det behöver din LAN-adress.

Gränserna går också åt andra hållet. En delad adress i en logg pekar på en gateway, inte ett hushåll; två sessioner från samma översatta adress på olika portar är olika enheter; samma adress två olika dagar kan vara två orelaterade abonnenter om porten återanvändes. En server som bara registrerar peer-nycklar kan inte koppla en till en kund utan kontodatabasen, och en server som bara registrerar adresser kan inte skilja en bärbar dator från en telefon bakom samma router.

Jämför båda ändarna i stället för att gissa

För att avgöra vad som hände, fånga samma anslutning vid båda ändarna vid samma tillfälle och jämför tupeln, inte adressen. På klienten, före varje översättning:

ss -uapn 'dport = :51820'
ip -4 route get 203.0.113.10
wg show wg0 endpoints

Läs sedan översättningsposten på routern eller CGNAT-gatewayen, och det som till slut når servern:

conntrack -L -p udp --dport 51820
tcpdump -ni eth0 udp port 51820

Tre mönster förklarar de flesta avvikelserna. Källporten på servern skiljer sig från den lokala porten medan målet stämmer: vanlig portöversättning. Källadressen på servern tillhör ett ISP-block som inte är ditt: minst ett extra NAT-lager. Paketen stannar efter en inaktivitetsperiod och återupptas med en ny port: mappningen har gått ut, inte ett routingfel. Om tidsstämplarna ligger mer än en sekund eller två isär jämför du två olika försök.

Där skillnaden förstör saker

Avbrott som ser ut som serverfel börjar oftast här. En åtkomstregel fäst vid din hemadress misslyckas efter att ISP-leasen ändras. En fail2ban-regel som matchar en översatt adress stänger av alla abonnenter bakom den gatewayen på en gång. En site-till-site-peer med fast fjärradress slutar förnya nycklar efter att en mobillänk ändras. Tunnelprotokollet var okej; antagandet om den yttre tupeln var det inte.

Samma förvirring dyker upp på serversidan. Om själva VPN-boxen står bakom NAT behöver du portvidarebefordran och en fungerande vidarebefordringsväg; strongSwans vidarebefordringsguide täcker det fallet för IPsec. En server som bara är nåbar på en privat adress ser aldrig den översatta tupel som klienterna presenterar, och det är ett annat problem än att klienter blir översatta.

Gå igenom dessa fyra kontroller i ordning och stanna vid den första som misslyckas:

  • Fånga vid båda ändarna samtidigt; bekräfta att källport, målport och tidsstämplar stämmer.
  • Läs serverns peer-lista för den adress den håller nu, inte den du förväntade dig.
  • Kontrollera conntrack- eller NAT-tabellen för posten och dess återstående livslängd.
  • Bekräfta att tunnelgränssnittets adress på klienten stämmer med den servern tilldelade, inte LAN-adressen.

Om båda fångsterna är överens om tupeln och tunneln ändå misslyckas är översättningen inte ditt problem; gå vidare till handskakningen och till routingtabellen inuti tunneln.

Relaterade artiklar