Com encaminar el trànsit de l'amfitrió a través d'un contenidor Docker amb VPN
Un contenidor VPN és un espai de noms de xarxa, no un proxy. Trieu un netns compartit, un autèntic oient SOCKS o una passarel·la encaminada, i després verifiqueu el camí de sortida.
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.
| Client | Arrangement | What must already exist |
|---|---|---|
| Another Compose service | Shares the vpn namespace via network_mode: service:vpn | A working tunnel and correct start order |
| Host browser, IDE or CLI | Proxy listener inside the namespace, published to host loopback | A configured SOCKS or HTTP proxy and its access rules |
| Router, VM or phone | The container as a layer-3 gateway | Forwarding, 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_healthyTres 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.meSi 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 MASQUERADEDues 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/healthLes 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.