Váš kontajner tunela funguje, docker compose exec vpn curl -s https://ifconfig.me odpovedá adresou poskytovateľa, a napriek tomu prehliadač na vašom stole vychádza cez vášho ISP. Táto medzera je očakávaná. Kontajner, ktorý spúšťa klienta VPN, drží sieťový menný priestor, trasy a rozhranie tunela, a nič, čo hovorí HTTP alebo SOCKS; publikovanie portu na ňom nemôže vytvoriť poslucháča, ktorý nikdy neexistoval.

Kde klient beží, rozhoduje o návrhu. Súrodenecký kontajner môže prejsť do menného priestoru tunela, desktopová aplikácia nemôže, a router potrebuje trasy, nie pole proxy. Ak pomýlite mapovanie, príznak je rovnaký: odmietnuté spojenie alebo prevádzka, ktorá ticho ide starou cestou.

Prispôsobte usporiadanie miestu, kde klient beží

Položte jednu otázku pred úpravou Compose: dá sa klient spustiť vo vnútri sieťového menného priestoru kontajnera VPN? Všetko, čo už beží ako kontajner Linux, môže. Prehliadač, IDE alebo CLI na vašom stole nemôže, pretože jeho nastavenie proxy očakáva protokolovú službu, nie menný priestor.

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

Tieto tri sa nemiešajú. Pole proxy HTTP namierené na mostovú adresu kontajnera nedosiahne nič, ak tam proxy nepočúva, a poslucháč proxy nesmeruje prevádzku routera. Najprv rozhodnite, potom nasledujte príslušnú časť.

Zdieľajte menný priestor tunela so súrodeneckým kontajnerom

Toto je najlacnejšia možnosť, pretože sa nezúčastňuje žiadny protokol proxy. Aplikácia vstúpi do menného priestoru služby vpn a zdedí jej rozhrania, trasy a priestor portov:

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

Z toho, že menný priestor patrí inej službe, vyplývajú tri obmedzenia. Aplikácia nedostane vlastný kľúč networks, pretože nemá menný priestor, ku ktorému by sa pripojila. Publikovanie portov patrí vpn, pretože tam menný priestor žije. A opätovné vytvorenie vpn zničí menný priestor, do ktorého aplikácia vstúpila, takže docker compose up -d --force-recreate vpn necháva na vás znova vytvoriť aj app; obyčajný reštart nie vždy stačí. Referencia služieb Compose pokrýva toto usporiadanie a jeho obmedzenie publikovania portov.

Nepredpokladajte, že resolver príde s ním. /etc/resolv.conf je súbor pre každý kontajner, nie súčasť sieťového menného priestoru, takže aplikácia stále môže spovedať resolver hostiteľa, kým jej pakety odchádzajú tunelom. Prečítajte ho vo vnútri kontajnera a nastavte dns: na aplikácii, keď sa súkromné mená majú riešiť tunelom.

docker compose exec app ip route
docker compose exec app cat /etc/resolv.conf
docker compose exec app curl -s https://ifconfig.me

Ak zoznam trás obsahuje rozhranie tunela a adresa je poskytovateľova, aplikácia je vnútri tunela. Ak rozhranie chýba, app sa spustil skôr, než vpn mal tunel, takže znova vytvorte app, keď vpn hlási zdravie.

Umiestnite skutočného poslucháča proxy do menného priestoru pre klientov hostiteľa

Desktopový prehliadač sa nemôže pripojiť k mennému priestoru, takže tunel musí byť vystavený ako služba. Spustite skutočnú proxy SOCKS alebo HTTP v mennom priestore vpn a publikujte len jej 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"]

Adresa na strane hostiteľa je dôležitá polovica tohto mapovania. 127.0.0.1:1080 vľavo drží poslucháča mimo vašej LAN; holé "1080:1080" publikuje otvorenú proxy každému zariadeniu, ktoré dosiahne váš stroj.

Strana kontajnera má vlastnú pascu. Publikované porty sa doručujú na adresu kontajnera na moste, nie na jeho loopback, takže proxy spustená s --socks 127.0.0.1:1080 v mennom priestore prijíma spojenia od súrodencov a odmieta všetko, čo prichádza publikovaným portom. Pripevnite ju k 0.0.0.0 a pri izolácii sa spoľahnite na naviazanie loopback na strane hostiteľa. Rovnaké pravidlo platí pre adresu počúvania v konfiguračnom súbore proxy.

Potom rozhodnite, kde sa mená riešia. V curl --socks5 rieši meno hostiteľa lokálne a --socks5-hostname posiela meno proxy; prehliadače vystavujú ten istý prepínač pod iným označením. Lokálne riešenie prezradí dopyt, aj keď sa stránka načíta tunelom.

Považujte kontajner za bránu len so spätnou trasou

Routery, VM a telefóny nebudú používať pole proxy HTTP a niektoré aplikácie premenné proxy úplne ignorujú. Smerovať ich prevádzku znamená vrstvu 3: kontajner preposiela pakety a prekladá adresy na rozhraní tunela.

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

Dve veci sa ľahko prehliadnu. Klient potrebuje trasu, ktorá nasmeruje jeho predvolenú bránu na tohto hostiteľa, a odpovede si musia nájsť cestu späť, buď statickou trasou na nadradenom routeri, alebo NAT na rozhraní obrátenom ku klientom. Bez jedného z toho tunel vynesie požiadavku von a odpoveď zmizne.

Má aj najširší dosah. Hostiteľ v role brány pre celú LAN pošle každého zle nastaveného klienta cez váš účet VPN a výpadok tunela buď zablokuje LAN, alebo sa vráti k ISP podľa kill switch.

Overte cestu výstupu a potom sa vracajte v poradí

Kontrolujte v tomto poradí a zastavte sa pri prvom zlyhaní: výstupná adresa v mennom priestore, výstupná adresa z hostiteľa cez proxy, potom riešenie mien pre súkromného hostiteľa.

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

Prvé dve adresy majú zodpovedať poskytovateľovi a tretia sa má vyriešiť cez proxy namiesto zlyhania s chybou mena. Zhoda prvého riadku a zlyhanie druhého znamená, že nesprávny je poslucháč alebo publikovaný port, nie tunel.

Vrátenie je opak nastavenia. Odstráňte premenné prostredia proxy z profilu shellu a z akejkoľvek jednotky systemd, potom spustite stack dole, aby zdieľaný menný priestor zmizol so svojím vlastníkom. Vymažte publikovaný port pred vymazaním služby proxy, inak hostiteľovi zostane poslucháč loopback, ktorý nikto nečíta.

Než budete pokračovať, potvrďte štyri veci: klient, na ktorom vám záleží, skutočne dosiahne tunel, porty publikuje iba vlastník menného priestoru, súkromné mená sa riešia tam, kde ste chceli, a nič nepočúva na adrese hostiteľa, ktorá nie je loopback. Každá z nich v produkcii ticho zlyháva a každá je kontrolou na jeden riadok vyššie.

Súvisiace články