OpenVPN-client stopt wanneer zijn server op dezelfde host draait
Twee OpenVPN-instanties op één host vechten om dezelfde lokale poort en dezelfde routetabel. Zet de poort vast, splits de apparaten en controleer welke tabel wint.
Ik had een labmachine die een tunnel van een externe locatie accepteerde en ook uitbelde naar een leveranciersnetwerk. Het uitgaande profiel werkte wekenlang. Nadat de inkomende server was toegevoegd, verbond de uitgaande en stopte daarna binnen enkele seconden met het doorgeven van verkeer, of weigerde te starten met een fout dat het adres al in gebruik is. De configuratiebestanden waren niet veranderd; de host had gewoon een tweede OpenVPN-proces gekregen met zijn eigen mening over poorten en routes.
De storing is niet willekeurig, en het is geen authenticatieprobleem. Twee daemons op één machine concurreren om dezelfde lokale socket en dezelfde routetabel, en degene die het laatst start of opnieuw verbindt, wint meestal. Weten welke van die twee botsingen je hebt, bepaalt waar je eerst moet kijken.
Lees het symptoom achterstevoren
Begin bij wanneer de tunnel sterft. Een bindfout bij het starten wijst op de luisterkant: iets bezit die poort al, en OpenVPN weigert te starten in plaats van hem te delen. Een tunnel die opkomt en daarna stil wordt, wijst op routing, omdat een route die door de andere instantie is geïnstalleerd de pakketten van de buitenste verbinding van hun pad kan trekken.
Beide gevallen leveren dezelfde gebruikersklacht op, daarom lossen herhaalpogingen en watchdog-scripts niets op. Ze verbinden de client opnieuw in hetzelfde conflict. De nuttige eerste vraag is of het proces nog draait wanneer het verkeer stopt.
Eén socket en één apparaat per instantie
Een luisterende server bindt zijn poort; een uitgaande client heeft ook een lokale poort nodig voor zijn ingekapselde verkeer. Wanneer beide op dezelfde host leven, kan het standaardgedrag van de client botsen met de poort van de server. De lokale poort van de client kan worden vastgezet, en binden kan worden overgeslagen waar de tegenpartij geen vaste bronpoort nodig heeft:
lport 1195
nobind
dev tun1Die getallen zijn voorbeelden, geen vereiste. Wat telt is dat de client stopt met concurreren om de poort van de server en dat elke instantie een apart tunnelapparaat krijgt. Twee daemons die tun0 delen, overschrijven elkaars apparaatstatus zelfs wanneer hun poorten verschillen, dus één apparaat per tunnel is niet optioneel.
nobind hoort bij de clientkant. Een server moet nog steeds binden en luisteren, dus kopieer de regel niet naar de serverconfiguratie, en schakel binden niet uit op een client waarvan de tegenpartij op een vaste bronpoort filtert.
Kies één eigenaar voor de standaardroute
Slechts één verbinding kan een standaardroute installeren. Als beide profielen al het verkeer omleiden, vervangt de tweede verbinding stilzwijgend de eerste, en de eerste lijkt te breken. Houd de uitgaande tunnel gesplitst en stuur alleen de leveranciersprefices, of geef hem een aparte routetabel.
ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2De adressen en het tabelnummer hierboven zijn plaatsaanduidingen. Bevestig onmiddellijk na het toevoegen van de regel dat het adres van de VPN-server zelf nog steeds via de normale tabel wordt opgelost; een tabel die het buitenste transport vangt, breekt de tunnel die hij moest beschermen, en de herverbindingslus die volgt lijkt op een onbetrouwbare provider.
Voor een opstelling die herverbindingen en herstarts moet overleven, is een netwerknamespace de steviger grens. De tweede client draait in zijn eigen namespace met zijn eigen interfaces en routes, en alleen de diensten die moeten oversteken worden blootgesteld. De host houdt één standaardroute, en een namespace-herverbinding kan die niet herschrijven.
Controleer met de tabel, niet met de statusregel
Een client die meldt dat hij verbonden is, bewijst alleen zijn controlekanaal. Leg de routestatus vast voor en na elke verbinding en vraag de kernel vervolgens welk apparaat een echte bestemming zou gebruiken:
ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194Als het gekozen apparaat voor het leveranciersadres verandert wanneer de tweede tunnel start, heb je de routebotsing. Als beide processen op dezelfde lokale poort verschijnen, heb je de socketbotsing. Het eerste oplossen zonder het tweede verplaatst de storing alleen naar de volgende herverbinding.
Schrijf de poorten, apparaten, tabellen en route-eigenaar in de runbook van de host. Anders zal de volgende persoon die een derde tunnel toevoegt dezelfde botsing opnieuw ontdekken, en het enige zichtbare bewijs is een verbinding die werkt tot iemand anders daemon herstart.