Sådan dirigerer du værtstrafik gennem en Docker VPN-container
En VPN-container er et netværksnavnerum, ikke en proxy. Vælg et delt netns, en rigtig SOCKS-lytter eller en routet gateway, og verificér derefter udgangsstien.
Din tunnelcontainer virker, docker compose exec vpn curl -s https://ifconfig.me svarer med udbyderens adresse, og alligevel forlader browseren på dit skrivebord din ISP. Det gab er forventeligt. En container, der kører en VPN-klient, holder et netværksnavnerum, ruter og en tunnelgrænseflade, og intet, der taler HTTP eller SOCKS; at publicere en port på den kan ikke skabe en lytter, der aldrig var der.
Hvor klienten kører, afgør designet. En søskendecontainer kan flytte ind i tunnelens navnerum, en skrivebordsapplikation kan ikke, og en router har brug for ruter frem for et proxyfelt. Tager du mappingen fejl, er symptomet det samme: forbindelse nægtet eller trafik, der stille tager den gamle vej.
Tilpas arrangementet til det sted, hvor klienten kører
Stil ét spørgsmål, før du redigerer Compose: kan klienten startes inde i VPN-containerens netværksnavnerum? Alt, der allerede kører som en Linux-container, kan. En browser, en IDE eller en CLI på dit skrivebord kan ikke, fordi dens proxyindstilling forventer en protokolttjeneste, ikke et navnerum.
| 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 mod containerens broadresse når intet, medmindre en proxy lytter der, og en proxylytter router ikke en routers trafik. Beslut først, og følg derefter det matchende afsnit.
Del tunnelens navnerum med en søskendecontainer
Dette er den billigste mulighed, fordi ingen proxyprotokol er involveret. Appen slutter sig til vpn-tjenestens navnerum og arver dens grænseflader, ruter og portrum:
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 begrænsninger følger af, at navnerummet tilhører en anden tjeneste. Appen får ingen egen networks-nøgle, fordi den ikke har noget navnerum at hænge sig på. Portpublicering hører til vpn, da det er der, navnerummet bor. Og genskabelse af vpn ødelægger det navnerum, appen sluttede sig til, så docker compose up -d --force-recreate vpn overlader det til dig også at genskabe app; en almindelig genstart er ikke altid nok. Compose-tjenestreference dækker dette arrangement og dets begrænsning for portpublicering.
Antag ikke, at resolveren følger med. /etc/resolv.conf er en fil pr. container og ikke en del af netværksnavnerummet, så appen kan stadig spørge værtens resolver, mens dens pakker forlader gennem tunnelen. Læs den inde fra containeren, og sæt dns: på appen, når private navne skal opløses gennem 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 indeholder tunnelgrænsefladen, og adressen er udbyderens, er appen inde i tunnelen. Hvis grænsefladen mangler, startede app, før vpn havde en tunnel, så genskab app, når vpn rapporterer sund.
Sæt en rigtig proxylytter i navnerummet til værtsklienter
En skrivebordsbrowser kan ikke slutte sig til et navnerum, så tunnelen skal eksponeres som en tjeneste. Kør en rigtig SOCKS- eller HTTP-proxy inde i vpn-navnerummet, og publicer kun dens 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"]Adressen på værtsiden er den vigtige halvdel af den mapping. 127.0.0.1:1080 til venstre holder lytteren væk fra dit LAN; en nøgen "1080:1080" publicerer en åben proxy til enhver enhed, der kan nå din maskine.
Containersiden har sin egen fælde. Publicerede porte leveres til containerens adresse på broen, ikke til dens loopback, så en proxy startet med --socks 127.0.0.1:1080 inde i navnerummet accepterer forbindelser fra søskende og afviser alt, der ankommer gennem den publicerede port. Bind den til 0.0.0.0, og stol på loopback-bindingen på værtsiden for isolering. Samme regel gælder for lytteadressen i en proxykonfigurationsfil.
Beslut derefter, hvor navne opløses. I curl opløser --socks5 værtsnavnet lokalt, og --socks5-hostname sender navnet til proxyen; browsere viser den samme kontakt under en anden etiket. Lokal opløsning lækker opslaget, selv når siden indlæses gennem tunnelen.
Behandl kun containeren som gateway med en returrute
Routere, VM'er og telefoner vil ikke bruge et HTTP-proxyfelt, og nogle applikationer ignorerer proxyvariabler helt. At route deres trafik betyder lag 3: containeren videresender pakker og oversætter adresser på tunnelgrænsefladen.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADETo ting er lette at overse. Klienten har brug for en rute, der peger dens standardgateway mod denne vært, og svar skal finde vej tilbage, enten gennem en statisk rute på den opstrøms router eller gennem NAT på grænsefladen mod klienterne. Uden en af dem bærer tunnelen anmodningen ud, og svaret forsvinder.
Den har også den bredeste effektradius. En vært, der fungerer som gateway for hele LAN'et, sender hver fejlkonfigureret klient gennem din VPN-konto, og et tunnelfald enten blokerer LAN'et eller falder tilbage til ISP'en afhængigt af kill switch.
Verificér udgangsstien, og rul derefter tilbage i rækkefølge
Kontrollér i denne rækkefølge, og stop ved den første fejl: udgangsadresse inde i navnerummet, udgangsadresse fra værten gennem proxyen, derefter navneopløsning for en privat vært.
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 adresser skal matche udbyderen, og den tredje skal opløses gennem proxyen i stedet for at fejle med en navnefejl. En matchende første linje og en fejlende anden linje betyder, at lytteren eller den publicerede port er forkert, ikke tunnelen.
Tilbagerulning er det modsatte af opsætningen. Fjern proxy-miljøvariablerne fra shellprofilen og fra enhver systemd-enhed, og bring derefter stakken ned, så det delte navnerum forsvinder med sin ejer. Slet den publicerede port, før du sletter proxytjenesten, ellers beholder værten en loopback-lytter, som ingen læser.
Før du går videre, bekræft fire ting: den klient, du bekymrer dig om, når faktisk tunnelen, kun navnerummets ejer publicerer porte, private navne opløses, hvor du havde tænkt, og intet lytter på en værtsadresse, der ikke er loopback. Hver af dem fejler lydløst i produktion, og hver er et tjek på én linje ovenfor.