Provoz kontejnerů Docker obchází VPN hostitele: jak to ověřit
VPN hostitele pokrývá jen jmenný prostor hostitele. Pomocí těchto kontrol zjistíte, zda provoz kontejnerů na mostu vstupuje do tunelu, nebo odchází přímo.
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 see | Usual cause | First check |
|---|---|---|
| Host exits through the VPN, container shows the ISP address | The container never entered the tunnel | Default route inside the container |
| Container works until the daemon restarts, then stops | Rules outside the supported hook, or a changed backend | Daemon's reported firewall backend and DOCKER-USER |
| Container loses internal hosts after the tunnel comes up | VPN prefix overlaps the Docker bridge subnet | ip route on the host, then docker network inspect |
| Small replies arrive, large ones hang | Tunnel MTU or missing MSS clamping | Link MTU on both ends of the tunnel |
| Container falls back to the ISP address when the tunnel drops | Nothing enforces the kill switch for forwarded traffic | Stop 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ů.