Varför din VPN-tunnel faller när Wi-Fi byts eller Ethernet pluggas in
'Ett nytt SSID, roaming mellan åtkomstpunkter och en inkopplad kabel bryter en tunnel på tre olika ställen. Kontrollera källadressen, sedan rutten, sedan protokollet.'
Två saker rapporteras som ett enda fel: datorn har flyttat till ett annat Wi-Fi-nät, eller en kabel sattes i medan Wi-Fi fortsatte att fungera. Klienten säger fortfarande ansluten, ikonen ser frisk ut och tunneln transporterar ingenting. Under ytan kan bara tre bitar tillstånd flytta sig - förbindelsen, den lokala adressen, standardrutten - och vilken som flyttade sig avgör om tunneln återhämtar sig själv eller behöver ny anslutning. Jag kontrollerar dem i den ordningen, eftersom ändrade kontoinställningar aldrig har åtgärdat någon av dem.
Förbindelse, adress och rutt flyttar sig oberoende
Roaming mellan åtkomstpunkter i samma nät är oftast en L2-händelse. Radion återansluter, gränssnittet behåller adressen och gatewayen, och ingenting som tunneln är beroende av förändras, vilket är varför en promenad genom ett stort kontor ibland går obemärkt förbi. Att ansluta till ett annat SSID är inte det: det gamla gränssnittet kan gå ner, DHCP delar ut en ny adress, en ny gateway och nya resolvers, och det yttre flöde som tunneln använde upphör att existera.
Ethernet lägger till en tredje form. Wi-Fi faller aldrig, så ingen förbindelsehändelse utlöses alls, men det kabelanslutna gränssnittet dyker upp med sin egen adress och vinner ofta standardrutten på metrik. Tunneln fortsätter på en väg som inte längre är föredragen, eller klienten håller sin socket fäst vid det trådlösa nät den startade på. Från webbläsaren ser båda likadana ut: sidor stannar i samma ögonblick som kabeln klickar i.
Så den första frågan är inte om Wi-Fi ändrades. Den är om adressen du är bunden till, eller rutten till slutpunkten, ändrades medan tunneln var uppe.
Den yttre socketen är fäst vid en adress som precis försvann
Varje tunnel är ett yttre flöde: en lokal adress och port som talar med serverns adress och port. På Linux är det en UDP-socket bunden till den gamla källan; när gränssnittet som håller adressen tas bort misslyckas sändningar antingen med EADDRNOTAVAIL eller går ut genom det nya gränssnittet med en källa som servern aldrig har sett.
Den bortre sidan behåller sin egen fästning. En IKEv2-SA utan MOBIKE identifieras av adressparet, och en OpenVPN-session är bunden till den peer-adress den lärde sig, och en NAT-mappning tillhör den privata adressen, porten och den publika adressen som skapade den. Flytta dig bakom en annan NAT och varje svar går till en mappning som inte finns längre. Ingenting på din maskin är felkonfigurerat; femset pekar på ett nät du lämnade.
Läs tillståndet innan du teoretiserar:
ss -unpvisar den lokala adress och port som varje tunnel-socket faktiskt håller.ip route get 203.0.113.10skriver ut källadressen och enheten som kärnan skulle använda för slutpunkten just nu.wg show wg0 endpoints,swanctl --list-saseller klientloggen visar den peer-adress som den bortre sidan tror den talar med.
Om socket-adressen och ruttuppslaget inte stämmer överens har du hittat brottet, och ingen ändring av inloggningsuppgifter kommer att röra det.
Vad varje protokoll gör med en ny källadress
Klienter absorberar ändringen i olika grad, och tabellen är det jag jämför med klientkonfigurationen i stället för att gissa utifrån återanslutningsbeteendet.
| Tunnel | Recovery behaviour | Failure signature |
|---|---|---|
| WireGuard | Updates the peer endpoint when an authenticated packet arrives from a new address; no handshake needed if traffic continues. | Handshake current, no return traffic; wg show still lists the old endpoint. |
| IKEv2/IPsec | MOBIKE (RFC 4555) moves the SA to the new address; without it the responder discards packets from an unknown source. | DPD or keepalive timeouts, then a full rekey or a dead SA. |
| OpenVPN over UDP | --float accepts a packet from a new source mid-session; otherwise the session stays tied to the original peer address. | Idle until ping-restart fires, then a visible reconnect. |
| OpenVPN over TCP | The tunnel is a byte stream, so a changed source address breaks it outright. | Immediate reset and a new connection attempt. |
WireGuards roamingregel fungerar bara i en riktning: klienten måste först skicka från den nya adressen. En socket som fortfarande är bunden till det gamla gränssnittet gör det aldrig, vilket är varför en tunnel kan se levande ut medan dess handskakningstimer åldras. protokollbeskrivningen anger exakt villkoret för uppdatering av slutpunkten, och den är värd att läsa innan du ändrar en konfiguration.
MOBIKE förhandlas, det antas inte. Om servern inte erbjuder det måste klienten återupprätta, och det är ett faktum du bekräftar från SA-listan eller loggen i stället för att dra slutsatsen från ett snurrande hjul.
Ruttprioriteringen avgör vägen, inte Wi-Fi-ikonen
Med båda gränssnitten uppe väljer kärnan efter metrik och prefixlängd. ip route show default listar kandidaterna och ip route get 203.0.113.10 avgör det verkliga beslutet, inklusive källadressen. En kabelansluten standardrutt på metrik 100 och en trådlös på 600 betyder att slutpunkten flyttas i samma ögonblick som kabeln sätter sig, medan varje program som öppnade en socket tidigare behåller sin gamla källa.
Windows gör samma sak med automatiska gränssnittsmetriker, påverkade av länkhastigheten. Get-NetRoute -DestinationPrefix 0.0.0.0/0 sorterar kandidaterna, och Find-NetRoute -RemoteIPAddress 203.0.113.10 returnerar det gränssnitt och den källa som stacken skulle välja. En klient som binder sin yttre socket till ett gränssnitt fortsätter att använda det efter att metriken vänt; det är ett bindningsbeslut, inte ett routingfel.
Android gör uppdelningen synlig: ConnectivityManager rapporterar tillgängliga nät och en separat standard, och en VPN-app som binder en socket till ett Network-objekt behåller bindningen tills den binder om. På macOS scutil --nwi skriver ut det primära gränssnittet och den ordning som systemet skulle använda.
DNS, MTU och IPv6 flyttar med anslutningen
En ny anslutning tar med sig nya resolvers. Med systemd-resolved är DNS per länk, resolvectl status visar vilken länk som svarar på ett namn, och ett gästnät som delar ut sin egen resolver kan lämna den DNS som tunneln tryckt in oanvänd tills länken blir föredragen igen. En captive portal gör det värre: den första HTTPS-förfrågan besvaras av portalen i stället för slutpunkten, och klienten registrerar en död server.
MTU:n för vägen ändras också. Ethernet och Wi-Fi bär oftast 1500 byte, PPPoE 1492, och mobila länkar ofta mindre. En tunnel som ärver en mindre MTU fastnar på stora paket medan små förfrågningar går igenom, vilket läses som en halvt bruten anslutning. ping -M do -s 1472 203.0.113.10 skickar ett paket på 1500 byte med DF satt; tystnad betyder att vägen är mindre än du antog.
IPv6 är den andra halvan. Ett nät som delar ut ett nytt prefix ändrar den källa som en dual-stack-klient skulle använda, och en tunnel bara för v4 lämnar v6-trafik utanför tills policyn hinner ikapp. ip -6 route show default och ip -6 addr show svarar på om den nya länken överhuvudtaget har en v6-väg.
Återskapa övergången i stället för att beskriva den
Välj en ofarlig förfrågan och kör samma tre kommandon på båda sidor av ändringen: ip -br addr, ip route show default, ip route get 203.0.113.10. Titta sedan om tunneln fortfarande skickar paket - tcpdump -ni any udp port 51820 för WireGuard, motsvarande port för allt annat. Paket som lämnar den gamla källan betyder ett bindningsproblem. Paket från den nya källan utan svar betyder den bortre sidan eller NAT:en däremellan.
Notera vilken händelse som sammanföll med det första felet: länken nere, adressändring eller ändring av standardrutten. De pekar på olika ansvariga - en klient som måste bindas om, en adress som måste hämtas igen, eller en rutt som hör till en konfigurationsfil och inte till en permanent kringgångsregel.
Innan du kallar det åtgärdat ska du bekräfta att blocket för direkt trafik fortfarande håller under gapet och att namn löses genom den nya anslutningen. Om klienten behåller den gamla slutpunkten efter bytet ska du först rätta roaming- eller float-inställningen. Om den roamar korrekt och fortfarande inte får svar ska du titta på serverns peer-identitet och NAT:en på vägen, och behålla båda nätverkskontexterna i skrivningen så att nästa person kan jämföra dem.