A konténer csomagja soha nem ér el a tun0 címre, és a konténeren lévő további képességek ezen nem változtatnak. A vendég és az alagút között két útvonalkeresés áll: egy a vendég hálózati névterében, egy a hoston, miután a keret a hídra érkezik, a második pedig egy másik táblát kérdez más illesztési szabályokkal. A referenciabeállításom egy Linux host, amelyen OpenVPN kliens fut, amely 10.8.0.10 címet tart tun0-on, egy Docker-híd a 172.18.0.0/16 címen, és egy privát cím, amelyhez csak az alagút oldala fér hozzá. A cél szűk marad: az a vendég-alhálózat az alagúton távozik, míg a host megtartja a szokásos uplinkjét.

A VPN-kliens a konténeren belüli futtatása más tervezés, nem rövidítés. Akkor a konténer birtokolja az alagutat és a hitelesítő adatokat, és a munka Dockerfile-ba kerül ahelyett, hogy iptables-ban maradna.

A továbbítás cél szerint választ útvonalat, majd a NAT átírja a forrást

Ha be van állítva a net.ipv4.ip_forward=1, a továbbított csomag csak cél szerint útvonalazódik, a fő táblában. A forrás nem játszik szerepet ebben a döntésben. Csak az útvonal kiválasztása után futtatja a kernel a POSTROUTING szabályt, és ott van a Docker saját szabálya: -s 172.18.0.0/16 ! -o br-appnet -j MASQUERADE. Minden, ami a hidat elhagyja egy másik interfész felé, lefordítódik, és az a cím, amivé válik, attól az interfésztől függ, amelyre az útvonal küldte.

Ez a szabály magyarázza a legtöbb tünetet, amiről kérdeznek. Ha a fő táblában nincs útvonal a privát célhoz, a csomag a host fizikai címével hagyja el az uplinket. A szolgáltató eldobja a célt, vagy a távoli oldal eldob egy RFC 1918 forrást, amelyre soha nem számított, és a konténer túllépi az időt, miközben az alagút áll és egészséges. A tun0-on végzett rögzítés semmit sem mutat, és ez a jel. Ha az útvonal mégis a tun0 felé mutat, a MASQUERADE átírja a forrást a 10.8.0.10 címre, és ugyanaz a konténer működik anélkül, hogy bármihez hozzányúlna.

Kérje azt a keresést, amely megnevezi a vendég forrását. from és iif nélkül a host a saját socketéért válaszol, és olyan útvonalat jelent, amelyet a továbbított csomag soha nem vesz fel:

ip route get 192.168.11.222 from 172.18.0.5 iif br-appnet

Ha az a válasz az uplinket nevezi meg, az alagút nincs a képben, és semmilyen alagút oldali beállítás nem segít.

Vigye a vendéget az alagút saját címére

A legkisebb működő változtatás egy kifejezett forrás-átírás kifelé. Szúrja be, ne fűzze hozzá: a Docker már a POSTROUTING élén ül, ezért a -A-val hozzáadott szabály a Dockeré mögött értékelődik ki, és soha nem lép életbe.

iptables -t nat -I POSTROUTING 1 -s 172.18.0.0/16 -o tun0 -j SNAT --to-source 10.8.0.10

Két feltétel dönti el, hogy ez megmarad-e. A címnek olyannak kell lennie, amellyel a kliens valóban rendelkezik, ezért rögzítse egy ügyfelenkénti bejegyzéssel, amely tartalmazza a ifconfig-push 10.8.0.10 255.255.255.0 sort; az olyan szabály, amely soha nem kiosztott címet nevez meg, csendes eldobásokat okoz, nem hibát. És a távoli oldalnak el kell fogadnia ezt a forrást, és vissza kell irányítania a válaszokat, ezért az ottani engedélyezési lista az alagút címét nevezi meg, nem a vendég-alhálózatot. Ha a kliens címe dinamikus, a -j MASQUERADE a -o tun0-val együtt azt követi, amivel az interfész rendelkezik, annak a távoli házirendnek az árán, amely ellen nem írhat fix értéket.

A szűrés a másik fél. A Docker a FORWARD házirendet drop-ra állítja, és minden démon-újraindításkor kiüríti a saját láncait, ezért a helyi házirendet a DOCKER-USER-ba tegye, amely túlél:

iptables -I DOCKER-USER -i br-appnet -o tun0 -j ACCEPT
iptables -I DOCKER-USER -i tun0 -o br-appnet -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

A visszatérési szabály számít: a tun0-ra érkező válasz egy híd által nyitott kapcsolathoz nem attól fogadódik el, hogy a kifelé irány elfogadott volt.

Tartsa a hostot közvetlenül egy forrásszabállyal

Amikor az egész hídnak az alagutat kell használnia, de a hoston semmi másnak nem, hagyja ki a NAT-ot, és adjon annak a forrásnak saját táblát. A vendégcímek így végig láthatók maradnak.

echo "200 vpnbox" >> /etc/iproute2/rt_tables
ip rule add from 172.18.0.0/16 lookup vpnbox pref 1000
ip route add default dev tun0 table vpnbox

A szabályokat a fő tábla előtt kérdezik, és a from illeszkedik a forrásra. Az alagút saját külső csomagjai a host fizikai forrását hordozzák, ezért soha nem illeszkednek a from 172.18.0.0/16-ra, és az alagút nem tudja magát visszairányítani önmagába. Ez az önkizárás teszi stabillá az elrendezést.

A visszaútnak most segítség kell. A távoli oldal egy le nem fordított 172.18.0.x címet lát, és nincs oka tudni, hol lakik. A szerveren az ügyfelenkénti fájlnak iroute 172.18.0.0 255.255.0.0 kell, hogy a szerver belső táblája átadja ezt a prefixet ennek a kliensnek, és egy tolt route 172.18.0.0 255.255.0.0 kell, hogy a többi kliens tudja, hogy létezik.

Két ellenőrzés, mielőtt megbízik benne. Futtassa a ip route show default parancsot: a redirect-gateway def1-val a tábla 0.0.0.0/1 és 128.0.0.0/1 útvonalat tart tun0 felé, és a host egyáltalán nem közvetlen, mert ezek a fél-defaultok nyernek anélkül, hogy lecserélnék a default-t. A ip rule add-val hozzáadott szabályok is eltűnnek újraindításkor, ezért vigye őket egy up szkriptbe.

A csomagméret a második hiba, amivel találkozik

Az 1500 bájtos hídinterfész többet ad az alagútnak, mint amennyit el tud vinni, amint a külső UDP- és IP-fejlécek hozzáadódnak. A kis cserék átmennek, így a DNS feloldódik és a TLS-kézfogás befejeződik, majd egy nagyobb feltöltés mindenhol hiba nélkül megakad. A küldő ugyanazt a szegmensméretet ismétli, mert az ICMP üzenet a töredezettség szükségességéről, amely megmondaná neki, hogy csökkentsen, soha nem érkezik meg.

Javítsa az interfészen, az MSS-en vagy mindkettőn. A szorítás nem igényel együttműködést a vendégtől:

ip link set dev tun0 mtu 1400
iptables -t mangle -A FORWARD -o tun0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

A szorítás csak a TCP-t írja át. Az UDP-nek, a QUIC-kel együtt, inkább alacsonyabb vendéginterfész kell, a --opt com.docker.network.driver.mtu=1400-val a hálózat létrehozásakor vagy a megfelelő compose-kulccsal.

DNS és az ismétlésre érdemes ellenőrzések

A névfeloldás ugyanazt az utat követi. A Docker beágyazott feloldója a 127.0.0.11 címen a host beállított szervereihez továbbít, így a konténer azt örökli, amit a host használ. Amikor a privát zónára csak az alagúton elérhető feloldó válaszol, irányítsa a vendéget arra a címre, és a getent hosts-val teszteljen a konténeren belül, ne a hoston.

  • Futtassa a sikertelen kérést a vendégen belül; a host oldali teszt más forráscímet használ, és elrejti a problémát.
  • Olvassa le a hozzáadott NAT- és szűrőszabályok számlálóit. A nulla egyezésű szabály útvonalazási hiba, nem házirend-hiba.
  • Erősítse meg, hogy az SNAT-szabályában szereplő alagútcím az, amellyel a kliens valóban rendelkezik.
  • Csökkentse a vendég MTU-ját, vagy szorítsa meg az MSS-t, mielőtt a szervert hibáztatná a megakadásért.

Menjen végig a listán, és álljon meg az első hibánál. Azt a réteget kell javítani; bármi, amit lejjebb adnak hozzá, csak elrejti a határt, amely eltörik.

Kapcsolódó cikkek