OpenVPN-klienten går i stå, når dens server kører på samme vært
To OpenVPN-instanser på én vært kæmper om den samme lokale port og routingtabel. Fastgør porten, del enhederne, og kontroller, hvilken tabel der vinder.
Jeg havde en laboratoriemaskine, der tog imod en tunnel fra et eksternt sted og også ringede ud til et leverandørnetværk. Den udgående profil havde virket i uger. Efter at den indgående server blev tilføjet, oprettede den udgående forbindelse og stoppede derefter med at sende trafik inden for få sekunder, eller nægtede at starte med en adresse-i-brug-fejl. Konfigurationsfilerne var ikke ændret; værten havde blot fået en anden OpenVPN-proces med sin egen mening om porte og ruter.
Fejlen er ikke tilfældig, og det er ikke et godkendelsesproblem. To daemoner på én maskine konkurrerer om den samme lokale socket og den samme routingtabel, og den, der starter eller genopretter forbindelse sidst, vinder som regel. At vide, hvilket af de to sammenstød du har, afgør, hvor du skal kigge først.
Læs symptomet baglæns
Start med hvornår tunnelen dør. En bind-fejl ved opstart peger på lyttesiden: noget ejer allerede den port, og OpenVPN nægter at starte i stedet for at dele den. En tunnel, der kommer op og derefter bliver stille, peger på routing, fordi en rute installeret af den anden instans kan trække den ydre forbindelses pakker af deres vej.
Begge tilfælde giver den samme brugerklage, og derfor løser genforsøgsløkker og watchdog-scripts intet. De genopretter klienten til den samme konflikt. Det nyttige første spørgsmål er, om processen stadig kører, når trafikken stopper.
Én socket og én enhed per instans
En lyttende server binder sin port; en udgående klient har også brug for en lokal port til sin indkapslede trafik. Når begge bor på samme vært, kan klientens standardadfærd støde sammen med serverens port. Klientens lokale port kan fastgøres, og binding kan springes over, hvor modparten ikke har brug for en fast kildeport:
lport 1195
nobind
dev tun1Disse tal er eksempler, ikke et krav. Det afgørende er, at klienten holder op med at konkurrere om serverens port, og at hver instans får en separat tunneienhed. To daemoner, der deler tun0, overskriver hinandens enhedstilstand, selv når deres porte er forskellige, så én enhed per tunnel er ikke valgfrit.
nobind hører til klientsiden. En server skal stadig binde og lytte, så kopiér ikke linjen til serverkonfigurationen, og deaktiver ikke binding på en klient, hvis modpart filtrerer på en fast kildeport.
Vælg én ejer til standardruten
Kun én forbindelse kan installere en standardrute. Hvis begge profiler omdirigerer al trafik, erstatter den anden forbindelse lydløst den første, og den første ser ud til at gå i stykker. Enten hold den udgående tunnel opdelt og push kun leverandørpræfikserne, eller giv den en separat routingtabel.
ip rule add from 10.9.0.2 table 120
ip route add default dev tun1 table 120
ip route get 10.9.0.2Adresserne og tabelnummeret ovenfor er pladsholdere. Bekræft straks efter tilføjelsen af reglen, at VPN-serverens egen adresse stadig opløses gennem den normale tabel; en tabel, der fanger den ydre transport, ødelægger den tunnel, den skulle beskytte, og den efterfølgende genopretningsløkke ligner en upålidelig udbyder.
For en opsætning, der skal overleve genoprettelser og genstarter, er et netværksnamespace den mere robuste grænse. Den anden klient kører inde i sit eget namespace med sine egne interfaces og ruter, og kun de tjenester, der skal krydse, eksponeres. Værten beholder én standardrute, og en namespace-genoprettelse kan ikke overskrive den.
Kontroller med tabellen, ikke statuslinjen
En klient, der rapporterer, at den er forbundet, beviser kun sin kontrolkanal. Optag routingtilstanden før og efter hver forbindelse, og spørg derefter kernen, hvilken enhed en rigtig destination ville bruge:
ip route show
ip route get 10.40.0.20
ss -lunp | grep 1194Hvis den valgte enhed til leverandøradressen ændrer sig, når den anden tunnel starter, har du rute-kollisionen. Hvis begge processer dukker op på den samme lokale port, har du socket-kollisionen. At rette den første uden den anden flytter bare fejlen til den næste genoprettelse.
Skriv portene, enhederne, tabellerne og ruteejeren ind i værtens runbook. Ellers vil den næste person, der tilføjer en tredje tunnel, genopdage den samme kollision, og det eneste synlige bevis vil være en forbindelse, der virker, indtil en andens daemon genstarter.