Slik ruter du vertstrafikk gjennom en Docker VPN-container
En VPN-container er et nettverksnavnerom, ikke en proxy. Velg et delt netns, en ekte SOCKS-lytter eller en rutet gateway, og verifiser deretter utgangsstien.
Tunnelcontaineren din fungerer, docker compose exec vpn curl -s https://ifconfig.me svarer med leverandørens adresse, og likevel forlater nettleseren på skrivebordet ditt via ISP-en din. Det gapet er forventet. En container som kjører en VPN-klient, holder et nettverksnavnerom, ruter og et tunellgrensesnitt, og ingenting som snakker HTTP eller SOCKS; å publisere en port på den kan ikke skape en lytter som aldri var der.
Hvor klienten kjører, avgjør designet. En søskencontainer kan flytte inn i navnerommet til tunnelen, en skrivebordsapplikasjon kan ikke, og en ruter trenger ruter framfor et proxyfelt. Tar du kartleggingen feil, er symptomet det samme: tilkobling nektet, eller trafikk som stille tar den gamle veien.
Tilpass oppsettet til stedet der klienten kjører
Still ett spørsmål før du redigerer Compose: kan klienten startes inne i nettverksnavnerommet til VPN-containeren? Alt som allerede kjører som en Linux-container, kan. En nettleser, en IDE eller en CLI på skrivebordet ditt kan ikke, fordi proxyinnstillingen forventer en protokolltjeneste, ikke et navnerom.
| 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 |
Disse tre blandes ikke. Et HTTP-proxyfelt rettet mot containerens broadresse når ingenting med mindre en proxy lytter der, og en proxylytter ruter ikke trafikken til en ruter. Bestem først, og følg deretter den aktuelle delen.
Del tunellnavnerommet med en søskencontainer
Dette er det billigste alternativet fordi ingen proxyprotokoll er involvert. Appen kobler seg til navnerommet til vpn-tjenesten og arver grensesnittene, rutene og portrommet:
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_healthyTre begrensninger følger av at navnerommet tilhører en annen tjeneste. Appen får ingen egen networks-nøkkel, fordi den ikke har noe navnerom å feste seg til. Portpublisering hører til vpn, siden det er der navnerommet bor. Og nyoppretting av vpn ødelegger navnerommet appen koblet seg til, så docker compose up -d --force-recreate vpn overlater til deg å opprette app på nytt også; en vanlig omstart er ikke alltid nok. Compose-tjenestreferansen dekker dette oppsettet og begrensningen for portpublisering.
Ikke anta at resolveren følger med. /etc/resolv.conf er en fil per container, ikke en del av nettverksnavnerommet, så appen kan fortsatt spørre vertens resolver mens pakkene forlater gjennom tunnelen. Les den inne i containeren og sett dns: på appen når private navn må løses gjennom tunnelen.
docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.meHvis rutelisten inneholder tunellgrensesnittet og adressen er leverandørens, er appen inne i tunnelen. Hvis grensesnittet mangler, startet app før vpn hadde en tunnel, så opprett app på nytt når vpn rapporterer at den er frisk.
Sett en ekte proxylytter i navnerommet for vertsklienter
En skrivebordsnettleser kan ikke bli med i et navnerom, så tunnelen må eksponeres som en tjeneste. Kjør en ekte SOCKS- eller HTTP-proxy inne i vpn-navnerommet og publiser bare porten:
services:
vpn:
ports:
- "127.0.0.1:1080:1080"
proxy:
image: your-proxy
network_mode: service:vpn
command: ["--socks", "0.0.0.0:1080"]Adressen på vertssiden er den viktige halvdelen av den kartleggingen. 127.0.0.1:1080 til venstre holder lytteren utenfor LAN-et ditt; en naken "1080:1080" publiserer en åpen proxy til hver enhet som kan nå maskinen din.
Containersiden har sin egen felle. Publiserte porter leveres til containerens adresse på broen, ikke til loopbacken, så en proxy startet med --socks 127.0.0.1:1080 inne i navnerommet godtar tilkoblinger fra søsken og avviser alt som kommer gjennom den publiserte porten. Bind den til 0.0.0.0 og stol på loopback-bindingen på vertssiden for isolasjon. Samme regel gjelder lytteadressen i en proxykonfigurasjonsfil.
Deretter bestemmer du hvor navn løses. I curl løser --socks5 vertsnavnet lokalt, og --socks5-hostname sender navnet til proxyen; nettlesere viser samme bryter under en annen etikett. Lokal oppløsning lekker oppslaget selv når siden lastes gjennom tunnelen.
Behandle containeren som gateway bare med en returrute
Rutere, VM-er og telefoner vil ikke bruke et HTTP-proxyfelt, og noen applikasjoner ignorerer proxyvariabler helt. Å rute trafikken deres betyr lag 3: containeren videresender pakker og oversetter adresser på tunellgrensesnittet.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADETo ting er lette å overse. Klienten trenger en rute som peker standardgatewayen mot denne verten, og svar må finne veien tilbake, enten gjennom en statisk rute på oppstrømsruteren eller gjennom NAT på grensesnittet mot klientene. Uten en av dem bærer tunnelen forespørselen ut, og svaret forsvinner.
Den har også den bredeste effekten. En vert som fungerer som gateway for hele LAN-et, sender hver feilkonfigurert klient gjennom VPN-kontoen din, og et tunnelfall blokkerer enten LAN-et eller faller tilbake til ISP-en avhengig av kill switch.
Verifiser utgangsstien, og rull deretter tilbake i rekkefølge
Kontroller i denne rekkefølgen og stopp ved første feil: utgangsadresse inne i navnerommet, utgangsadresse fra verten gjennom proxyen, deretter navneoppløsning for en privat vert.
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/healthDe to første adressene skal samsvare med leverandøren, og den tredje skal løses gjennom proxyen i stedet for å feile med en navnefeil. En samsvarende første linje og en feilende andre linje betyr at lytteren eller den publiserte porten er feil, ikke tunnelen.
Tilbakerulling er det motsatte av oppsettet. Fjern proxy-miljøvariablene fra skallprofilen og fra enhver systemd-enhet, og ta deretter stakken ned slik at det delte navnerommet forsvinner med eieren sin. Slett den publiserte porten før du sletter proxytjenesten, ellers beholder verten en loopback-lytter som ingen leser.
Før du går videre, bekreft fire ting: klienten du bryr deg om når faktisk tunnelen, bare navnerommets eier publiserer porter, private navn løses der du hadde tenkt, og ingenting lytter på en vertsadresse som ikke er loopback. Hver av dem feiler stille i produksjon, og hver er en enlinjekontroll ovenfor.