Kako usmeriti promet gostitelja skozi vsebnik Docker VPN
Vsebnik VPN je imenski prostor omrežja, ne posrednik. Izberite skupni netns, pravega poslušalca SOCKS ali usmerjena vrata, nato preverite izhodno pot.
Vaš vsebnik tunela deluje, docker compose exec vpn curl -s https://ifconfig.me odgovarja z naslovom ponudnika, in vendar brskalnik na vaši delovni površini še vedno izhaja prek vašega ISP. Ta vrzel je pričakovana. Vsebnik, ki izvaja odjemalca VPN, drži imenski prostor omrežja, poti in vmesnik tunela, in nič, kar govori HTTP ali SOCKS; objava vrat na njem ne more ustvariti poslušalca, ki ga ni nikoli bilo.
Kje se odjemalec izvaja, odloča o zasnovi. Sosednji vsebnik lahko preide v imenski prostor tunela, namizna aplikacija ne more, usmerjevalnik pa potrebuje poti, ne polja posrednika. Če zamešate preslikavo, je simptom enak: povezava zavrnjena ali promet, ki tiho ubere staro pot.
Prilagodite ureditev kraju, kjer se odjemalec izvaja
Postavite eno vprašanje, preden uredite Compose: je mogoče odjemalca zagnati znotraj imenskega prostora omrežja vsebnika VPN? Vse, kar že teče kot vsebnik Linux, lahko. Brskalnik, IDE ali CLI na vaši mizi ne more, ker njegova nastavitev posrednika pričakuje protokolarno storitev, ne imenskega prostora.
| 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 |
Ti trije se ne mešajo. Polje posrednika HTTP, usmerjeno na mostni naslov vsebnika, ne doseže ničesar, če tam ne posluša posrednik, poslušalec posrednika pa ne usmerja prometa usmerjevalnika. Najprej se odločite, nato sledite ustreznemu razdelku.
Delite imenski prostor tunela s sosednjim vsebnikom
To je najcenejša možnost, ker ni vključen noben protokol posrednika. Aplikacija vstopi v imenski prostor storitve vpn in podeduje njene vmesnike, poti in prostor vrat:
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_healthyIz dejstva, da imenski prostor pripada drugi storitvi, izhajajo tri omejitve. Aplikacija ne dobi lastnega ključa networks, ker nima imenskega prostora, na katerega bi se pripela. Objavljanje vrat pripada vpn, saj tam živi imenski prostor. In ponovno ustvarjanje vpn uniči imenski prostor, v katerega je vstopila aplikacija, zato docker compose up -d --force-recreate vpn prepušča vam, da znova ustvarite tudi app; navaden ponovni zagon ni vedno dovolj. Referenca storitev Compose pokriva to ureditev in njeno omejitev objavljanja vrat.
Ne predpostavljajte, da razreševalnik pride zraven. /etc/resolv.conf je datoteka na vsebnik, ne del imenskega prostora omrežja, zato lahko aplikacija še vedno vpraša razreševalnik gostitelja, medtem ko njena paketa odhajata skozi tunel. Preberite jo znotraj vsebnika in nastavite dns: na aplikaciji, ko je treba zasebna imena razrešiti skozi tunel.
docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.meČe seznam poti vsebuje vmesnik tunela in je naslov ponudnikov, je aplikacija znotraj tunela. Če vmesnika ni, se je app zagnala, preden je vpn imel tunel, zato znova ustvarite app, ko vpn poroča o zdravju.
V imenski prostor postavite pravega poslušalca posrednika za odjemalce gostitelja
Namizni brskalnik ne more vstopiti v imenski prostor, zato je treba tunel izpostaviti kot storitev. Zaženite pravi posrednik SOCKS ali HTTP znotraj imenskega prostora vpn in objavite samo njegova vrata:
services:
vpn:
ports:
- "127.0.0.1:1080:1080"
proxy:
image: your-proxy
network_mode: service:vpn
command: ["--socks", "0.0.0.0:1080"]Naslov na strani gostitelja je pomembna polovica te preslikave. 127.0.0.1:1080 na levi drži poslušalca zunaj vaše LAN; goli "1080:1080" objavi odprt posrednik vsaki napravi, ki lahko doseže vaš stroj.
Stran vsebnika ima svojo past. Objavljena vrata se dostavijo na naslov vsebnika na mostu, ne na njegov loopback, zato posrednik, zagnan z --socks 127.0.0.1:1080 v imenskem prostoru, sprejema povezave sosedov in zavrača vse, kar pride skozi objavljena vrata. Privežite ga na 0.0.0.0 in se za izolacijo zanesite na vezavo loopback na strani gostitelja. Isto pravilo velja za naslov poslušanja v konfiguracijski datoteki posrednika.
Nato odločite, kje se imena razrešujejo. V curl --socks5 razreši ime gostitelja lokalno, --socks5-hostname pa pošlje ime posredniku; brskalniki ponujajo isto stikalo pod drugo oznako. Lokalno razreševanje razkrije poizvedbo, tudi ko se stran naloži skozi tunel.
Obravnavajte vsebnik kot prehod samo s povratno potjo
Usmerjevalniki, VM in telefoni ne bodo uporabili polja posrednika HTTP, nekatere aplikacije pa spremenljivke posrednika povsem ignorirajo. Usmerjanje njihovega prometa pomeni plast 3: vsebnik posreduje pakete in prevaja naslove na vmesniku tunela.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADEDve stvari zlahka spregledate. Odjemalec potrebuje pot, ki njegova privzeta vrata usmeri na tega gostitelja, odgovori pa morajo najti pot nazaj, bodisi po statični poti na nadrejenem usmerjevalniku bodisi po NAT na vmesniku proti odjemalcem. Brez enega od tega tunel odnese zahtevo ven in odgovor izgine.
Ima tudi najširši doseg. Gostitelj kot prehod za celotno LAN pošlje vsakega napačno nastavljenega odjemalca skozi vaš račun VPN, padec tunela pa bodisi zatemni LAN bodisi se vrne na ISP glede na kill switch.
Preverite izhodno pot in nato zavrtite nazaj po vrstnem redu
Preverjajte v tem vrstnem redu in se ustavite ob prvi napaki: izhodni naslov v imenskem prostoru, izhodni naslov z gostitelja skozi posrednika, nato razreševanje imen za zasebnega gostitelja.
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/healthPrva dva naslova se morata ujemati s ponudnikom, tretji pa se mora razrešiti skozi posrednika, namesto da bi spodletel z napako imena. Ujemajoča se prva vrstica in spodletela druga pomenita, da so napačna poslušalec ali objavljena vrata, ne tunel.
Vračanje nazaj je nasprotje nastavitve. Odstranite okoljske spremenljivke posrednika iz profila lupine in iz katere koli enote systemd, nato spustite sklad, da skupni imenski prostor izgine s svojim lastnikom. Izbrišite objavljena vrata, preden izbrišete storitev posrednika, sicer gostitelju ostane poslušalec loopback, ki ga nihče ne bere.
Preden nadaljujete, potrdite štiri stvari: odjemalec, ki vam je pomemben, res doseže tunel, vrata objavlja samo lastnik imenskega prostora, zasebna imena se razrešujejo tam, kjer ste nameravali, in nič ne posluša na naslovu gostitelja, ki ni loopback. Vsaka od teh v produkciji tiho spodleti in vsaka je preverjanje v eni vrstici zgoraj.