Waarom breekt een tweede VPN-tunnel de eerste?
Een tweede VPN-client installeert twee halve standaardroutes en de eerste tunnel wordt donker: lees welke route wint en splits dan op profiel, tabel of naamruimte.
Een tweede VPN-client installeren om bij één klantnetwerk te komen is de gebruikelijke manier waarop dit begint, en de eerste tunnel wordt donker terwijl beide clients succes melden. Elke client installeerde een standaardroute, de tweede was specifieker, en de kernel volgt die nu voor alles behalve de eigen buitenverbinding van de eerste tunnel. Niets is gecrasht en geen enkel profiel is fout. De ene route verving de andere, en de oplossing is te beslissen welke tunnel de standaard mag bezitten.
Het symptoom: de tweede client wint stil
OpenVPN: de optie redirect-gateway def1 overschrijft 0.0.0.0/0 niet. Hij voegt 0.0.0.0/1 en 128.0.0.0/1 toe: samen dekken ze elk IPv4-adres, en elk prefix verslaat een gewone standaard op lengte. De oorspronkelijke standaard blijft in de tabel staan en wordt niet meer voor gewoon verkeer gebruikt, en een hostroute naar de VPN-server houdt de tunnel ervan af zijn eigen buitenste pakketten te vangen. Beide clients doen dit, en de tweede installeert gewoon zijn paar later.
Daarom lijkt de eerste tunnel dood in plaats van losgekoppeld. De interface staat omhoog, het controlekanaal leeft, en er komt geen applicatieverkeer meer bij. De omgekeerde klacht heeft dezelfde ontbrekende push: een telefoon die verbindt maar niets verstuurt, praat meestal met een server die nooit redirect-gateway aankondigde, dus het apparaat houdt zijn eigen standaard en bereikt alleen de pool.
Maak een routing-snapshot voor en na het verbinden van de tweede client. De twee halve routes die in de tabel verschijnen zijn de hele verandering, en ze verklaren beide klachten. Niets anders in de tabel hoeft te bewegen om het symptoom te laten verschijnen. Daarom herstelt het verwijderen van de tweede client de eerste onmiddellijk.
Lees welke tunnel echt wint
Leid de winnaar niet af uit de volgorde waarin de clients startten of uit het pictogram in de systeemvak. Vraag de kernel welke route hij zou gebruiken voor een bestemming buiten beide privénetwerken, en lees de interface die terugkomt.
ip route show
ip route get 198.51.100.24
route print -4
Find-NetRoute -RemoteIPAddress 198.51.100.24
De eerste twee zijn het Linux-antwoord en de laatste twee het Windows-equivalent. Voer ze uit terwijl beide tunnels omhoog staan, verbreek dan één en voer ze opnieuw uit. Het verschil tussen de twee uitvoer is het feit dat je nodig hebt voordat je een oplossing kiest, en het kost minder tijd dan het log van een van beide clients lezen.
Noteer het resultaat, inclusief de interfacenaam en het prefix dat overeenkwam. Een ticket dat zegt dat de tweede VPN de eerste brak, is een beschrijving van het symptoom, geen routeringsuitspraak waar iemand op kan handelen. De opzoeking maakt er een feit van dat de volgende engineer met één commando kan reproduceren.
Windows: voorkom dat één profiel de standaard bezit
Windows bewaart opgeslagen profielen, en de ingebouwde client laat het ene van het andere afhangen zodat de eerste automatisch omhoogkomt wanneer de tweede inbelt. Het profiel dat het laatst verbond, houdt meestal de standaard, dus de praktische eigenaar is de laatste inbelverbinding en niet de eerste. Geef elk profiel zijn eigen push-routes en zet split tunneling aan voor het profiel dat de standaard niet mag bezitten.
Set-VpnConnection -Name "Contoso" -SplitTunneling $true
rasdial Contoso
Split tunneling verandert dat: alleen door de server gepushte prefixen komen in de tabel, wat de standaard bij de eerste tunnel laat. Het ontwerp faalt nog steeds als beide servers een standaardroute pushen, want dan wint de laatste verbinding en geen enkele instelling aan de clientkant verandert dat. Repareer de push aan de serverkant of accepteer één eigenaar.
App-gestuurde profielen zijn een andere functie en de moeite waard te kennen: een Windows-profiel kan starten wanneer een genoemd uitvoerbaar bestand begint, waarbij verkeersfilters beslissen wat het draagt. Dat is een profielinstelling en geen firewallregel, en het lost een ander probleem op dan het conflict om de standaardroute.
Linux: houd de tweede tunnel buiten de hoofdtabel
Twee openvpn --config-instanties op één machine draaien zet beide clients in dezelfde tabel, en drie opties scheiden ze met toenemende isolatie. De lichtste is de tweede client de tabel helemaal niet laten bewerken, met route-nopull en expliciete routes, of een route-up-script dat alleen installeert wat je bedoelt. Dan draagt de tweede tunnel precies de prefixen die je noemt en niets anders. Dan beslis je welke prefixen waarheen gaan in plaats van het achteraf te ontdekken.
Policy-routing is de middelste optie. Een regel kiest een aparte tabel voor één bronadres of firewallmarkering, en die tabel draagt de routes van de tweede tunnel. Reverse-path-filtering is hier de valkuil, want een antwoord dat op een andere interface aankomt dan de tabel zou kiezen, wordt weggegooid, dus controleer de instelling rp_filter voordat je concludeert dat de tunnel stuk is.
ip rule add from 10.44.7.0/24 table 100
ip route add default dev tun1 table 100
sysctl net.ipv4.conf.all.rp_filter
Netwerk-naamruimten zijn de zwaarste en schoonste optie. Start de tweede client binnen ip netns, geef hem een veth-paar en ga die naamruimte in om hem te gebruiken. Storingen verdwijnen omdat elke naamruimte eigen tabellen bezit in plaats van er één te delen, wat de extra opzet waard is wanneer beide tunnels weken omhoog moeten blijven.
Per applicatie, en ketenen als een apart probleem
Soms mag alleen één programma de tweede tunnel gebruiken. Op Linux bereikt policy-routing per gebruiker, cgroup of poort dat resultaat, en één bestemming kan aan een interface worden vastgezet zonder de standaard überhaupt aan te raken. Een applicatie die zijn socket aan één interface vastzet, raadpleegt de routingtabel helemaal niet, dus een launcher kan het fysieke adapter blijven gebruiken tot een adres in zijn eigen instellingen wordt gekozen.
Ketenen is een andere bewerking dan twee tunnels naast elkaar draaien. A over B ketenen betekent dat het adres van de binnenste server bereikbaar moet zijn van binnen de buitenste tunnel. De buitenste client mag de versleutelde pakketten van de binnenste client ook niet voor een lek aanzien. Eén client in een virtuele machine is de grove maar betrouwbare versie; beide op één host vereisen het routeringswerk hierboven plus een buitenpad naar de binnenste server dat nooit de binnenste tunnel in gaat.
Schrijf de eigenaar van de standaard op, de prefixlijst die elke tunnel draagt, en het DNS-pad. Die drie feiten maken het volgende incident een opzoeking in plaats van een onderzoek.