Kontejner, který se nedostane nikam za firemní VPN, obvykle žije v jiném síťovém namespace než tunel. Trasy, DNS servery a značky firewallu klientského hostitele patří jeho zásobníku; kontejner v bridge síti má svůj. Tento jediný fakt vysvětluje většinu hlášení, která se dostanou k platformnímu týmu, a je také důvodem, proč „VPN je rozbitá“ a „Docker obchází VPN“ mohou být nesprávné současně. Za jedním příznakem se skrývají dvě velmi odlišná uspořádání, proto zjistěte, které máte, než změníte nastavení.

Zjistěte, čí namespace tunel vlastní

V Docker Desktop pro macOS nebo Windows běží kontejnery uvnitř linuxového virtuálního stroje. Klient VPN nainstalovaný na ploše vytvoří tunel v operačním systému plochy a virtuální stroj ho nikdy neuvidí. Žádná konfigurace kontejneru to nespraví, protože rozhraní, které by kontejner potřeboval, v jeho síťovém namespace vůbec neexistuje.

Na linuxovém hostiteli žije tunel v namespace hostitele a kontejnery v bridge síti se k němu obvykle dostanou přes směrovací tabulku hostitele s NATem zdroje na odchozí cestě. Když tato cesta selže, příčinou bývá obvykle politika předávání, filtrování zpětné cesty nebo překrývající se podsíť, nikoli chybějící trasa. Potvrďte, ve kterém ze dvou světů jste, než budete číst dál:

docker info --format '{{.OperatingSystem}}'
docker run --rm --net=host alpine ip route | head -5
docker run --rm alpine ip route | head -5

Rozdíl mezi těmito dvěma směrovacími tabulkami je celý problém na jedné obrazovce. Pokud pohled hostitele obsahuje tunelové rozhraní a pohled bridge ne, díváte se na izolaci namespace a vše ostatní je volba, jak ji překonat.

Hostitelská síť je test, ne návrh

Spuštění kontejneru s hostitelskou sítí, kterou Docker dokumentuje jako sdílení síťového namespace hostitele, způsobí, že přímo zdědí tunelové rozhraní a jeho trasy. Pokud stejný požadavek pak uspěje, teorie tras je potvrzena a selháním je izolace namespace, nikoli přihlašovací údaje, DNS nebo přístupové pravidlo.

docker run --rm --net=host curl -sS -o /dev/null -w '%{http_code}\n' https://api.internal/health

Ponechte to jako diagnostiku. Hostitelská síť se vzdává publikování portů a většiny izolace, kterou jste od kontejneru chtěli, a v Docker Desktop „host“ znamená virtuální stroj, ne plochu, takže úspěch nebo selhání tam vás může zmást, pokud zapomenete, kterého hostitele oslovujete.

Zařízení tun a oprávnění, která s ním přicházejí

Klient VPN uvnitř kontejneru potřebuje tunelové zařízení a oprávnění k jeho konfiguraci. Běžnou zkratkou je --privileged, který uděluje všechna zařízení a uvolňuje bezpečnostní politiku v celém kontejneru. To je mnohem víc, než tento úkol vyžaduje, a v recenzi se to těžko obhajuje.

sudo modprobe tun
docker run --rm -it --device /dev/net/tun --cap-add NET_ADMIN myvpn-client

Užší forma mapuje jediný uzel zařízení a přidává pouze možnost správy sítě. Nejprve načtěte modul na hostiteli, aby uzel existoval. Pokud kontejner nastartuje a klient hlásí, že nemůže otevřít tunelové zařízení, zkontrolujte mapování, než budete podezřívat profil, protože tato chyba je obvykle doslovná.

Tento návrh také znamená, že klient běží pro každý kontejner. To je správná odpověď, když každá zátěž potřebuje vlastní tunel, a nesprávná, když jste jen chtěli, aby byl tunel hostitele viditelný, což platformní tým pravděpodobně předpokládal, že děláte.

NAT bridge mění zdroj, který VPN vidí

S výchozím bridge se odchozí provoz kontejneru překládá na adresu hostitele. Za VPN proto firemní strana vidí tunelovou adresu hostitele, ne kontejneru, přístupová pravidla podle zdroje se chovají, jako by požadavek poslal hostitel, a dva kontejnery se pro server VPN stanou nerozlišitelnými.

macvlan nebo ipvlan místo toho předá kontejneru adresu LAN, což pomáhá objevování v LAN a dělá kontejner rovnocenným na segmentu. Zcela také obchází tunel hostitele, takže takový kontejner nedosáhne na prefixy pouze pro VPN, pokud VPN není dostupná i z této LAN.

Obě podoby jsou legitimní; odpovídají na různé požadavky. Pokud je požadavkem „tento kontejner musí dosáhnout na službu pouze pro VPN“, vybíráte mezi směrováním přes hostitele a ukončením tunelu uvnitř kontejneru. Zapište tuto volbu před nasazením, ne po prvním neúspěšném požadavku. Ať zvolíte cokoli, zaznamenejte zdrojovou adresu, kterou uvidí vzdálená strana, protože právě to ukážou její přístupová pravidla a její záznamy. Návrh, který tuto adresu nedokáže uvést, není hotový.

DNS následuje daemona, ne tunel

Kontejner dostane konfiguraci resolveru při startu, zkopírovanou z daemona nebo z image. Adresy, které VPN pošle po připojení, přicházejí pro tuto kopii příliš pozdě a posílají se resolveru hostitele, ne do kontejneru.

Nastavte resolver pro službu výslovně, nebo ho nasměrujte na interní resolver dostupný přes tunel. Kontejner, který překládá soukromé jméno na veřejnou adresu, obvykle používá veřejný resolver, ne že by trpěl rozbitou trasou, a oprava patří do souboru compose nebo konfigurace daemona.

Stejná úvaha platí pro otázku výstupní adresy. Pokud se každý kontejner musí objevovat z jiné adresy VPN, jeden tunel hostitele to nedokáže, protože NAT je sloučí do jednoho zdroje. Fungující podoby jsou klient v namespace každého kontejneru nebo sidecar, který tunel vlastní a sdílí svůj stack, a obě mění způsob adresování aplikace.

Kontrolní seznam před uzavřením tiketu: určete namespace, který tunel vlastní, prokažte cestu hostitelskou sítí, namapujte jen potřebné zařízení tun, zapamatujte si zdrojovou adresu po NATu, nastavte resolver výslovně a berte výstupní adresy pro kontejner jako architektonické rozhodnutí, ne jako přepínač.

Související články