NAT decide ce adresă sursă vede de fapt serverul tău VPN
Adresa laptopului tău nu ajunge niciodată la serverul VPN. NAT o rescrie la ultimul salt, iar IP-ul tunelului este atribuit mai târziu. Cum compari cele două capete.
Îți imaginezi serverul VPN citind adresa laptopului tău din pachet și scriind-o într-un jurnal. Ceea ce citește este ce a pus ultimul salt NAT în antetul exterior, iar pe un telefon folosit ca hotspot aceasta este adesea o adresă partajată cu sute de alți abonați. Adresa proprie a mașinii tale 192.168.x.x nu traversează niciodată internetul în acel antet, iar adresa tunelului este acordată de server după ce conexiunea este deja stabilită. Așa că, atunci când jurnalul serverului și ip addr de pe laptop nu coincid, niciunul nu este greșit; descriu straturi diferite ale aceleiași sesiuni.
Trei adrese, și doar una este în jurnal
Confuzia apare din reducerea a trei adrese la una. Fiecare are alt proprietar, trăiește într-un alt antet și ajunge la server pe o altă cale.
| Address | Who assigns it | Where it sits | Visible to the VPN server |
|---|---|---|---|
Device address, e.g. 192.168.1.24 | Your router via DHCP | Outer header, before translation | No, rewritten in place |
| Translated address and port | Router, ISP CGNAT, or both | Outer header, after translation | Yes, this is the tuple it logs |
Tunnel address, e.g. 10.8.0.6 | The VPN server itself | Inner header, after decapsulation | Yes, but it chose it |
Doar rândul din mijloc este necunoscut în momentul conectării. Serverul îl scrie în tabelul de parteneri, fișierul de stare sau jurnalul de fluxuri în funcție de demon: WireGuard îl numește punct final, un fișier de stare OpenVPN îl etichetează drept Real Address, iar strongSwan îl raportează ca gazdă la distanță a IKE_SA. Acea valoare este reîmprospătată de fiecare dată când sosește un pachet din altă sursă, deci se schimbă fără ca cineva să repornească ceva.
Rândul de jos este ceea ce oamenii citesc greșit ca o afirmație de identitate. Marchează un loc în configurația serverului, nu o persoană, pentru că serverul l-a ales din propriul său bazin. Doi utilizatori pot primi aceeași adresă de tunel în zile diferite, iar unul poate ține două dintre ele de pe două dispozitive.
De ce tuplul înregistrat se schimbă în timp ce tunelul rămâne activ
Traducerea adreselor este un tabel cu temporizator, nu o legătură permanentă. Un router de acasă își păstrează maparea UDP o vreme după ultimul pachet, un gateway al operatorului reciclează porturi după propriul program, iar un telefon care trece de la Wi-Fi la LTE se întoarce cu o sursă complet diferită. Valorile implicite ale conntrack din Linux sunt un reper util aici: nf_conntrack_udp_timeout este de 30 de secunde, iar varianta de streaming este de 120, așa că un tunel liniștit poate pierde maparea mult înainte ca utilizatorul să observe.
Tunelul supraviețuiește pentru că protocolul autentifică partenerul, nu adresa. WireGuard este fără stare după handshake, deci orice pachet autentificat actualizează punctul final stocat, iar rebind-ul se vindecă la următorul pachet; de aceea există persistent-keepalive = 25, ca să păstreze maparea caldă în timpul inactivității. --float din OpenVPN face același lucru și permite unui client autentificat să continue de la o adresă și un port noi. În build-urile 2.4 și 2.5 unde float este oprit implicit, o rebind-are resetează sesiunea și clientul se reconectează.
IPsec ajunge acolo cu mai multe piese mobile. IKEv2 observă traducerea comparând hash-urile sursă și destinație din sarcinile de detectare NAT, trece la încapsulare UDP 4500 și urmărește keepalive-urile până la noul tuplu. Când keepalive-urile sunt blocate, SA rămâne activ pe hârtie în timp ce traficul într-o direcție se oprește în tăcere.
Ce poate atribui serverul și ce nu
Mitul care merită ucis este că traducerea te ascunde de operator. Ea schimbă eticheta, nu observația. Un gateway din spatele NAT-ului operatorului vede spațiul 100.64.0.0/10 sau o adresă publică partajată de mulți abonați și poate totuși lega fluxul de un subiect de certificat, o cheie publică WireGuard, o adresă de tunel alocată, contoare de octeți și o fereastră de timp. Niciuna dintre acestea nu are nevoie de adresa ta LAN.
Limitele merg și în cealaltă direcție. O adresă partajată într-un jurnal indică un gateway, nu o gospodărie; două sesiuni de la aceeași adresă tradusă pe porturi diferite sunt dispozitive diferite; aceeași adresă în două zile diferite poate fi doi abonați fără legătură dacă portul a fost reciclat. Un server care înregistrează doar chei de parteneri nu poate asocia una unui client fără baza de date de conturi, iar un server care înregistrează doar adrese nu poate distinge un laptop de un telefon în spatele aceluiași router.
Compară ambele capete în loc să ghicești
Pentru a stabili ce s-a întâmplat, captează aceeași conexiune la ambele capete în același moment și compară tuplul, nu adresa. Pe client, înainte de orice traducere:
ss -uapn 'dport = :51820'
ip -4 route get 203.0.113.10
wg show wg0 endpoints
Apoi citește intrarea de traducere de pe router sau de pe gateway-ul CGNAT, și ce ajunge în final la server:
conntrack -L -p udp --dport 51820
tcpdump -ni eth0 udp port 51820
Trei tipare explică majoritatea nepotrivirilor. Portul sursă de pe server diferă de portul local în timp ce destinația se potrivește: traducere obișnuită de porturi. Adresa sursă de pe server aparține unui bloc ISP care nu este al tău: cel puțin un strat NAT suplimentar. Pachetele se opresc după o perioadă de inactivitate și reiau cu un port nou: maparea a expirat, nu este o defecțiune de rutare. Dacă marcajele de timp sunt la mai mult de o secundă sau două, compari două încercări diferite.
Unde diferența strică lucrurile
Întreruperile care par defecte de server încep de obicei aici. O regulă de acces fixată de adresa ta de acasă eșuează după ce se schimbă lease-ul ISP. O regulă fail2ban care se potrivește cu o adresă tradusă blochează toți abonații din spatele acelui gateway deodată. Un partener site-to-site cu o adresă la distanță fixă nu mai reînnoiește cheile după ce se schimbă o legătură mobilă. Protocolul tunelului era în regulă; presupunerea despre tuplul exterior nu.
Aceeași confuzie apare și pe partea serverului. Dacă cutia VPN însăși stă în spatele NAT, ai nevoie de port forwarding și de o cale de forwarding funcțională; ghidul de forwarding al strongSwan acoperă acel caz pentru IPsec. Un server accesibil doar pe o adresă privată nu vede niciodată tuplul tradus pe care îl prezintă clienții săi, iar asta este o problemă diferită de traducerea clienților.
Parcurge aceste patru verificări în ordine și oprește-te la prima care eșuează:
- Captează la ambele capete în același timp; confirmă că portul sursă, portul destinație și marcajele de timp se potrivesc.
- Citește lista de parteneri a serverului pentru adresa pe care o deține acum, nu cea pe care o așteptai.
- Verifică tabelul conntrack sau NAT pentru intrare și durata de viață rămasă.
- Confirmă că adresa interfeței tunelului pe client corespunde celei alocate de server, nu adresei LAN.
Dacă ambele capturi sunt de acord asupra tuplului și tunelul tot eșuează, traducerea nu este problema ta; treci la handshake și la tabelul de rutare din interiorul tunelului.