Fuld tunnel i OpenVPN afbryder din SSH-session: ret returvejen
Standardruten sender SSH-svar ind i tunnelen. Fastgør peer, filtrer redirect-gateway, eller rut efter kilde, før du mister maskinen.
At slå en OpenVPN-klient med fuld tunnel til på en maskine, du når over SSH, kan afbryde sessionen inden for et sekund, og maskinen gør intet forkert. Tunnelen ændrer ikke, hvordan pakker når serveren; den ændrer, hvordan svarene forlader den. Når standardruten peger på tun0, går et svar til din SSH-klient ind i udbyderens netværk, som ikke har nogen rute tilbage til din adresse. Forbindelsen hænger, det næste forsøg timer ud, og daemonen lytter stadig på port 22 hele tiden.
Læs routingtabellen, før du læser VPN-loggen. Loggen vil sige, at tunnelen kom op, og den har ret. Spørgsmålet er, hvilken grænseflade hvert svar overdrages til, og det er et opslag per pakke mod en tabel, tunnelen netop har skrevet om.
Hvorfor svaret forlader gennem den forkerte dør
Indgående pakker ankommer stadig på den fysiske grænseflade, fordi en VPN-klient ikke kan ændre, hvordan internettet når din servers offentlige adresse. Svar er en separat beslutning: for hver pakke slår kernen destinationen op, og efter --redirect-gateway siger standardposten tunnel. Udbyderens udgang ser en destination, den ikke betjener, og dropper pakken.
Den beskyttelse, som OpenVPN selv har, dækker præcis én destination. 2.6-manualen beskriver --redirect-gateway som en sekvens: den tilføjer en værtsrute for VPN-peeren gennem den gateway, der blev brugt før tunnelen, så den krypterede trafik ikke kan loope tilbage i sig selv, og erstatter derefter standardruten. Den værtsrute er kun for peeren. Din SSH-klient er bare endnu en internetadresse og får ingen undtagelse.
Én præfiksfejl er værd at udelukke tidligt. ip route add -net 0.0.0.0 gw 10.8.0.1 dev tun0 uden længde matcher den enkelte adresse 0.0.0.0, ikke internettet; den skal være 0.0.0.0/0. Og hvis standardruten ødelægger tunnelens egen transport, tilføj endepunktet som en værtsrute gennem den fysiske grænseflade, med udbyderens rigtige adresse.
Fastgør din SSH-klientadresse for en øjeblikkelig løsning
Den hurtigste reparation er en værtsrute til din klientadresse gennem den gateway, serveren brugte, før tunnelen fandtes. Fra din side: find den adresse, serveren vil se, og læs derefter serverens tabel, så du kender den gamle gateway:
curl -s https://ifconfig.co
ip route
På serveren tilføjer du undtagelsen, før klienten starter. Adresserne her er pladsholdere; formen er det, der betyder noget:
sudo ip route add 80.128.240.55 via 192.168.178.1
Dette er den reparation, der blev brugt i det rapporterede tilfælde, og den virker med det samme. Den er også skrøbelig på to forudsigelige måder: ruten forsvinder ved genstart, og den bliver forkert i det øjeblik, din udbyder giver dig en anden adresse. Behandl den som en nødforanstaltning, og gør den bevidst holdbar via en netværksenhed eller et dispatcher-hook, eller accepter, at den er midlertidig, og skriv gendannelsesvejen ned.
Forhindr klienten i at tage standardruten
Den renere mulighed er at forhindre tunnelen i at erstatte standardruten helt. route-nopull accepterer, brugt med --client eller --pull, push-optioner bortset fra ruter, block-outside-dns og DHCP-lignende optioner som DNS-servere, så du tilføjer kun de præfikser, du har brug for. Et smallere værktøj er et pull-filter, som dropper én problematisk direktiv og beholder resten:
route-nopull
pull-filter ignore "redirect-gateway"
Brug det ene eller det andet, ikke begge, og vær klar over, hvad der ændrer sig. Uden en standardrute gennem tunnelen browser serveren ikke længere internettet gennem udbyderen; den når kun det, du eksplicit har routet. Hvis den fulde tunnel var hele pointen med opsætningen, er dette den forkerte knap, og værtsruten ovenfor er den rigtige.
Del returvejen efter kilde eller forbindelse
Når den indgående adresse er stabil, holder en kilderegel svarene lokale uden at røre tunnelens egne ruter. Giv den fysiske grænseflades adresse sin egen tabel med LAN-præfikset og den fysiske standardrute, og vælg derefter den tabel for trafik, der stammer fra den:
ip rule add from 192.168.1.11 table 128
ip route add table 128 to 192.168.1.0/24 dev eth0
ip route add table 128 default via 192.168.1.1
Det virker, fordi svar på en indgående SSH-forbindelse stammer fra den adresse, klienten oprettede forbindelse til. Et rapporteret tilfælde, hvor hver indgående tjeneste skulle blive ved med at virke, brugte præcis denne form. Når den indgående adresse flyder, eller stien er dynamisk, marker i stedet forbindelsen: sæt et conntrack-mærke på den første pakke fra den fysiske grænseflade, kopiér det til svarpakker i OUTPUT, og rut markerede pakker gennem en tabel, der peger på den fysiske gateway.
iptables -t mangle -A PREROUTING -i eth0 -m conntrack --ctstate NEW -j CONNMARK --set-mark 1234
iptables -t mangle -A OUTPUT -m connmark --mark 1234 -j MARK --set-mark 4321
ip route add default via 192.168.1.1 dev eth0 table 3412
ip rule add fwmark 4321 table 3412
Hold forbindelsesmærke, firewall-mærke og tabelnummer adskilt under test. Genbrug af ét nummer til to roller giver en regel, der ser korrekt ud og matcher de forkerte pakker. Tabellens standardpost kræver også via med LAN-gatewayen på et almindeligt Ethernet-link; en nøgen dev eth0 virker kun, når grænsefladen er punkt-til-punkt, eller næste hop løses på en anden måde. Den rapporterede Jessie-vært sad tilfældigvis på et link, hvor den nøgne form virkede, hvilket ikke er en distributionsregel at kopiere.
Bekræft uden at låse dig selv ude
Test ikke ved at afbryde. Hold den første session åben, bring tunnelen op, og spørg kernen, hvilken vej din egen adresse ville tage:
ip route get 80.128.240.55
Svaret bør nævne den fysiske grænseflade og den gamle gateway, ikke tunnelen. Åbn derefter en anden SSH-forbindelse; det er den rigtige test, fordi den gamle session kan overleve på tilstand, som en ny forbindelse ikke kan genskabe. Hvis den anden hænger, mens den første stadig svarer, har reglen aldrig ramt den trafik, der betyder noget, og mærkerne eller kildeadressen er stedet at kigge.
Hold en out-of-band-konsol tilgængelig under hele øvelsen. En server, hvis eneste adgangsvej er den tunnel, du netop har brækket, kan ikke repareres over den tunnel, og tilbagerulningen er lettere, når du har skrevet tabelnumrene og præfikserne ned, som du tilføjede.