Tunelul complet OpenVPN îți taie sesiunea SSH: repară calea de întoarcere
Ruta implicită trimite răspunsurile SSH în tunel. Fixează peer-ul, filtrează redirect-gateway sau rutează după sursă înainte de a pierde mașina.
Pornirea unui client OpenVPN cu tunel complet pe o mașină la care ajungi prin SSH poate întrerupe sesiunea într-o secundă, iar mașina nu face nimic greșit. Tunelul nu schimbă modul în care pachetele ajung la server; schimbă modul în care ies răspunsurile. Imediat ce ruta implicită arată spre tun0, un răspuns către clientul tău SSH intră în rețeaua furnizorului, care nu are rută înapoi la adresa ta. Conexiunea se blochează, următoarea încercare expiră, iar daemonul ascultă în continuare pe portul 22 tot timpul.
Citește tabelul de rutare înainte de a citi jurnalul VPN. Jurnalul va spune că tunelul a urcat, și are dreptate. Întrebarea este cărei interfețe este predat fiecare răspuns, iar aceasta este o căutare pentru fiecare pachet într-un tabel pe care tunelul tocmai l-a rescris.
De ce răspunsul iese pe ușa greșită
Pachetele de intrare ajung în continuare pe interfața fizică, pentru că un client VPN nu poate schimba modul în care internetul ajunge la adresa publică a serverului tău. Răspunsurile sunt o decizie separată: pentru fiecare pachet nucleul caută destinația, iar după --redirect-gateway intrarea implicită spune tunel. Ieșirea furnizorului vede o destinație pe care nu o deservește și aruncă pachetul.
Protecția proprie a OpenVPN acoperă exact o destinație. Manualul 2.6 descrie --redirect-gateway ca o secvență: adaugă o rută de gazdă pentru peer-ul VPN prin gateway-ul folosit înainte de tunel, ca traficul criptat să nu poată reveni în sine, apoi înlocuiește ruta implicită. Acea rută de gazdă este doar pentru peer. Clientul tău SSH este doar o altă adresă de internet și nu primește nicio excepție.
Merită exclusă devreme o greșeală de prefix. ip route add -net 0.0.0.0 gw 10.8.0.1 dev tun0 fără lungime corespunde adresei unice 0.0.0.0, nu internetului; trebuie să fie 0.0.0.0/0. Și dacă preluarea rutei implicite rupe transportul propriu al tunelului, adaugă punctul final ca rută de gazdă prin interfața fizică, folosind adresa reală a furnizorului.
Fixează adresa clientului tău SSH pentru o reparație imediată
Cea mai rapidă reparație este o rută de gazdă pentru adresa clientului tău prin gateway-ul pe care serverul îl folosea înainte de tunel. Din partea ta, găsește adresa pe care o va vedea serverul, apoi citește tabelul serverului ca să știi gateway-ul vechi:
curl -s https://ifconfig.co
ip route
Pe server, adaugă excepția înainte ca clientul să pornească. Adresele de aici sunt substituenți; forma este ce contează:
sudo ip route add 80.128.240.55 via 192.168.178.1
Aceasta este reparația folosită în cazul raportat și funcționează imediat. Este și fragilă în două moduri previzibile: ruta dispare la repornire și devine greșită în momentul în care ISP-ul tău îți dă altă adresă. Trateaz-o ca măsură de urgență și fă-o durabilă în mod deliberat, printr-o unitate de rețea sau un hook al dispecerului, sau acceptă că este temporară și notează calea de recuperare.
Împiedică clientul să preia ruta implicită
Opțiunea mai curată este să împiedici tunelul să înlocuiască deloc ruta implicită. route-nopull, folosit cu --client sau --pull, acceptă opțiunile împinse cu excepția rutelor, block-outside-dns și a opțiunilor de tip DHCP precum serverele DNS, așa că adaugi doar prefixele de care ai nevoie. Un instrument mai îngust este un filtru de tragere, care aruncă o directivă problematică și păstrează restul:
route-nopull
pull-filter ignore "redirect-gateway"
Folosește una sau alta, nu ambele, și fii clar ce se schimbă. Fără rută implicită prin tunel, serverul nu mai navighează internetul prin furnizor; ajunge doar la ce ai rutat explicit. Dacă tunelul complet era tot scopul configurării, aceasta este maneta greșită, iar ruta de gazdă de mai sus este cea corectă.
Împarte calea de întoarcere după sursă sau după conexiune
Când adresa de intrare este stabilă, o regulă de sursă ține răspunsurile local fără să atingă rutele proprii ale tunelului. Dă adresei interfeței fizice propriul tabel cu prefixul LAN și ruta implicită fizică, apoi selectează acel tabel pentru traficul care vine de acolo:
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
Acest lucru funcționează pentru că răspunsurile la o conexiune SSH de intrare pleacă de la adresa la care s-a conectat clientul. Un caz raportat în care fiecare serviciu de intrare trebuia să continue să funcționeze a folosit exact această formă. Când adresa de intrare fluctuează sau calea este dinamică, marchează în schimb conexiunea: pune un marcaj conntrack pe primul pachet care vine de pe interfața fizică, copiază-l pe pachetele de răspuns în OUTPUT și rutează pachetele marcate printr-un tabel care indică gateway-ul fizic.
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
Ține separate marcajul conexiunii, marcajul firewallului și numărul tabelului în timpul testelor. Refolosirea unui număr pentru două roluri produce o regulă care pare corectă și lovește pachetele greșite. Intrarea implicită a tabelului are nevoie și de via cu gateway-ul LAN pe o legătură Ethernet obișnuită; un dev eth0 gol funcționează doar când interfața este punct-la-punct sau următorul salt este rezolvat altfel. Gazda Jessie raportată se afla pe o legătură unde forma goală funcționa, ceea ce nu este o regulă de distribuție de copiat.
Verifică fără să te încuie pe dinafară
Nu testa deconectând. Ține prima sesiune deschisă, ridică tunelul și întreabă nucleul ce cale ar lua propria ta adresă:
ip route get 80.128.240.55
Răspunsul ar trebui să numească interfața fizică și gateway-ul vechi, nu tunelul. Apoi deschide o a doua conexiune SSH; acesta este testul real, pentru că sesiunea veche poate supraviețui într-o stare pe care o conexiune nouă nu o poate reproduce. Dacă a doua se blochează în timp ce prima încă răspunde, regula nu a nimerit niciodată traficul care contează, iar marcajele sau adresa sursă sunt locul unde trebuie să te uiți.
Ține o consolă în afara benzii disponibilă pe tot parcursul exercițiului. Un server al cărui singur drum de acces este tunelul pe care tocmai l-ai stricat nu poate fi reparat prin acel tunel, iar revenirea este mai ușoară când ai notat numerele de tabel și prefixele pe care le-ai adăugat.