OpenVPN prin SOCKS5: potrivirea versiunii, transportului și DNS
Lanțul SOCKS eșuează când versiunea proxy-ului, transportul sau calea DNS nu se potrivesc. Potriviți SOCKS5, transportați TCP și țineți lanțul într-un singur spațiu de nume.
Una dintre căile de ieșire din această stație de lucru este un proxy SOCKS, iar OpenVPN din spatele lui raportează expirarea timpului de conectare fără niciun detaliu util. Browserul de pe aceeași mașină funcționează prin acel proxy, acreditările sunt corecte și portul răspunde. Trei lucruri diferă destul de des ca să fie verificate primele: versiunea SOCKS pe care o vorbește proxy-ul, transportul ales de client și locul unde are loc rezolvarea numelor. Confirmați fiecare înainte de a da vina pe firewall.
Potriviți versiunea SOCKS înainte de firewall
OpenVPN comunitar vorbește SOCKS5 pentru socks-proxy. Îndreptați-l spre un proxy care oferă doar SOCKS4 și conexiunea TCP se deschide, apoi se blochează, pentru că clientul așteaptă un răspuns la un salut pe care cealaltă parte nu îl analizează niciodată. Din exterior, blocajul arată exact ca un port filtrat, de aceea întrebarea despre versiune vine înaintea oricărei reguli de firewall. O singură descărcare cu cunoștințe SOCKS rezolvă asta cu o comandă.
curl --socks5-hostname 127.0.0.1:9050 gw.lab.example
O cerere finalizată dovedește două lucruri deodată: proxy-ul a acceptat cererea SOCKS și a rezolvat numele. Nu e nevoie de schemă URL, pentru că curl tratează gazda simplă ca HTTP, iar asta e suficient pentru acest test.
Acea descărcare exclude și defecțiunea pe care jurnalul clientului o ascunde. Proxy-ul poate permite browserul și totuși refuza destinația VPN, iar atunci refuzul are loc la CONNECT, înaintea oricărei autentificări VPN. OpenVPN raportează doar expirarea timpului, deci răspunsul propriu al proxy-ului este dovada de care aveți nevoie.
Transportul trebuie să fie TCP pe ambele părți
Aici SOCKS5 transportă un flux TCP, deci tunelul însuși are nevoie de proto tcp-client. Un profil încă setat pe UDP nu va funcționa pe această cale, pentru că clientul nu folosește modul de asociere UDP al protocolului. Inversarea profilului este o schimbare reală, nu o formalitate: partea îndepărtată trebuie să asculte TCP pe același port. Apoi încărcătura devine TCP în TCP, unde segmentul pierdut este retrimis de două ori și ritmul scade, ceea ce sesiunile interactive simt mult mai puternic decât transferurile mari.
proto tcp-client
remote gw.lab.example 8443
socks-proxy 127.0.0.1 9050
Directiva primește gazda proxy-ului, un port opțional și un fișier opțional de acreditări. Puneți-le în profilul însuși, ca o copie de altundeva să se comporte la fel.
Închideți tot lanțul într-un singur container
A face lanțul pe gazdă înseamnă să preiei ruta ei implicită și să lași rezolvatorul într-o stare pe care nimeni nu o va explica mai târziu. Un spațiu de nume sau un container îl limitează în schimb, așa că gazda își păstrează calea, iar saltul SOCKS și tunelul trăiesc împreună. Înăuntru nu se ridică nimic fără un dispozitiv de tunel, drepturi de configurare a acestuia și un proxy accesibil. Un serviciu Compose obține asta cu cap_add: NET_ADMIN și /dev/net/tun montat prin bind.
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun:/dev/net/tun
Această pereche este mai îngustă decât rularea containerului cu privilegii depline și este tot accesul necesar la dispozitiv. Un client Tor sau un container separat de proxy poate furniza ascultătorul. În ambele cazuri legați-l de loopback și ajungeți la el din spațiul de nume prin gazdă, în loc să expuneți proxy-ul în rețea.
Rezolvarea numelor este locul unde izolarea eșuează
Un tunel care transportă pachete și totuși întreabă rezolvatorul gazdei nu a izolat nimic. Două lucruri fac izolarea reală: spațiul de nume are propriul rezolvator, iar interogările lui trec prin proxy sau tunel, niciodată prin interfața fizică. Pentru test folosiți două nume: unul care există doar în spatele tunelului și unul public care ar trebui să urmeze aceeași cale.
docker compose exec vpn cat /etc/resolv.conf
docker compose exec vpn getent hosts internal.lab.example
Dacă numele îndepărtat se rezolvă iar cel public nu, lanțul este selectiv, nu stricat, iar diferența vă spune ce cale a urmat fiecare interogare. Dacă ambele se rezolvă de pe gazdă dar niciunul în container, containerul încă împrumută rezolvatorul gazdei. Notați fișierul de rezolvator găsit, pentru că aceea este setarea care trebuie schimbată.
Dovediți fiecare salt în ordine
Lista este scurtă. O cerere SOCKS5 primește răspuns, tunelul ajunge la ascultătorul său prin proxy, iar pachetele care părăsesc spațiul de nume poartă adresa pe care o așteaptă partea îndepărtată. Confirmați câte unul, în loc să adăugați mai multă configurație. Când clientul spune conectat și nimic nu se mișcă, ruptura este aproape întotdeauna în al doilea sau al treilea fapt.
curl --socks5-hostname 127.0.0.1:9050 gw.lab.example
docker compose exec vpn ip route get 203.0.113.10
docker compose exec vpn getent hosts internal.lab.example
Notați combinația care a funcționat: versiunea SOCKS, transportul, rezolvatorul și setările spațiului de nume. Rezolvarea acestui lanț a doua oară din memorie costă mai mult decât notița. Țineți cele patru fapte în tichet, nu în firul de chat.
Un lanț care raportează conectat și nu trece nimic a eșuat de obicei la saltul pe care încă nu l-ați dovedit. Testați acel salt înainte de a adăuga un alt strat.