Symtomen följer ett mönster: en värd fungerar, sedan ansluter den till en VPN som klient, och nu når LAN-klienter den medan svaren försvinner. En avlyssning på värden visar att svaren lämnar genom tunneleenheten i stället för LAN-gränssnittet. Inget i tunneln är trasigt, och åtgärden är en rutt, inte en återanslutning. Gå igenom de fyra kontrollerna nedan i ordning och stanna vid den första som misslyckas.

Ett svar är ett nytt paket, inte en återgång

Det hjälper att släppa tanken att ett svar reser tillbaka längs den väg en förfrågan tog. Routning avgörs per paket, per riktning, på värden som skickar. En förfrågan som kom från 10.64.0.23 inne i tunneln skapar ingen returväg; när värden svarar jämförs svaret med tabellen som ett nytt paket och lämnar genom den rutt som vinner.

Därför ger en klient med full tunnel på en maskin som också betjänar ett LAN ett så förvirrande fel. Klienten installerar en standardrutt, eller de två halva standardrutterna som vissa klienter föredrar, och svaret till en LAN-klient matchar nu tunneln. Det går till leverantören, som inte har någon anledning att vidarebefordra det, och LAN-klienten ser en tidsgräns trots att värden är uppe och svarar lokalt. Avlyssningen gör det uppenbart, och rutttabellen förklarar det.

Håll två subnät i minnet medan du läser resten. Det ena är VPN-adresspoolen som fjärrklienterna kommer från, i det här exemplet 10.64.0.0/24. Det andra är LAN:et som måste fortsätta fungera, 172.16.24.0/24 med sin router på 172.16.24.1. Felet är att trafiken mellan dem avgörs av standardrutten.

Bevisa det med avlyssningen och uppslaget

Innan du ändrar något, bekräfta vilken enhet svaret kommer att använda. Ett uppslag är snabbare än en avlyssning och svarar på exakt den fråga som kärnan svarar på när paketet byggs.

ip route get 10.64.0.23 from 172.16.24.10
tcpdump -ni any -c 6 icmp

Läs svaret i två delar. Om det nämner dev tun0 kommer värden att kapsla in svaret och lämna det till leverantören, och LAN-klienten kommer aldrig att se det. Om det nämner dev eth0 men klienten ändå får en tidsgräns är rutten redan korrekt och paketet kastas senare, vilket är ett annat problem med en annan åtgärd.

Avlyssningen i samma steg avgör det tvivel som ett ping inte kan. Ett eko-svar som når LAN-klienten bevisar att någon väg fungerar, inte vilket gränssnitt som bar det, så kör avlyssningen på värden själv och se var ramarna lämnar. En skrivare i samma subnät fortsätter att svara, eftersom dess direkta rutt är mer specifik än tunnelns standardrutt. En vidarebefordrad port misslyckas precis som vilket annat flöde som helst, eftersom tabellen väljer gränssnittet och anslutningen inte.

Installera den smalaste rutt som överträffar tunneln

Prefixlängden avgör, inte metriken, så en rutt för klientpoolen via LAN-routern vinner över varje standardrutt som VPN-klienten installerar. Metrikkirurgi behövs inte, och standardrutten kan bli kvar precis där klienten satte den.

ip route replace 10.64.0.0/24 via 172.16.24.1 dev eth0
ip route get 10.64.0.23 from 172.16.24.10

Använd replace i stället för add, eftersom en klient som återansluter redan har installerat sin egen post och en andra add misslyckas med ett fel om att rutten finns, vilket läses som ett behörighetsproblem. På en Windows-värd är motsvarigheten route add 10.64.0.0 mask 255.255.255.0 172.16.24.1 -p, där -p behåller posten över omstarter, eftersom klienten kan bygga om tabellen när tunneln kommer upp igen. På en modern Windows-värd är den stödda motsvarigheten New-NetRoute -DestinationPrefix 10.64.0.0/24 -NextHop 172.16.24.1 -InterfaceAlias Ethernet -PolicyStore PersistentStore, medan det äldre route-kommandot behålls som en äldre form.

En detalj avgör om detta är korrekt eller bara trovärdigt: nästa hopp måste vara routern som faktiskt äger vägen tillbaka till klienterna. Att rikta rutten mot en adress som själv nås genom tunneln skapar en slinga som visar sig som intermittent förlust i stället för ett rent fel. Bekräfta att nästa hopp ligger i LAN-subnätet innan du bekräftar raden.

Behåll svaret efter en återanslutning

En rutt som lagts till för hand överlever i bästa fall till nästa återanslutning. Om klientpoolen är dynamisk, fäst den i serverkonfigurationen så att prefixet du routade förblir det prefix klienterna får; annars pekar posten på ett tomt intervall och symtomet återkommer veckor senare utan uppenbar orsak. Att skriva rutten i klientens eget up-skript är det andra pålitliga alternativet, eftersom det körs efter att klienten har skrivit om tabellen.

En tillståndsbaserad brandvägg kan fortfarande besegra en korrekt rutt. Om avlyssningen nu visar att svaret lämnar genom eth0 och klienten fortfarande får en tidsgräns, kontrollera om värden kastar paketet innan det skickas. Strikt omvänd vägfiltrering och net.ipv4.conf.all.rp_filter satt till 1 kastar paket vars källa inte skulle routas tillbaka genom det gränssnitt de kom in på, och det är precis det asymmetriska fallet du just skapade och sedan åtgärdade, och conntrack-tillståndet berättar samma historia för vidarebefordrade portar.

Den sista kontrollen är den folk hoppar över: upprepa uppslaget efter att tunneln varit nere och kommit upp igen. Fyra värden ska stämma med det du skrev ned: destinationen, nästa hopp, enheten och den valda källan. Om något av dem har flyttat sig har klienten skrivit om tabellen och åtgärden hör hemma i dess krokar och inte i en shell-historik.

Relaterade artiklar