Jag tillbringade en förmiddag med en tunnel som kom upp rent och flyttade trafik åt exakt ett håll: filialen nådde filservern på huvudkontoret, och varje anslutning som öppnades från huvudkontoret in i filialen dog vid första SYN. SA:erna var uppe, tunneltäljarna steg och handskakningen var aldrig problemet. Svaret routades någonstans som tunneln inte täcker, och det valet tillhör den bortre sidan. Ett plats-till-plats-VPN transporterar bara de paket som en värd lämnar till gatewayen, och varje värd gör det valet separat, i varje riktning, från sin egen routingtabell.

Båda riktningarna routas var för sig

IP minns ingenting om riktningen på ett samtal. Varje värd som skickar ett paket gör sin egen sökning på längsta prefix, väljer ett nästa hopp och glömmer beslutet. Förfrågan och svaret är två oberoende paket som råkar höra till samma anslutning, och tunneln är ett hopp som vilket som helst av dem kan använda eller inte. Ingenting i IKE-utbytet lär den bortre servern hur den når ditt subnät; förhandlingen kommer bara överens om vilka prefix som får krypteras.

Den överenskommelsen är den andra porten. I strongSwan är trafikselektorerna leftsubnet och rightsubnet, och ett paket vars källa eller mål faller utanför det förhandlade paret krypteras inte, vad routingtabellen än säger. Ett prefix som routas in i tunneln men saknas i selektorerna är ett tyst enkelriktat fel: rutten ser rätt ut, paketet går ändå ut i klartext eller slängs, och bara charon-loggen klagar.

Den bortre värden vet ingenting om din tunnel

Inne i det bortre LAN:et är svaret ett vanligt paket adresserat till din klient. Destinationsvärden ser ingen IPsec-rubrik och har ingen anledning att föredra VPN-gatewayen; den slår upp ditt prefix, hittar inget mer specifikt än sin standardrutt och följer den. Om standardrutten pekar på en kärnbrandvägg har brandväggen antingen en rutt tillbaka in i tunneln eller inte. När den inte har det får du ett tyst tapp, en ICMP unreachable eller ett svar som går ut via det internetvända gränssnittet och dör.

Ett andra gränssnitt räcker för att bryta detta även när en rutt finns. En NAS med hanteringslänk på ett annat VLAN, en server med backup-uplink, en policyregel som skickar ett källområde till en andra tabell: vilket som helst av dessa kan fånga svaret. På Linux visar ip rule show och ip route show table all regler och tabeller som standardlistningen döljer.

Läs beslutet på maskinen som skickar svaret

Fråga kärnan innan du ändrar något, och ge den källadressen, eftersom källberoende regler ändrar svaret.

ip route get 10.10.5.10 from 10.20.30.15
ip rule show
ip route show table all
ss -tn state established "( sport = :445 )"

Utdata namnger det utgående gränssnittet och nästa hopp. Om gränssnittet inte är det som vetter mot VPN-gatewayen har du hittat felet, och det som återstår är att välja var rutten hör hemma. En ping från gatewayen bevisar lite här: den svarar med en adress som den bortre värden kan placera, inte med adressen till din laptop.

På Windows är motsvarigheterna Find-NetRoute -RemoteIPAddress 10.10.5.10 för beslutet och Get-NetRoute för tabellen. En rutt som läggs till med New-NetRoute och har högre metrik än standardrutten förlorar tyst, så läs metrikkolumnen, inte posten. Bekräfta sedan med paket: tcpdump -ni any "host 10.10.5.10 and tcp port 445" på det bortre LAN-gränssnittet visar förfrågan, och samma filter på tunnelsidan visar om ett svar kom tillbaka. Förfrågan synlig utan svar betyder att svaret routades någon annanstans eller slängdes; ett svar på fel gränssnitt ger dig boven innan du rör en rutt.

När serverns gateway inte är VPN-ändpunkten

Många platser sätter en brandvägg mellan servrarna och koncentratorn. Den brandväggen vidarebefordrar svaret, så den behöver en rutt för ditt klientprefix mot VPN-gatewayen, och vidarebefordringspolicy i båda riktningarna. Tillståndskänsliga enheter gör det värre: förfrågan korsade brandväggen från en LAN-värd som den tillät, svaret kommer nu från en annan riktning, och posten för anslutningsspårning stämmer inte längre, så paketet kastas som ogiltigt i stället för nekat. Därför ser policyloggen tom ut medan trafiken försvinner.

Gatewayen har sin egen andra filter. Linux omvänd vägfiltrering kastar paket vars källa inte är nåbar via det gränssnitt de kom in på, och det är exakt formen av en legitim asymmetrisk returväg. strongSwans vägledning för vidarebefordran kräver net.ipv4.ip_forward och en uppmjukad net.ipv4.conf.all.rp_filter just därför. Ett strikt värde på 1 på endera gatewayen bryter tyst en korrekt rutt, och nstat -az visar tappen om du vet var du ska titta.

SymptomWhere the reply is most likely lost
Gateway ping works, LAN host silentSource address the far host cannot place in its table
SYN arrives, no SYN-ACK, tunnel counters flatNo route to the client prefix on the far host or its gateway
Reply counted on the internet-facing interfaceDefault route or policy rule on the far host
Firewall reports invalid stateAsymmetric path through a stateful device
Worked until a link failed overNew path is asymmetric, or rp_filter now rejects it

Routa eller översätt, och verifiera sedan i båda riktningarna

De två reparationerna är inte likvärdiga. Att lägga till en rutt håller klientadressen intakt, så källbaserade regler, revisionsloggar och applikationer som registrerar den som ringer fortsätter att fungera; priset är att varje hopp som fattar beslutet behöver rutten, vilket är fler ställen att ha fel på. Maskering på den bortre gatewayen krymper returvägen till ett hopp, eftersom svaret nu är adresserat till gatewayen själv, och döljer vilken klient som gjorde vad.

iptables -t nat -A POSTROUTING -o eth1 -s 10.20.30.0/24 -j MASQUERADE

Välj det medvetet: när klienterna väl framstår som gatewayens adress slutar källbaserade ACL:er att skilja dem åt, och conntrack måste hålla mappningen så att svaret skrivs tillbaka in i tunneln. Om selektorerna fortfarande utesluter klientprefixet ändrar NAT ingenting, eftersom förfrågan aldrig kom in i tunneln.

Innan du kallar det reparerat, bekräfta fyra saker i ordning: rutten på värden som skickar svaret, rutten på varje hopp som vidarebefordrar det, selektorerna som täcker båda prefixen, och en inspelning som visar svaret gå in i tunneln med den källa du förväntar dig. Upprepa sedan testet från den andra platsen. En riktning som passerar är en halvöppen design, och den andra riktningen misslyckas oftast av en annan orsak än den du just reparerade.

Relaterade artiklar