De ce LAN-ul tău nu ajunge la un serviciu de pe un client VPN
Un client VPN poate găzdui un serviciu pe care LAN-ul nu îl poate deschide. Ce lipsește de obicei este drumul de întoarcere: o rută, o pereche DNAT sau linia SNAT pe care nimeni nu o adaugă.
Tunelul tău este activ, serviciul ascultă, iar LAN-ul biroului tot nu primește nimic înapoi. Nimeni nu a stricat VPN-ul. Din partea LAN-ului, adresa de tunel a laptopului nu există până când ceva îi spune LAN-ului cum să ajungă la ea, și răspunsul trebuie să se întoarcă pe același drum pe care a ieșit cererea. Am văzut oameni reconstruind de trei ori un tunel perfect sănătos înainte ca cineva să se uite la drumul de întoarcere.
Nu tunelul s-a stricat
Ambele capete stau pe intervale private, ceea ce este cazul normal și nu o configurație greșită. O adresă ca 10.8.0.6 este reală în interiorul tunelului și nu există nicăieri altundeva, așa că LAN-ul nu are niciun motiv să trimită ceva acolo. Înainte de a atinge rutarea, confirmă că serviciul este accesibil în interiorul tunelului: pe client, ss -ltn arată dacă ascultătorul se leagă de 127.0.0.1, de interfața LAN sau de adresa tunelului. Un daemon legat doar de loopback nu răspunde nimănui în afară de el însuși, și nicio rută, DNAT sau redirecționare de port nu schimbă asta.
Un proxy pe portul 80 sau 443 este alt instrument cu altă vizibilitate. Mută cereri, nu pachete, deci este stratul greșit pentru o conexiune brută la o bază de date, și tocmai apelarea la el este modul în care această problemă ajunge trei instrumente adânc înainte ca cineva să măsoare ceva.
Forma rutei: spune LAN-ului unde este bazinul
O rută statică pe gateway-ul LAN este cel mai curat răspuns când LAN-ul și bazinul tunelului nu se suprapun. Îndreaptă bazinul spre mașina care termină tunelul:
ip route add 10.8.0.0/24 via 192.168.1.12
route add -p 10.8.0.0 mask 255.255.255.0 192.168.1.12 # Windows, persistent
Asta repară doar o direcție, de aceea versiunile pe jumătate ale acestei schimbări arată ca progres. Partea tunelului are nevoie de jumătatea corespunzătoare, altfel răspunsul părăsește clientul pe propria rută implicită și moare pe drum:
push "route 192.168.1.0 255.255.255.0"
Pentru o subrețea care stă în spatele unui client și nu în spatele serverului, serverul are nevoie atât de o rută de sistem, cât și de o intrare iroute în fișierul acelui client sub client-config-dir. Fără iroute, OpenVPN știe că prefixul există și nu are idee ce client îl deține: pachetele sosesc și daemonul nu are cu ce să le potrivească.
Iată mitul care merită un nume. O rută face o adresă accesibilă; nu face cealaltă parte dispusă să răspundă. Partenerii site-la-site adaugă încă un strat deasupra, pentru că gateway-ul îndepărtat acceptă doar surse din interiorul prefixelor din politica sa, iar un laptop care vine dintr-un bazin de acasă nu este în ele.
Forma NAT: DNAT spre interior și linia SNAT pe care toți o omit
Când nu poți atinge gateway-ul LAN, sau vrei să publici exact un port, traducerea pe gazda VPN funcționează fără nicio rută pe LAN. Publică portul, redirecționează-l și tradu sursa pe drumul spre tunel:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.8.0.6:3000
iptables -A FORWARD -i eth0 -o tun0 -p tcp -d 10.8.0.6 --dport 3000 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -d 10.8.0.6 -p tcp --dport 3000 -j SNAT --to-source 10.8.0.1
A treia linie este cea care dispare. Omite-o și clientul vede adresa LAN originală ca sursă, răspunde pe propria rută implicită, iar acel răspuns pleacă în tunel în loc să se întoarcă spre LAN. Dacă conexiunea supraviețuiește depinde atunci de rutare pe care nu ai planificat-o niciodată. Cu SNAT clientul vede adresa de tunel a serverului, așa că răspunsul urmează tunelul înapoi până la singura gazdă care poate anula traducerea.
Firmware-ul de consum folosește propriile nume de lanțuri și nu generează acea traducere pentru tine. Pe Tomato, o regulă de intrare ajunge în WANPREROUTING și apoi într-un lanț de filtrare ca wanin, iar un set de reguli care pare complet are totuși nevoie de o linie POSTROUTING manuală. Nu este un bug de firmware; este un set de reguli scris doar pentru trafic de intrare.
De ce o regulă care pare corectă tot aruncă pachetul
Majoritatea acestor eșecuri nu sunt în regula la care te uiți fix. Verifică patru lucruri în această ordine și oprește-te la primul care nu se ține:
- Ordinea lanțurilor.
iptables -Iinserează sus și-Aadaugă la final, deci o regulă permisivă sau blocantă anterioară decide prima. - Lanț greșit. Traficul adresat routerului însuși trece prin INPUT, iar traficul redirecționat nu îl atinge niciodată. Publicarea unui singur serviciu poate cere reguli în ambele.
- Steaguri de direcție.
-i tun0corespunde traficului care vine de la clienți și-o tun0traficului care pleacă spre ei. Un REJECT cu steagul greșit blochează ceva ce nu ai intenționat. - Restricție de sursă. O redirecționare care acceptă o adresă de client funcționează de la acel client și aruncă orice altă sursă fără un cuvânt.
O regulă cu contorul de pachete la zero nu este deloc pe traseu, iar citirea contoarelor este cea mai rapidă cale de a separa o problemă de lanț greșit de una de regulă greșită.
Redirecționarea locală, când nimic din LAN nu poate fi schimbat
O redirecționare SSH locală ocolește toată întrebarea. Nu are nevoie de rută în LAN, de cooperarea firewall-ului clientului și de niciun port publicat nicăieri:
ssh -N -f -L 3000:10.8.0.6:3000 user@vpn-host
Serviciul apare apoi pe localhost:3000 al mașinii care ține tunelul, și nicăieri altundeva. Aceasta este limita: o stație de lucru, un port, iar redirecționarea moare odată cu sesiunea dacă ceva nu o repornește. Pentru un administrator care verifică o bază de date de test este instrumentul potrivit. Pentru o cameră sau un scanner la care trebuie să ajungă alți oameni, nu este, pentru că fiecare utilizator ar avea nevoie de propria redirecționare.
Verifică ambele direcții înainte de a adăuga altă regulă
Traducerea lasă urme, iar citirea lor e mai bună decât ghicitul. Pe gazda VPN, conntrack -L arată dacă traducerea a avut loc, iptables -t nat -L -n -v arată dacă contoarele s-au mișcat, iar tcpdump -ni any port 3000 arată ce adresă de sursă a ajuns de fapt. Pe client, ss -ltn confirmă că ascultătorul este pe o adresă pe care tunelul o poate atinge.
Apoi alege forma pe care o păstrezi. Un port publicat, o rută pentru întregul bazin și o redirecționare pentru un singur administrator sunt trei angajamente diferite, iar amestecarea lor este felul în care o configurație funcțională devine una pe care nimeni nu o poate explica șase luni mai târziu. Notează ce adresă este accesibilă de unde, iar următoarea persoană care depanează asta începe de la răspuns în loc de tunel.