Je kiest een server die dichterbij lijkt, drukt op verbinden, en de browser stopt met laden voordat de nieuwe tunnel staat. Het pictogram springt naar een verbindingsstatus en blijft daar terwijl elk tabblad afloopt. Die pauze is meestal de kill switch die werkt zoals bedoeld: het verkeer is geblokkeerd zolang de client geen tunnel heeft om het door te sturen. Of de pauze aanvaardbaar is, hangt af van wat de client in die seconden doet en of de blokkade wordt opgeheven wanneer hij zegt dat het zo is.

Wat de client tussen twee servers doet

Een wissel van eindpunt is meerdere stappen, niet één schakelaar. De client breekt de huidige tunnel af, werkt zijn blokkeerregels bij, lost het nieuwe eindpunt op en bereikt het buiten de tunnel, en installeert daarna de nieuwe routes en heft de blokkade op. De opening die je voelt zit tussen de eerste en de laatste stap.

De volgorde is hier belangrijker dan de snelheid. Als de blokkeerregels ingaan voordat de uitzondering voor het nieuwe eindpunt bestaat, kan de client de handshake niet afronden en blijft hij op verbinden staan tot een time-out. Als de uitzondering een kopie van het adres van de oude server is, ziet de nieuwe handshake eruit als elk ander uitgaand pakket en wordt hij weggegooid. Beide gevallen zien er in de browser hetzelfde uit, en daarom kunnen een wissel die na zes seconden herstelt en een die nooit herstelt dezelfde oorzaak hebben.

Het nieuwe eindpunt heeft een gat in de blokkade nodig

Om de tunnel te bouwen moet de client pakketten naar het adres en de poort van de nieuwe server sturen via de fysieke interface, bijvoorbeeld UDP 51820 voor een typisch WireGuard-profiel of 1194 en 443 voor OpenVPN, wat je eigen profiel ook voorschrijft. Dat verkeer zit niet in de tunnel die op het punt staat te ontstaan, dus een blokkade voor het hele apparaat slikt het in tenzij er een passende toestemmingsregel bestaat.

Profielen op basis van hostnaam voegen een tweede vereiste toe: de opzoeking zelf. Als de client het eindpunt oplost voordat de blokkade omhooggaat, kan hij een gecachet adres gebruiken, maar zodra het profiel adressen roteert of de cache-entry veroudert, gaat de handshake naar een adres dat de toestemmingsregel niet dekt. IPv6 maakt dat zichtbaar, omdat een eindpunt met dubbele stack zowel een A- als een AAAA-record kan publiceren, en een toestemmingsregel die alleen het v4-adres dekt de client laat blijven proberen tegen een geblokkeerd v6-adres.

Namen van opties en standaardwaarden verschillen per client en versie, dus lees de gedocumenteerde lijst voor de jouwe in plaats van te gokken op basis van schermafbeeldingen. De instellingenreferentie van OpenVPN Connect op openvpn.net/connect-docs/app-settings-windows is een voorbeeld van hoe een client zijn blokkeer- en split-tunnelopties beschrijft.

Fail-closed is een toestandsmachine, geen schakelaar

De meeste clients drukken de blokkade uit als firewallbeleid in drie toestanden: tunnel omhoog, met verkeer door de tunnel en geen blokkade; tunnel omlaag, met de blokkade actief; en overgang, met de blokkade actief plus tijdelijke uitzonderingen voor het eindpunt. In de derde toestand wonen de bugs, want die moet binnen een paar seconden twee keer veranderen, en er niet uit komen ziet er precies zo uit als een permanente blokkade.

Het mechanisme verschilt per platform, en de fout ook. Filters van Windows Filtering Platform hebben gewichten, dus een blokkeerfilter dat je toestemming overstemt blijft pakketten weggooien ook al bestaat de toestemming, en filters die een gedood clientproces heeft achtergelaten kunnen de machine offline houden nadat de app weg is. macOS-clients schrijven pf-regels meestal in een anchor, waar regelvolgorde en snelle beslissingen bepalen welke regel geldt. Linux-clients beheren meestal een nftables- of iptables-keten met drop-beleid en expliciete toestemmingen voor het eindpunt, de tunnelinterface en loopback. De always-on VPN van Android met de optie verbindingen zonder VPN te blokkeren is de strengste van de groep, omdat het besturingssysteem de blokkade op het hele apparaat toepast en niet per app.

WireGuard verdient een eigen opmerking, want AllowedIPs is een routekeuze, geen blokkering. Het bepaalt welke bestemmingen de tunnel in gaan; het doet niets om te voorkomen dat een pakket zonder tunnel via Wi-Fi naar buiten gaat. In een opstelling met alleen WireGuard en zonder firewallregel is de kill switch in werkelijkheid het ontbreken van een route, en na een weggegooide handshake kan een echt pakket via de fysieke interface naar buiten gaan.

Meet de opening in plaats van naar het pictogram te kijken

Let op pakketten, niet op het statuslampje. Start op Linux in het ene terminal een langzame ping naar een openbaar adres en vang in het andere de transportpoort van de tunnel op de fysieke interface:

ping -i 0.2 -c 100 1.1.1.1 | tail -5

sudo tcpdump -ni eth0 'udp port 51820'

Wissel van server in de client terwijl beide draaien. Drie dingen tellen: hoe lang de pings stoppen, of de opname laat zien dat de handshake het nieuwe eindpunt bereikt, en of het verkeer terugkomt voordat of nadat de status van de client op verbonden springt. Als de ping-opening het eerst eindigt, is de blokkade of te vroeg opgeheven of staat de tunnel al voordat de indicator het toegeeft. Als de opening later eindigt, is de indicator optimistisch.

Op Windows schrijft netsh wfp show state een momentopname waarin je kunt zoeken naar blokkeerfilters die er nog zijn terwijl de client beweert losgekoppeld te zijn. Op macOS somt sudo pfctl -sr de geladen regels en hun volgorde op. Koppel een van beide momentopnamen aan het eigen log van de client; de tijdlijn uit je ping vertelt of de blokkade laat eindigde of nooit.

Normale black-out tegenover een vastgelopen blokkade

Enige onderbreking is het doel van de functie, dus triage voordat je een instelling wijzigt:

What you seeUsually meansNext check
Two or three seconds of timeouts, then normal browsingExpected fail-closed gapNothing to fix
State says connected, traffic stays deadBlock filter or route left behindFirewall snapshot, client log
One app dead while others workTCP session bound to the old exit addressRestart the app
LAN devices unreachable after the switchLAN exception not reappliedAllow-LAN or split-tunnel setting
New server hangs, the old one reconnectsPermit covers only the old addressResolved address of the new host, including AAAA

Kom je in de tweede of vijfde rij uit, schakel de kill switch dan niet uit om te testen, want dat maakt van een routefout een lek. Herstart de dienst van de client, of herstart de machine waar filters het doden van een proces overleven, en kijk dan of de blokkade verdwijnt. Gebeurt dat, dan zit de fout in het opruimen tijdens de wissel en niet in de blokkade zelf.

Bevestig voor je volgende wissel vier dingen: de toestemming voor het eindpunt dekt elke adresfamilie die je profiel oplost, het clientlog toont de voltooide overgang, je pingtest meet de opening en niet het pictogram, en het afsluiten van de client herstelt de normale verbinding. Een kill switch die tijdens de wissel standhoudt en daarna loslaat, doet zijn werk. Een die vroeg loslaat, of nooit, is het debuggen waard.

Gerelateerde artikelen