Javítsa ki a host VPN-t figyelmen kívül hagyó Docker- és WSL-forgalmat
A konténerek és a WSL saját útvonalakat, feloldót és továbbítási útvonalat tartanak, ezért egy működő host-alagút elavult DNS-sel vagy kimenet nélkül hagyja őket. Javítsa ki minden réteget.
Idén tavasszal egy reggel nagy részét azzal töltöttem, hogy egy konténert üldöztem, amely egyetlen belső nevet sem tudott feloldani, miközben a mellette lévő böngésző panasz nélkül nyitotta a wikit. Az alagút fent volt, a böngésző bizonyította, a konténer pedig egy másik hálózati névtérben ült, más útvonaltáblával és más feloldóval. A következő az a sorrend, amit most ellenőrzök: először az útvonaltáblák, másodszor a névfeloldás, harmadszor a továbbítás, végül a host platform. Álljon meg az első lépésnél, amely már most elbukik, mert a szabályok hozzáadása lejjebb a veremben elrejti a határt ahelyett, hogy elmozdítaná.
Hasonlítsa össze a három útvonaltáblát, mielőtt szabályt változtat
A Docker alapértelmezett hídján lévő konténernek egy alapértelmezett útvonala mutat a docker0 átjáróra, és fogalma sincs róla, hogy létezik tun0. A hoston van tun0, a VPN által betolt útvonalak, és esetleg egy házirend-szabály, amely a próbaforgalmat más interfészen küldi ki, mint amire számít. A WSL egy harmadik táblát ad hozzá a saját virtuális adaptere mögé. Nyomtassa ki mindhármat, mielőtt bármelyiket szerkesztené.
| Context | Command | What a wrong answer looks like |
|---|---|---|
| Host | ip route get 10.8.0.20 | Leaves a physical interface instead of tun0 |
| Container | ip route | Only 172.17.0.0/16 via 172.17.0.1 |
| Container DNS | cat /etc/resolv.conf | A public resolver, or an upstream the tunnel never pushed |
| WSL | ip addr; ip route | Only the WSL subnet, no Windows VPN adapter |
Ha a konténer egyetlen útvonala a híd, és a tun0 soha nem jelenik meg a névterében, semmi sem segít lentebb: egyetlen névszerver-változtatás sem hoz létre útvonalat, és egyetlen útvonal sem hoz létre olyan alagút-identitást, amelyet a partner elfogad. A sorrend számít, mert a DNS-hiba és az útvonalhiba belülről nézve azonosnak tűnik egy shellben.
Irányítsa a feloldót az alagútra egy nyilvános helyett
A hoston, resolvectl status kapcsolatonként listázza a DNS-kiszolgálókat, és readlink -f /etc/resolv.conf megmondja, hogy a fájl a systemd stub, egy NetworkManager-fájl, vagy valami, amit egy szállító kliense újraírt. Egy felhasználó által meghatározott hálózaton lévő konténerben, /etc/resolv.conf nevet ad a 127.0.0.11-nek, a Docker beépített feloldójának, amely arra az upstreamre továbbít, amellyel a démon konfigurálva volt. Az alapértelmezett hídon lévő konténer viszont létrehozásakor kapta a hostfájl egy másolatát, és megtartja.
Ez a másolat az oka annak, hogy a konténer indítása után feljövő alagút a konténert a régi upstream kérdezgetésénél hagyja. Vagy adja át a VPN feloldóját kifejezetten ezzel: docker run --dns 10.8.0.53, vagy állítsa be a "dns": ["10.8.0.53"] -ot a /etc/docker/daemon.json fájlban, és indítsa újra a démont, vagy hozza létre újra a konténert, amikor az alagút fent van. Az újralétrehozás általában olcsóbb, mint egy olyan feloldó hibakeresése, amely egy órával korábban helyes volt.
A nyilvános feloldóra váltás az a javítás, amely megtartja a tünetet. Feloldja az internetet, és minden privát zónában elbukik, és csendesen megkerülheti azt a szűrést, amelyért az alagút létezik. Ha egy futó konténer /etc/resolv.conf-jébe próbál írni, számítson erre: Device or resource busy: a Docker bind-mountolja azt a fájlt, ezért a szerkesztéshez előbb leválasztás kell. A --dns beállítása létrehozáskor az a sorrend, amely túléli az újraindítást.
Továbbítson és fordítson, amikor a konténerek kölcsönveszik az alagutat
Az alapértelmezett híddal a host router a docker0 és a tun0 között, és alapértelmezés szerint egyik feladatot sem végzi. Kapcsolja be a továbbítást, és fordítsa le a forrás címet, hogy a partner a host alagútcímét lássa, ne olyat, amelyhez nincs visszaútvonala (cserélje a tun0-t arra, ahogy a kliense az interfészt nevezi):
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
iptables -A FORWARD -i docker0 -o tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -o docker0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPTA FORWARD-szabályok azokon a hostokon számítanak, amelyek továbbítási házirendje DROP. A Docker saját láncokat szúr be, ezért csomaggal teszteljen, ne olvasással: iptables -S: a konténerből a ip route get 10.8.0.20 nevezze meg a híd átjáróját, és a nc -vz 10.8.0.20 443 az alagútnál csatlakozzon vagy időtúllépjen, ne a feloldónál.
MASQUERADE nélkül a partnernek visszaútvonalra van szüksége a 172.17.0.0/16 felé, amelyet a legtöbb távoli hozzáférésű VPN nem tol be. Itt törik meg a házirend-alapú kliens terve is: ha csak bizonyos UID-ok vagy cgroups forgalmát fogja el, a továbbítási szabályok soha nem látják a csomagot az alagúton belül, és a javítás a kliens útválasztási házirendjébe tartozik, nem az iptablesbe. A kézzel hozzáadott szabályok újraindításkor eltűnnek, ezért tegye őket systemd-egységbe vagy netfilter-persistent táblába, és tesztelje újra újraindítás után, mivel egy későn feljövő alagút elsöpörheti őket.
Tegye az alagutat a konténer belsejébe, ha a cél az elkülönítés
Ha egy konténernek egy adott csomóponton keresztül kell kilépnie, futtassa a klienst abban a konténerben. Szüksége van --cap-add NET_ADMIN és --device /dev/net/tun elemre, és akkor saját tun0-val, útvonalakkal és tűzfallal rendelkezik. Ha más konténerek rajta keresztül mennek, akkor a konténeren belül továbbításra és MASQUERADE-szabályra is szüksége van, és azoknak a partnereknek kifejezett útvonalra vagy proxyra van szükségük, amely rá mutat; a Docker alapértelmezett hídja nem adja hozzá ezt az útvonalat Ön helyett.
Host-hálózat, docker run --network host, az olcsó változat: a konténer csatlakozik a host névteréhez, és közvetlenül látja az alagút útvonalait. Ezenkívül eldobja a hálózati elkülönítést, portütközéseket hív elő, és a gyakorlatban Linux-opció. Egy közzétett port nem helyettesíti. -p 8080:80 elérhetővé tesz egy szolgáltatást a hostról; nem teszi elérhetővé a belső 10.x címeket a konténer belsejéből, és a kettő összekeverése az az út, amelyen egy útválasztási probléma nyitott adatbázisporttá válik.
Különböztesse meg a névhibát az átfedő alhálózattól
A Docker alapértelmezett hídja 172.17.0.0/16, és sok vállalati VPN-készlet a 172.16.0.0/12 belsejében van. Amint az alagút birtokolja ezt a tartományt, a konténernek szánt forgalom az alagútba irányítható. A nevek elbuknak, a hiba DNS-nek tűnik, és a címek a probléma. Ellenőrizze a célt, ne a feloldót: ip route get 172.17.0.5 a hoston, majd hasonlítsa össze a híd előtagját a VPN-készlettel és a docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'-tal.
A javítás az egyik tartomány elmozdítása: vagy egy másik alapértelmezett címkészlet a Dockernek a daemon.json fájlban, vagy egy másik készlet a koncentrátoron. Egy további névszerver hozzáadása itt semmit sem tesz, és a ssh -b sem: a kliens interfészhez kötése a forráscímet változtatja, nem egy célútvonalat, amely az alagútba mutat. Gyors munkamegosztás: a hoston feloldódó, de a konténerben nem feloldódó név feloldóprobléma, míg a konténerben akadó, de a hoston működő közvetlen IP-kapcsolat útvonal- vagy továbbításilánc-probléma.
A WSL és a Docker Desktop nem követi a Linux szabályait
Alapértelmezett NAT-módjában a WSL a saját virtuális adaptere mögött ül, és nem kapja meg a Windows VPN belső útvonalait vagy DNS-utótagjait, ezért működik a böngésző, és ping a disztribúción belül nem. A tükrözött hálózat, amely a közelmúltbeli Windows 11 buildjeiben elérhető, helyette a host interfészeit osztja meg, de engedélyezni kell a .wslconfig fájlban, és a disztribúciót újra kell indítani a wsl --shutdown paranccsal. Erősítse meg az aktív módot a wslinfo --networking-mode paranccsal a javítás alkalmazása előtt, mert a NAT válasza hibás a tükrözött módhoz, és fordítva.
A Docker Desktop egy további réteget ad hozzá. A Windowson futó Linux-konténerek egy történelmileg vpnkitnek nevezett NAT-megvalósítás mögött ülnek, és az útvonaluk eltér egy natív Linux-hostétól. A Windows-konténerek Hyper-V virtuális kapcsolón keresztül csatlakoznak, és egy vállalati kliens blokkolhatja az arról a kapcsolóról érkező forgalmat, így az ugyanazon a gépen lévő Linux-konténerek elérhetik a hálózatot, míg a Windows-konténereknek semmi sem jut. A fizikai adapterhez kötött külső kapcsoló a szokásos megoldás, és olyan módon változtatja meg a konténer hálózati identitását, amelyet a házirend esetleg nem enged.
Mielőtt újabb szabályt írna, járja végig a négy réteget sorrendben, és álljon meg ott, ahol az egyik hibás:
- A konténeren belül: eléri-e a
ip routea privát előtagot, és nevez-e meg a/etc/resolv.confolyan upstreamet, amely feloldja? - A hoston: be van-e kapcsolva a továbbítás, a NAT az alagút interfészéhez van-e kötve, és a továbbítási lánc elfogadja-e a hidat az alagút felé?
- A partnernél: ismer-e visszaútvonalat, vagy a NAT-ra bízza a konténer alhálózatának elrejtését?
- A platformon: a WSL NAT vagy tükrözött módban van-e, és a konténer Linux vagy Windows?
Futtassa újra minden tesztet friss konténerben vagy shellben. Egy hosszú ideig futó folyamat gyorsítótárazott válasszal vagy létrejött kapcsolattal továbbra is elbukik, miután a konfiguráció helyes, és az a hiba pontosan úgy néz ki, mint egy javítás, amely nem működött.