Răspunsul VPN-ului de la site la site nu trece prin tunel
Un răspuns care ocolește tunelul este o decizie de rutare de partea cealaltă. Verificați tabela de hosturi, selectorii și rp_filter, apoi alegeți rută sau NAT.
Am petrecut o dimineață cu un tunel care se ridica curat și ducea traficul exact într-o singură direcție: sucursala ajungea la serverul de fișiere din sediul central, iar fiecare conexiune deschisă din sediu spre sucursală murea la primul SYN. SA erau active, contoarele tunelului creșteau, iar strângerea de mână nu a fost niciodată problema. Răspunsul era rutat undeva unde tunelul nu acoperă, iar alegerea aceea aparține părții îndepărtate. Un VPN de la site la site transportă doar pachetele pe care un host le predă gateway-ului, iar fiecare host face această alegere separat, în fiecare direcție, din propria tabelă de rutare.
Ambele direcții sunt rutate separat
IP nu ține minte direcția unei conversații. Fiecare host care trimite un pachet face propria căutare a celui mai lung prefix, alege un singur salt următor și uită decizia. Cererea și răspunsul sunt două pachete fără legătură care aparțin din întâmplare aceleiași conexiuni, iar tunelul este un salt pe care oricare dintre ele îl poate folosi sau nu. Nimic din schimbul IKE nu învață serverul îndepărtat cum să ajungă la subrețeaua dumneavoastră; negocierea cade doar de acord asupra prefixelor care pot fi criptate.
Acordul acela este a doua poartă. În strongSwan selectorii de trafic sunt leftsubnet și rightsubnet, iar un pachet a cărui sursă sau destinație cade în afara perechii negociate nu este criptat, orice ar spune tabela de rutare. Un prefix rutat în tunel dar absent din selectori este o defecțiune tăcută într-o singură direcție: ruta pare corectă, pachetul iese totuși în clar sau este aruncat, și doar jurnalul charon se plânge.
Hostul îndepărtat nu știe nimic despre tunelul dumneavoastră
În interiorul LAN-ului îndepărtat răspunsul este un pachet obișnuit adresat clientului dumneavoastră. Hostul destinație nu vede niciun antet IPsec și nu are niciun motiv să prefere gateway-ul VPN; caută prefixul dumneavoastră, nu găsește nimic mai specific decât ruta sa implicită și o urmează. Dacă ruta implicită indică un firewall central, firewall-ul fie are o rută înapoi în tunel, fie nu are. Când nu are, primiți o aruncare tăcută, un ICMP unreachable sau un răspuns care iese prin interfața orientată spre internet și moare.
O a doua interfață este suficientă pentru a strica asta chiar și atunci când există o rută. Un NAS cu legătură de administrare într-un alt VLAN, un server cu uplink de rezervă, o regulă de politică ce trimite un interval de surse într-o a doua tabelă: oricare dintre acestea poate captura răspunsul. În Linux, ip rule show și ip route show table all arată reguli și tabele pe care listarea implicită le ascunde.
Citiți decizia pe mașina care trimite răspunsul
Întrebați nucleul înainte de a schimba ceva, și dați-i adresa sursă, pentru că regulile dependente de sursă schimbă răspunsul.
ip route get 10.10.5.10 from 10.20.30.15
ip rule show
ip route show table all
ss -tn state established "( sport = :445 )"
Ieșirea numește interfața de ieșire și saltul următor. Dacă interfața nu este cea orientată spre gateway-ul VPN, ați găsit defectul, iar munca rămasă este să alegeți unde trebuie să stea ruta. Un ping de la gateway dovedește puțin aici: răspunde cu o adresă pe care hostul îndepărtat o poate plasa, nu cu adresa laptopului dumneavoastră.
În Windows echivalentele sunt Find-NetRoute -RemoteIPAddress 10.10.5.10 pentru decizie și Get-NetRoute pentru tabelă. O rută adăugată cu New-NetRoute care poartă o metrică mai mare decât cea implicită pierde în tăcere, așa că citiți coloana de metrică, nu intrarea. Apoi confirmați cu pachete: tcpdump -ni any "host 10.10.5.10 and tcp port 445" pe interfața LAN îndepărtată arată cererea, iar același filtru pe partea tunelului arată dacă a revenit un răspuns. Cerere vizibilă fără răspuns înseamnă că răspunsul a fost rutat în altă parte sau aruncat; un răspuns pe interfața greșită vă dă vinovatul înainte de a atinge o rută.
Când gateway-ul serverului nu este punctul final al VPN-ului
Multe site-uri pun un firewall între servere și concentrator. Acel firewall redirecționează răspunsul, deci are nevoie de o rută pentru prefixul clientului dumneavoastră către gateway-ul VPN, și de politică de redirecționare în ambele direcții. Dispozitivele cu stare înrăutățesc lucrurile: cererea a traversat firewall-ul de la un host LAN pe care acesta l-a permis, răspunsul vine acum din altă direcție, iar intrarea de urmărire a conexiunilor nu mai corespunde, așa că pachetul este aruncat ca invalid în loc să fie refuzat. De aceea jurnalul de politică pare gol în timp ce traficul dispare.
Gateway-ul are propriul al doilea filtru. Filtrarea căii inverse din Linux aruncă pachetele a căror sursă nu este accesibilă prin interfața pe care au sosit, și exact aceasta este forma unei căi de întoarcere asimetrice legitime. ghidul strongSwan despre redirecționare cere net.ipv4.ip_forward și un net.ipv4.conf.all.rp_filter relaxat exact din acest motiv. O valoare strictă de 1 pe oricare gateway rupe în tăcere o rută corectă, iar nstat -az arată aruncările dacă știți unde să priviți.
| Symptom | Where the reply is most likely lost |
|---|---|
| Gateway ping works, LAN host silent | Source address the far host cannot place in its table |
| SYN arrives, no SYN-ACK, tunnel counters flat | No route to the client prefix on the far host or its gateway |
| Reply counted on the internet-facing interface | Default route or policy rule on the far host |
| Firewall reports invalid state | Asymmetric path through a stateful device |
| Worked until a link failed over | New path is asymmetric, or rp_filter now rejects it |
Rutați sau traduceți, apoi verificați în ambele direcții
Cele două reparații nu sunt echivalente. Adăugarea unei rute păstrează adresa clientului intactă, așa că regulile bazate pe sursă, jurnalele de audit și aplicațiile care înregistrează apelantul continuă să funcționeze; prețul este că fiecare salt care ia decizia are nevoie de rută, adică mai multe locuri unde să greșiți. Mascare pe gateway-ul îndepărtat comprimă calea de întoarcere la un singur salt, pentru că răspunsul este acum adresat gateway-ului însuși, și ascunde care client a făcut ce.
iptables -t nat -A POSTROUTING -o eth1 -s 10.20.30.0/24 -j MASQUERADE
Alegeți-o deliberat: odată ce clienții apar cu adresa gateway-ului, ACL-urile bazate pe sursă nu mai pot să-i distingă, iar conntrack trebuie să țină maparea ca răspunsul să fie rescris înapoi în tunel. Dacă selectorii încă exclud prefixul clientului, NAT nu schimbă nimic, pentru că cererea nu a intrat niciodată în tunel.
Înainte de a declara problema rezolvată, confirmați patru lucruri în ordine: ruta pe hostul care trimite răspunsul, ruta pe fiecare salt care îl redirecționează, selectorii care acoperă ambele prefixe și o captură care arată răspunsul intrând în tunel cu sursa pe care o așteptați. Apoi repetați testul din celălalt site. O singură direcție care trece este un proiect pe jumătate deschis, iar a doua direcție eșuează de obicei dintr-un motiv diferit de cel pe care tocmai l-ați reparat.