Kā maršrutēt tikai Docker konteineru datplūsmu caur OpenVPN
Atstājiet resursdatoru tā parastajā uplink un ievietojiet vienu konteineru apakštīklu tunelī: NAT secība, avota noteikumi, OpenVPN iroute un MSS pārbaudes.
Konteineru pakete nekad nesasniedz tun0 un papildu iespējas konteinerā to nemainīs. Starp viesi un tuneli ir divas maršruta meklēšanas: viena viesa tīkla nosaukumtelpā, otra resursdatorā pēc tam, kad kadrs nonāk uz tilta, un otrā vaicā citai tabulai ar citiem atbilstības noteikumiem. Mans atsauces izvietojums ir Linux resursdators, kurā darbojas OpenVPN klients, kas tur 10.8.0.10 uz tun0, Docker tilts uz 172.18.0.0/16, un privāta adrese, ko sasniedz tikai tuneļa puse. Mērķis paliek šaurs: tas viesa apakštīkls iziet caur tuneli, kamēr resursdators saglabā parasto uplink.
VPN klienta darbināšana konteinerā ir cits dizains, nevis saīsne. Tad konteiners pārvalda savu tuneli un akreditācijas datus, un darbs pārceļas uz Dockerfile, nevis paliek iptables.
Pāradresēšana izvēlas maršrutu pēc galamērķa, tad NAT pārraksta avotu
Kad ir iestatīts net.ipv4.ip_forward=1 , pāradresētā pakete tiek maršrutēta tikai pēc galamērķa galvenajā tabulā. Avots šajā lēmumā nespēlē nekādu lomu. Tikai pēc maršruta izvēles kodols izpilda POSTROUTING , un tieši tur atrodas paša Docker noteikums: -s 172.18.0.0/16 ! -o br-appnet -j MASQUERADE . Viss, kas atstāj tiltu uz citu saskarni, tiek tulkots, un adrese, kurā tas pārvēršas, ir atkarīga no saskarnes, uz kuru maršruts to nosūtīja.
Šis noteikums izskaidro lielāko daļu simptomu, par kuriem man jautā. Ja galvenajā tabulā nav maršruta uz privāto galamērķi, pakete iziet pa uplink ar resursdatora fizisko adresi. Jūsu pakalpojumu sniedzējs atmet galamērķi, vai attālinātā vietne atmet RFC 1918 avotu, ko tā nekad nav gaidījusi, un konteiners pārsniedz laiku, kamēr tunelis paliek augšā un vesels. Uzņemšana uz tun0 neko neparāda, un tā ir pazīme. Ja maršruts tiešām norāda uz tun0 , MASQUERADE pārraksta avotu uz 10.8.0.10 , un tas pats konteiners darbojas, jums neko neaiztiekot.
Pieprasiet meklēšanu, kas nosauc viesa avotu. Bez from un iif resursdators atbild par savu ligzdu un ziņo ceļu, ko pāradresētā pakete nekad neies:
ip route get 192.168.11.222 from 172.18.0.5 iif br-appnetJa šī atbilde nosauc uplink, tunelis nav attēlā, un neviena tuneļa puses iestatīšana nepalīdzēs.
Pārvietojiet viesi uz paša tuneļa adresi
Mazākā strādājošā izmaiņa ir skaidra avota pārrakstīšana izejā. Ievietojiet to, nevis pievienojiet beigās: Docker jau sēž POSTROUTING galvgalī, tāpēc noteikums, kas pievienots ar -A , tiek vērtēts aiz Docker noteikuma un nekad neiedarbojas.
iptables -t nat -I POSTROUTING 1 -s 172.18.0.0/16 -o tun0 -j SNAT --to-source 10.8.0.10Vai tas noturēsies, izšķir divi nosacījumi. Adresei jābūt tai, kas klientam tiešām ir, tāpēc piespraudiet to ar ierakstu katram klientam, kas satur ifconfig-push 10.8.0.10 255.255.255.0 ; noteikums, kas nosauc nekad nepiešķirtu adresi, rada klusus nomešanas gadījumus, nevis kļūdu. Un attālinātajai pusei ir jāpieņem šis avots un jāmaršrutē atbildes atpakaļ, tāpēc atļauto saraksts tur nosauc tuneļa adresi, nevis viesa apakštīklu. Kad klienta adrese ir dinamiska, -j MASQUERADE ar -o tun0 seko tam, kas ir saskarnei, par cenu attālinātai politikai, pret kuru jūs nevarat rakstīt fiksētu vērtību.
Filtrēšana ir otra puse. Docker iestata FORWARD politiku uz drop un katrā dēmona restartā iztīra ķēdes, kas tam pieder, tāpēc ievietojiet vietējo politiku DOCKER-USER , kas izdzīvo:
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 ACCEPTAtgriešanās noteikums ir svarīgs: atbilde, kas ierodas uz tun0 tiltam atvērtam savienojumam, netiek pieņemta tikai tāpēc, ka izejas virziens tika pieņemts.
Turiet resursdatoru tiešu ar avota noteikumu
Kad visam tiltam jāizmanto tunelis, bet nekam citam resursdatorā nevajadzētu, izlaidiet NAT un dodiet šim avotam savu tabulu. Viesa adreses tad paliek redzamas no gala līdz galam.
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 vpnboxNoteikumi tiek izskatīti pirms galvenās tabulas, un from atbilst avotam. Paša tuneļa ārējās paketes nes resursdatora fizisko avotu, tāpēc tās nekad neatbilst from 172.18.0.0/16 , un tunelis nevar maršrutēt sevi atpakaļ sevī. Tieši šī pašizslēgšana padara izvietojumu stabilu.
Atgriešanās ceļam tagad vajag palīdzību. Attālinātā puse redz neiztulkotu 172.18.0.x un tai nav pamata zināt, kur tas dzīvo. Serverī failam katram klientam vajag iroute 172.18.0.0 255.255.0.0 , lai servera iekšējā tabula nodotu šo prefiksu šim klientam, un iebīdītu route 172.18.0.0 255.255.0.0 , lai citi klienti zinātu, ka tas pastāv.
Divi pārbaudes pirms uzticēties. Palaidiet ip route show default : ar redirect-gateway def1 tabulā ir 0.0.0.0/1 un 128.0.0.0/1 caur tun0 , un resursdators nemaz nav tiešs, jo šie pusnoklusējumi uzvar, neaizstājot default . Noteikumi, kas pievienoti ar ip rule add , arī pazūd pēc pārstartēšanas, tāpēc nesiet tos up skriptā.
Paketes izmērs ir otrā kļūme, ar ko saskaraties
Tilta saskarne ar 1500 baitiem dod tunelim vairāk, nekā tas var iznest, kad tiek pievienotas ārējās UDP un IP galvenes. Mazapmaiņas iet cauri, tāpēc DNS atrisinās un TLS rokasspiediens pabeidzas, tad lielāka augšupielāde iekaras bez jebkādas kļūdas. Sūtītājs atkārto to pašu segmenta izmēru, jo ICMP ziņojums par sadalīšanas nepieciešamību, kas tam pateiktu samazināt, nekad neierodas.
Novērsiet to saskarnē, MSS vai abos. Saspiešanai nav vajadzīga viesa sadarbība:
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-pmtuSaspiešana pārraksta tikai TCP. UDP, tostarp QUIC, tā vietā vajag zemāku viesa saskarni, ar --opt com.docker.network.driver.mtu=1400 tīkla izveides laikā vai atbilstošo compose atslēgu.
DNS un pārbaudes, ko ir vērts atkārtot
Nosaukumu atrisināšana iet to pašu ceļu. Docker iebūvētais risinātājs 127.0.0.11 pārsūta uz resursdatora konfigurētajiem serveriem, tāpēc konteiners manto to, ko izmanto resursdators. Kad privāto zonu atbild tikai caur tuneli sasniedzams risinātājs, vērsiet viesi uz šo adresi, un pārbaudiet ar getent hosts konteinera iekšpusē, nevis resursdatorā.
- Palaidiet neveiksmīgo pieprasījumu viesa iekšpusē; resursdatora puses tests izmanto citu avota adresi un paslēpj problēmu.
- Lasiet skaitītājus uz NAT un filtra noteikumiem, ko pievienojāt. Noteikums bez vienas atbilstības ir maršrutēšanas kļūda, nevis politikas kļūda.
- Apstipriniet, ka jūsu SNAT noteikuma tuneļa adrese ir tā, kas klientam tiešām ir.
- Pazeminiet viesa MTU vai saspiediet MSS, pirms vainojat serveri aizķeršanā.
Izejiet sarakstu un apstājieties pie pirmās kļūmes. Tieši tas slānis ir jālabo; viss, kas pievienots tālāk, tikai paslēpj robežu, kas lūzt.