El vostre contenidor de túnel funciona, docker compose exec vpn curl -s https://ifconfig.me respon amb l'adreça del proveïdor, i el navegador del vostre escriptori encara surt pel vostre ISP. Aquest buit és esperable. Un contenidor que executa un client VPN manté un espai de noms de xarxa, rutes i una interfície de túnel, i res que parli HTTP o SOCKS; publicar un port al seu damunt no pot crear un oient que mai no hi era.

On s'executa el client decideix el disseny. Un contenidor germà pot entrar a l'espai de noms del túnel, una aplicació d'escriptori no pot, i un encaminador necessita rutes i no un camp de proxy. Si feu malament la correspondència, el símptoma és el mateix: connexió rebutjada o trànsit que agafa silenciosament el camí antic.

Adapteu la disposició al lloc on s'executa el client

Feu una pregunta abans d'editar el Compose: es pot iniciar el client dins de l'espai de noms de xarxa del contenidor VPN? Qualsevol cosa que ja s'executi com a contenidor Linux pot. Un navegador, un IDE o una CLI del vostre escriptori no poden, perquè la seva configuració de proxy espera un servei de protocol, no un espai de noms.

ClientArrangementWhat must already exist
Another Compose serviceShares the vpn namespace via network_mode: service:vpnA working tunnel and correct start order
Host browser, IDE or CLIProxy listener inside the namespace, published to host loopbackA configured SOCKS or HTTP proxy and its access rules
Router, VM or phoneThe container as a layer-3 gatewayForwarding, NAT and a return route

Aquests tres no es barregen. Un camp de proxy HTTP apuntat a l'adreça de pont del contenidor no arriba enlloc si no hi ha un proxy escoltant-hi, i un oient de proxy no encamina el trànsit d'un encaminador. Decidiu primer i després seguiu la secció corresponent.

Compartiu l'espai de noms del túnel amb un contenidor germà

Aquesta és l'opció més barata perquè no hi intervé cap protocol de proxy. L'aplicació s'uneix a l'espai de noms del servei vpn i n'hereta les interfícies, les rutes i l'espai de ports:

services:
  vpn:
    image: your-vpn-client
    cap_add:
      - NET_ADMIN
    healthcheck:
      test: ["CMD-SHELL", "ip link show tun0 >/dev/null"]
      interval: 10s
      retries: 5
  app:
    image: your-app
    network_mode: service:vpn
    depends_on:
      vpn:
        condition: service_healthy

Tres restriccions es deriven del fet que l'espai de noms pertany a un altre servei. L'aplicació no rep cap clau networks pròpia, perquè no té cap espai de noms on enganxar-se. La publicació de ports correspon a vpn, ja que allà viu l'espai de noms. I recrear vpn destrueix l'espai de noms al qual es va unir l'aplicació, així que docker compose up -d --force-recreate vpn us deixa recrear també app; un reinici simple no sempre n'hi ha prou. La referència de serveis del Compose cobreix aquesta disposició i la seva restricció de publicació de ports.

No pressuposeu que el resolutor ve de sèrie. /etc/resolv.conf és un fitxer per contenidor i no forma part de l'espai de noms de xarxa, així que l'aplicació encara pot consultar el resolutor de l'amfitrió mentre els seus paquets surten pel túnel. Llegiu-lo des de dins del contenidor i definiu dns: a l'aplicació quan els noms privats s'hagin de resoldre pel túnel.

docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.me

Si la llista de rutes conté la interfície del túnel i l'adreça és la del proveïdor, l'aplicació és dins del túnel. Si la interfície falta, app es va iniciar abans que vpn tingués túnel, així que recreeu app quan vpn informi que és saludable.

Poseu un oient de proxy real a l'espai de noms per als clients de l'amfitrió

Un navegador d'escriptori no pot unir-se a un espai de noms, així que el túnel s'ha d'exposar com a servei. Executeu un proxy SOCKS o HTTP real dins de l'espai de noms vpn i publiqueu només el seu port:

services:
  vpn:
    ports:
      - "127.0.0.1:1080:1080"
  proxy:
    image: your-proxy
    network_mode: service:vpn
    command: ["--socks", "0.0.0.0:1080"]

L'adreça del costat de l'amfitrió és la meitat important d'aquesta correspondència. 127.0.0.1:1080 a l'esquerra manté l'oient fora de la vostra LAN; un "1080:1080" nu publica un proxy obert a cada dispositiu que pugui arribar a la vostra màquina.

El costat del contenidor té la seva pròpia trampa. Els ports publicats es lliuren a l'adreça del contenidor al pont, no al seu loopback, així que un proxy iniciat amb --socks 127.0.0.1:1080 dins de l'espai de noms accepta connexions dels germans i refusa tot el que arriba pel port publicat. Lligueu-lo a 0.0.0.0 i confieu en l'enllaç de loopback del costat de l'amfitrió per a l'aïllament. La mateixa regla s'aplica a l'adreça d'escolta en un fitxer de configuració de proxy.

Després decidiu on es resolen els noms. A curl, --socks5 resol el nom d'amfitrió localment i --socks5-hostname envia el nom al proxy; els navegadors exposen el mateix commutador amb una etiqueta diferent. La resolució local filtra la consulta fins i tot quan la pàgina es carrega pel túnel.

Tracteu el contenidor com a passarel·la només amb una ruta de tornada

Els encaminadors, les VM i els telèfons no faran servir un camp de proxy HTTP, i algunes aplicacions ignoren del tot les variables de proxy. Encaminar el seu trànsit vol dir capa 3: el contenidor reenvia paquets i tradueix adreces a la interfície del túnel.

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

Dues coses són fàcils de passar per alt. El client necessita una ruta que apunti la seva passarel·la per defecte a aquest amfitrió, i les respostes han de trobar el camí de tornada, ja sigui per una ruta estàtica a l'encaminador superior o per NAT a la interfície que mira als clients. Sense una de les dues, el túnel porta la petició fora i la resposta desapareix.

També té el radi d'impacte més ampli. Un amfitrió que fa de passarel·la per a tota la LAN envia cada client mal configurat pel vostre compte VPN, i una caiguda del túnel o bé deixa la LAN a les fosques o bé torna a l'ISP segons el kill switch.

Verifiqueu el camí de sortida i després revertiu per ordre

Comproveu en aquest ordre i atureu-vos a la primera fallada: adreça de sortida dins de l'espai de noms, adreça de sortida des de l'amfitrió a través del proxy, i després la resolució de noms per a un amfitrió privat.

docker compose exec vpn curl -s https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 https://ifconfig.me
curl -s -x socks5h://127.0.0.1:1080 http://internal.example/health

Les dues primeres adreces han de coincidir amb el proveïdor, i la tercera s'ha de resoldre a través del proxy en lloc de fallar amb un error de nom. Una primera línia coincident i una segona que falla volen dir que l'oient o el port publicat és incorrecte, no el túnel.

Revertir és el contrari de la instal·lació. Traieu les variables d'entorn de proxy del perfil de l'intèrpret i de qualsevol unitat systemd, i després baixeu la pila perquè l'espai de noms compartit desaparegui amb el seu propietari. Esborreu el port publicat abans d'esborrar el servei de proxy, o l'amfitrió es queda amb un oient de loopback que ningú no llegeix.

Abans de continuar, confirmeu quatre coses: el client que us importa arriba realment al túnel, només el propietari de l'espai de noms publica ports, els noms privats es resolen on volíeu, i res no escolta en una adreça d'amfitrió que no sigui loopback. Cadascuna d'aquestes falla en silenci en producció, i cadascuna és una comprovació d'una línia més amunt.

Articles relacionats