Una ruta que surt d'aquesta estació de treball és un proxy SOCKS, i OpenVPN al darrere informa d'un temps d'espera de connexió sense res útil adjunt. Un navegador a la mateixa màquina funciona a través d'aquest proxy, les credencials són correctes i el port respon. Tres coses difereixen prou sovint per comprovar-les primer: la versió de SOCKS que parla el proxy, el transport que ha triat el client i on es fa la resolució de noms. Confirma cadascuna abans de decidir que el tallafoc té la culpa.

Encaixa la versió de SOCKS abans del tallafoc

OpenVPN comunitari parla SOCKS5 per a socks-proxy. Apunta'l a un proxy que només ofereix SOCKS4 i la connexió TCP s'obre, però després s'atura, perquè el client espera una resposta a una salutació que l'altre extrem no arriba a analitzar. Des de fora, aquesta aturada sembla exactament un port filtrat, i per això la pregunta de la versió va abans de qualsevol regla del tallafoc. Una consulta amb coneixement de SOCKS ho resol en una sola ordre.

curl --socks5-hostname 127.0.0.1:9050 gw.lab.example

Una petició completada demostra dues coses alhora: el proxy ha acceptat la petició SOCKS i ha resolt el nom. No cal cap esquema d'URL, perquè curl tracta un amfitrió sense esquema com a HTTP, cosa suficient per a aquesta prova.

Aquesta consulta també descarta la fallada que amaga el registre del client. Un proxy pot permetre el navegador i tot i així refusar la destinació VPN, cas en què el rebuig passa a CONNECT, abans de qualsevol autenticació VPN. OpenVPN només informa d'un temps d'espera, així que la resposta del propi proxy és l'evidència que necessites.

El transport ha de ser TCP als dos costats

SOCKS5 porta aquí un flux TCP, així que el túnel mateix necessita proto tcp-client. Un perfil encara configurat per a UDP no funcionarà per aquest camí, perquè el client no utilitza el mode d'associació UDP del protocol. Canviar el perfil és un canvi real i no una formalitat: l'altre extrem ha d'escoltar en TCP al mateix port. La càrrega passa llavors a ser TCP dins de TCP, on un segment perdut es retransmet dues vegades i el ritme es degrada, cosa que les sessions interactives noten molt més que les transferències grans.

proto tcp-client
remote gw.lab.example 8443
socks-proxy 127.0.0.1 9050

La directiva pren l'amfitrió del proxy, un port opcional i un fitxer de credencials opcional. Posa'ls al mateix perfil perquè una còpia es comporti igual en un altre lloc.

Confina tota la cadena en un sol contenidor

Fer la cadena a l'amfitrió significa prendre'n la ruta per defecte i deixar el resolutor en un estat que ningú no podrà explicar després. Un namespace o un contenidor ho limita en canvi, de manera que l'amfitrió conserva el seu camí mentre el salt SOCKS i el túnel viuen junts. A dins no s'aixeca res sense un dispositiu de túnel, els permisos per configurar-lo i un proxy accessible. Un servei de Compose ho aconsegueix amb cap_add: NET_ADMIN i un /dev/net/tun muntat per bind.

cap_add:
  - NET_ADMIN
devices:
  - /dev/net/tun:/dev/net/tun

Aquesta parella és més estreta que executar el contenidor amb privilegis, i és tot l'accés al dispositiu que cal. Un client de Tor o un contenidor de proxy a part poden proporcionar l'oïdor. En qualsevol cas, lliga'l a loopback i arriba-hi des del namespace a través de l'amfitrió en lloc d'exposar el proxy a la xarxa.

La resolució de noms és on falla l'aïllament

Un túnel que porta paquets mentre pregunta al resolutor de l'amfitrió no ha aïllat res. Dues coses fan real l'aïllament: el namespace té un resolutor propi i les seves consultes viatgen pel proxy o pel túnel, mai per la interfície física. Fes servir dos noms per a la prova: un que només existeixi darrere del túnel i un de públic que hauria de seguir el mateix camí.

docker compose exec vpn cat /etc/resolv.conf
docker compose exec vpn getent hosts internal.lab.example

Si el nom del costat remot es resol i el públic no, la cadena és selectiva i no trencada, i la diferència et diu quin camí va prendre cada consulta. Si tots dos es resolen des de l'amfitrió però cap dins del contenidor, el contenidor encara manlleva el resolutor de l'amfitrió. Anota el fitxer de resolutor que has trobat, perquè és el paràmetre que s'ha de canviar.

Demostra cada salt per ordre

La llista és curta. Una petició SOCKS5 obté resposta, el túnel arriba al seu oïdor a través del proxy i els paquets que surten del namespace porten l'adreça que l'altre extrem espera. Confirma cada cosa per separat en lloc d'afegir més configuració. Quan el client diu que està connectat i res no es mou, la ruptura és gairebé sempre en el segon o el tercer fet.

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

Anota la combinació que ha funcionat: versió de SOCKS, transport, resolutor i paràmetres del namespace. Resoldre aquesta cadena una segona vegada de memòria costa més que la nota. Guarda aquests quatre fets al tiquet i no en un fil de xat.

Una cadena que informa de connexió i no passa res sol haver fallat en el salt que encara no has demostrat. Prova aquest salt abans d'afegir una altra capa.

Articles relacionats