Váš prohlížeč na hostiteli ukazuje výstupní adresu VPN, kontejner hlásí vaše domácí připojení a někdo tomu říká únik. Nic neuniklo. Tunel hostitele je soubor rozhraní, tras a pravidel, které patří síťovému jmennému prostoru hostitele, a kontejner na mostu je jiný jmenný prostor s vlastní výchozí trasou. Seděl jsem na stacku Compose, kde byl klient VPN připojený týdny a nevešel do něj ani jeden paket kontejneru.

Zkontrolujte jmenný prostor dřív než ikonu v oznamovací oblasti

Jmenné prostory jsou celý argument. Když Docker spustí kontejner v mostové síti, vytvoří síťový jmenný prostor, připojí do něj jeden konec páru veth a dá tomuto prostoru adresu a výchozí trasu. Rozhraní tunelu, ať se jmenuje jakkoli, žije ve jmenném prostoru hostitele. Provoz uvnitř kontejneru ho nevidí a žádné nastavení klienta to zvenčí nezmění.

Dva podporované kroky vás dostanou z izolace. --network host umístí kontejner do jmenného prostoru hostitele, takže zdědí trasy hostitele a tím i tunel. --network container:vpn sdílí jmenný prostor jiného kontejneru, a tak většina návrhů se sidecarem posílá zátěž přes kontejner VPN. Obojí je výslovná volba; obvykle jen jedna z nich je to, co člověk, který to nasazuje, zamýšlel.

Režim hostitele není bezplatný upgrade. Kontejner přestane mít vlastní adresu, publikování portů přestane platit a proces, který tam drží NET_ADMIN, může přepsat směrování hostitele. Přijmout to může být správné rozhodnutí. Předpokládat, že už je zapnutý, je způsob, jakým lidé stráví večer laděním tunelu, který nikdy nebyl na cestě.

Sledujte paket z mostu ven

Kontejner na mostu pošle svůj paket své výchozí bráně, což je mostové rozhraní na hostiteli. Hostitel paket přepošle a ve výchozí konfiguraci přeloží zdrojovou adresu na svou, než paket odejde. Právě tento krok překladu tiše ruší politiku.

Než paket dorazí ke koncovému bodu tunelu, nese adresu hostitele. Jakékoli pravidlo, politická trasa nebo rozhodnutí o rozděleném tunelu vázané na původní adresu kontejneru přestane odpovídat a dva kontejnery určené k odchodu různými výstupy nelze rozlišit jen podle zdroje. Pokud potřebujete směrování pro jednotlivé kontejnery, musí rozhodnutí padnout před překladem nebo uvnitř jmenného prostoru, který ovládáte.

Docker tato pravidla udržuje sám, prostřednictvím toho firewallového backendu, se kterým byl démon nakonfigurován. Ručně psaná pravidla mimo podporovaný hák pro přeposílaný provoz, DOCKER-USER, mohou být přeuspořádána nebo zrušena, když se démon restartuje nebo hostitel aktualizuje. Dokumentace Dockeru k filtrování paketů ukazuje pořadí řetězců; praktický bod je, že každé pravidlo potřebuje vlastníka a cestu pro opětovné načtení, kterou jste skutečně otestovali.

Testujte oba systémy odděleně

Důkaz z jednoho jmenného prostoru neříká nic o druhém. Požadavek spuštěný uvnitř kontejneru VPN dokazuje, že tunel pro tento kontejner funguje. Není to důkaz o hostiteli a stejný příkaz spuštěný z kontejneru s --network host není důkazem o mostu.

# host namespace
ip route get 1.1.1.1
ip -brief addr show

# a fresh container on the same bridge network
docker run --rm --network appnet alpine sh -c 'ip route; cat /etc/resolv.conf; ip -6 route'

Potom test zopakujte uvnitř skutečného kontejneru aplikace, ne v podobném obrazu. Aplikace může nést extra trasu, proměnnou prostředí pro proxy nebo jiný resolver, a každá z toho mění odpověď. Pokaždé zkontrolujte překlad jmen a druhou rodinu adres: kontejnery na uživatelsky definovaných mostech se překládají přes vestavěný resolver Dockeru na 127.0.0.11 a výchozí trasa IPv6 na mostu může odnést provoz ven, zatímco se zabýváte testováním tunelu jen pro IPv4.

Přečtěte si vzorec, než se dotknete přihlašovacích údajů

Když hostitel funguje a kontejner ne, příčina je téměř vždy strukturální a rotace klíčů nebo přeinstalace klienta promarní odpoledne. Nejprve roztřiďte symptom a oprava se obvykle pojmenuje sama.

What you seeUsual causeFirst check
Host exits through the VPN, container shows the ISP addressThe container never entered the tunnelDefault route inside the container
Container works until the daemon restarts, then stopsRules outside the supported hook, or a changed backendDaemon's reported firewall backend and DOCKER-USER
Container loses internal hosts after the tunnel comes upVPN prefix overlaps the Docker bridge subnetip route on the host, then docker network inspect
Small replies arrive, large ones hangTunnel MTU or missing MSS clampingLink MTU on both ends of the tunnel
Container falls back to the ISP address when the tunnel dropsNothing enforces the kill switch for forwarded trafficStop the tunnel with a request in flight

Řádek o překryvu si zaslouží vlastní větu. Profil VPN, který protlačí trasu pro 172.17.0.0/16 nebo pro 10.0.0.0/8, jež náhodou obsahuje prefix vašeho mostu, přiměje tunel nárokovat si podsíť kontejnerů, a odpovědi na přeložené adresy se vydají špatným směrem nebo zmizí. Přečíslování sítě Docker je obvykle čistší než hromadění výjimek.

Udělejte pokrytí explicitním a pak ho schválně rozbijte

Dva návrhy obstojí při kontrole. Sdílejte jmenný prostor kontejneru VPN a každá pokrytá zátěž použije jeden tunel s jednou hranicí restartu, což je jednoduché, dokud jedna služba nepotřebuje jiný výstup nebo vlastní cestu DNS. Nebo nasměrujte síť kontejnerů na bránu VPN na hostiteli: přeposílání zapnuto, prefix mostu namířen na tunel, zpětný provoz výslovně ošetřen. To kupuje kontrolu pro každou síť a stojí vás sadu pravidel, kterou musíte udržovat napříč aktualizacemi démona i klienta.

Ať tak či onak, test, na kterém záleží, je případ selhání. Zastavte tunel s požadavkem kontejneru za letu a sledujte, kam paket jde. Pokud se vrátí na přímou cestu, pokrytí nebylo nikdy vynuceno, protože kill switch klienta řídí vlastní provoz klienta, ne přeposílané pakety z mostu. Potom restartujte démona a hostitele a výsledek potvrďte podruhé; to je okamžik, kdy ručně psaná pravidla mizí.

Než to prohlásíte za hotové, potvrďte čtyři věci: rozhraní tunelu je ve stejném jmenném prostoru jako provoz, test kontejneru proběhl uvnitř skutečného kontejneru, překlad jmen i obě rodiny adres byly zkontrolovány a test selhání tunelu stále selhává zavřeně. Potom zapište firewallový backend, verzi klienta a vlastníka každého pravidla. Právě tento záznam brání tomu, aby příští aktualizace nechala na místě nedokumentovanou směs starých předpokladů.

Související články