O seu contedor de túnel funciona, docker compose exec vpn curl -s https://ifconfig.me responde co enderezo do provedor e, aínda así, o navegador do seu escritorio sae polo seu ISP. Esa fenda é esperable. Un contedor que executa un cliente VPN mantén un espazo de nomes de rede, rutas e unha interface de túnel, e nada que fale HTTP ou SOCKS; publicar un porto nel non pode crear un oínte que nunca existiu.

Onde se executa o cliente decide o deseño. Un contedor irmán pode entrar no espazo de nomes do túnel, unha aplicación de escritorio non pode, e un enrutador necesita rutas en lugar dun campo de proxy. Se se equivoca na correspondencia, o síntoma é o mesmo: conexión rexeitada ou tráfico que toma en silencio a ruta antiga.

Axuste a disposición ao lugar onde se executa o cliente

Faga unha pregunta antes de editar Compose: pódese iniciar o cliente dentro do espazo de nomes de rede do contedor VPN? Calquera cousa que xa se execute como contedor Linux pode. Un navegador, un IDE ou unha CLI do seu escritorio non pode, porque o seu axuste de proxy espera un servizo de protocolo, non un espazo de nomes.

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

Estes tres non se mesturan. Un campo de proxy HTTP apuntado ao enderezo de ponte do contedor non chega a nada salvo que un proxy escoite alí, e un oínte de proxy non enruta o tráfico dun enrutador. Decida primeiro e logo siga a sección correspondente.

Comparta o espazo de nomes do túnel cun contedor irmán

Esta é a opción máis barata porque non intervé ningún protocolo de proxy. A aplicación únese ao espazo de nomes do servizo vpn e herda as súas interfaces, rutas e espazo de portos:

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 restricións derivan de que o espazo de nomes pertenza a outro servizo. A aplicación non recibe unha clave networks propia, porque non ten espazo de nomes ao que engancharse. A publicación de portos corresponde a vpn, xa que alí vive o espazo de nomes. E recrear vpn destrúe o espazo de nomes ao que se uniu a aplicación, así que docker compose up -d --force-recreate vpn déixalle recrear tamén app; un reinicio simple non sempre abonda. A referencia de servizos de Compose cobre esta disposición e a súa restrición de publicación de portos.

Non dea por feito que o resolutor vén incluído. /etc/resolv.conf é un ficheiro por contedor e non forma parte do espazo de nomes de rede, así que a aplicación aínda pode consultar o resolutor do host mentres os seus paquetes saen polo túnel. Léeo dentro do contedor e defina dns: na aplicación cando os nomes privados deban resolverse polo 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

Se a lista de rutas contén a interface do túnel e o enderezo é o do provedor, a aplicación está dentro do túnel. Se falta a interface, app iniciouse antes de que vpn tivese túnel, así que recree app en canto vpn informe que está san.

Pon un oínte de proxy real no espazo de nomes para os clientes do host

Un navegador de escritorio non pode unirse a un espazo de nomes, así que o túnel debe exporse como servizo. Execute un proxy SOCKS ou HTTP real dentro do espazo de nomes vpn e publique só o seu porto:

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

O enderezo do lado do host é a metade importante desa correspondencia. 127.0.0.1:1080 á esquerda mantén o oínte fóra da súa LAN; un "1080:1080" espido publica un proxy aberto a cada dispositivo que poida alcanzar a súa máquina.

O lado do contedor ten a súa propia trampa. Os portos publicados entréganse ao enderezo do contedor na ponte, non ao seu loopback, así que un proxy iniciado con --socks 127.0.0.1:1080 dentro do espazo de nomes acepta conexións dos irmáns e rexeita todo o que chega polo porto publicado. Áteo a 0.0.0.0 e confíe na ligazón de loopback do lado do host para o illamento. A mesma regra aplícase ao enderezo de escoita nun ficheiro de configuración de proxy.

Logo decida onde se resolven os nomes. En curl, --socks5 resolve o nome de host localmente e --socks5-hostname envía o nome ao proxy; os navegadores expoñen o mesmo conmutador baixo outra etiqueta. A resolución local filtra a consulta incluso cando a páxina carga polo túnel.

Trate o contedor como pasarela só cunha ruta de volta

Os enrutadores, as VM e os teléfonos non usarán un campo de proxy HTTP, e algunhas aplicacións ignoran por completo as variables de proxy. Enrutar o seu tráfico significa capa 3: o contedor reenvía paquetes e traduce enderezos na interface do túnel.

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

Dúas cousas pasan por alto con facilidade. O cliente necesita unha ruta que apunte a súa pasarela predeterminada a este host, e as respostas deben atopar o camiño de volta, xa sexa por unha ruta estática no enrutador superior ou por NAT na interface que mira aos clientes. Sen unha das dúas, o túnel leva a petición fóra e a resposta desaparece.

Tamén ten o maior radio de impacto. Un host que actúa como pasarela para toda a LAN envía cada cliente mal configurado pola súa conta VPN, e unha caída do túnel ou ben deixa a LAN ás escuras ou ben volve ao ISP segundo o kill switch.

Verifique a ruta de saída e logo reverta por orde

Comprobe nesta orde e detéñase no primeiro fallo: enderezo de saída dentro do espazo de nomes, enderezo de saída desde o host a través do proxy, e logo resolución de nomes para un host privado.

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

Os dous primeiros enderezos deben coincidir co provedor, e o terceiro debe resolverse a través do proxy en lugar de fallar cun erro de nome. Unha primeira liña coincidente e unha segunda que falla significan que o oínte ou o porto publicado están mal, non o túnel.

Reverter é o contrario da instalación. Elimine as variables de contorno de proxy do perfil do shell e de calquera unidade systemd, e logo baixe a pila para que o espazo de nomes compartido desapareza co seu propietario. Borre o porto publicado antes de borrar o servizo de proxy, ou o host conserva un oínte de loopback que ninguén le.

Antes de continuar, confirme catro cousas: o cliente que lle importa chega realmente ao túnel, só o propietario do espazo de nomes publica portos, os nomes privados resólvense onde vostede quería, e nada escoita nun enderezo de host que non sexa loopback. Cada unha delas falla en silencio en produción, e cada unha é unha comprobación dunha liña máis arriba.

Artigos relacionados