OpenVPN-klienten fastnar när servern körs på samma värd
Två OpenVPN-instanser på en värd slåss om samma lokala port och samma routingtabell. Fäst porten, dela upp enheterna och kontrollera vilken tabell som vinner.
Jag hade en laboratoriemaskin som tog emot en tunnel från en avlägsen plats och även ringde ut till ett leverantörsnätverk. Den utgående profilen hade fungerat i veckor. Efter att den inkommande servern lades till anslöt den utgående och slutade sedan skicka trafik inom några sekunder, eller vägrade starta med ett fel om att adressen redan används. Konfigurationsfilerna hade inte ändrats; värden hade helt enkelt fått en andra OpenVPN-process med sin egen åsikt om portar och rutter.
Felet är inte slumpmässigt, och det är inte ett autentiseringsproblem. Två daemoner på en maskin konkurrerar om samma lokala socket och samma routingtabell, och den som startar eller återansluter sist vinner vanligtvis. Att veta vilken av dessa två kollisioner du har avgör var du ska titta först.
Läs symptomet baklänges
Börja med när tunneln dör. Ett bind-fel vid start pekar på lyssningssidan: något äger redan den porten, och OpenVPN vägrar starta i stället för att dela den. En tunnel som kommer upp och sedan tystnar pekar på routing, eftersom en rutt som installerats av den andra instansen kan dra den yttre anslutningens paket från deras väg.
Båda fallen ger samma användarklagomål, vilket är varför återförsöksloopar och watchdog-skript inte fixar något. De återansluter klienten till samma konflikt. Den användbara första frågan är om processen fortfarande körs när trafiken stannar.
En socket och en enhet per instans
En lyssnande server binder sin port; en utgående klient behöver också en lokal port för sin inkapslade trafik. När båda lever på samma värd kan klientens standardbeteende kollidera med serverns port. Klientens lokala port kan fästas, och bindning kan hoppas över där motparten inte behöver en fast källport:
lport 1195
nobind
dev tun1De siffrorna är exempel, inte ett krav. Det som spelar roll är att klienten slutar konkurrera om serverns port och att varje instans får en egen tunnelenhet. Två daemoner som delar tun0 skriver över varandras enhetsstatus även när deras portar skiljer sig, så en enhet per tunnel är inte valfritt.
nobind hör till klientsidan. En server måste fortfarande binda och lyssna, så kopiera inte raden till serverkonfigurationen, och inaktivera inte bindning på en klient vars motpart filtrerar på en fast källport.
Välj en ägare för standardrutten
Bara en anslutning kan installera en standardrutt. Om båda profilerna omdirigerar all trafik ersätter den andra anslutningen tyst den första, och den första verkar gå sönder. Antingen håller du den utgående tunneln delad och skickar bara leverantörens prefix, eller så ger du den en egen routingtabell.
ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2Adresserna och tabellnumret ovan är platshållare. Bekräfta omedelbart efter att regeln lagts till att VPN-serverns egen adress fortfarande löses via den vanliga tabellen; en tabell som fångar den yttre transporten bryter tunneln den skulle skydda, och återanslutningsloopen som följer ser ut som en opålitlig leverantör.
För en installation som måste överleva återanslutningar och omstarter är ett nätverksnamnrymd den stabilare gränsen. Den andra klienten körs i sin egen namnrymd med egna gränssnitt och rutter, och bara de tjänster som måste korsa gränsen exponeras. Värden behåller en standardrutt, och en namnrymdsåteranslutning kan inte skriva om den.
Verifiera med tabellen, inte statusraden
En klient som rapporterar att den är ansluten bevisar bara sin kontrollkanal. Fånga routingtillståndet före och efter varje anslutning och fråga sedan kärnan vilken enhet en verklig destination skulle använda:
ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194Om den valda enheten för leverantörsadressen ändras när den andra tunneln startar har du ruttkollisionen. Om båda processerna dyker upp på samma lokala port har du socketkollisionen. Att fixa den första utan den andra flyttar bara felet till nästa återanslutning.
Skriv portarna, enheterna, tabellerna och ruttägaren i värdens runbook. Annars kommer nästa person som lägger till en tredje tunnel att återupptäcka samma kollision, och det enda synliga beviset blir en anslutning som fungerar tills någon annans daemon startar om.