Įsivaizduokite Linux hostą, kuris užbaigia VPN ir tuo pačiu metu paleidžia konteinerį macvlan tinkle. LAN yra 192.168.60.0/24, konteineris turi 192.168.60.210, o VPN klientai ateina iš 10.95.0.0/24. Klientas pasiekia paslaugą, atsakymas niekada negrįžta, o kiekviena ugniasienės taisyklė hoste atrodo teisinga. Šį simptomą sukelia du atskiri apribojimai, o sutaisius vieną kitas lieka savo vietoje.

Du apribojimai, vienas simptomas

Pirmasis apribojimas yra izoliacija: Docker macvlan tvarkyklė neleidžia konteineriui kalbėtis su savo pačiu hostu per pagrindinę sąsają. Srautas tarp hosto krūvos ir konteinerio neturi kelio, kad ir kaip būtų užrašyti maršrutai hoste.

Antrasis apribojimas yra grįžimo kelias. Konteinerio numatytasis šliuzas paprastai yra LAN maršrutizatorius, todėl VPN klientui adresuotas atsakymas išeina per tą maršrutizatorių. Jei maršrutizatorius neturi maršruto atgal į VPN telkinį, atsakymas numetamas kažkur viduryje.

Abu gedimai iš kliento pusės atrodo vienodai: užklausa ateina, o atsakymas niekada neateina. Jiems reikia skirtingų taisymų, o plati masquerade taisyklė gali paslėpti, kuris iš jų dar sulūžęs. Todėl pirmasis bandymas yra fiksavimas konteinerio pusėje, o ne dar vienas ugniasienės pakeitimas. Jei užklausa ten niekada nepasirodo, galioja izoliacijos apribojimas.

Sukurkite hosto pusės shim siaurai

Antroji macvlan sąsaja hoste, prijungta prie tos pačios pagrindinės sąsajos tilto režimu, suteikia hosto krūvai savo tapatybę tame LAN segmente. Rezervuokite jai adresą už DHCP telkinio ir už konteinerio diapazono ribų, o pro ją leiskite tik konteinerį.

ip link add macvlan-vpn link eth0 type macvlan mode bridge
ip address add 192.168.60.250/32 dev macvlan-vpn
ip link set macvlan-vpn up
ip route add 192.168.60.210/32 dev macvlan-vpn src 192.168.60.250

Pirmoji komanda sukuria sąsają tilto režimu, kuris yra dokumentuotas šios tvarkyklės numatytasis nustatymas ir režimas, kurio norite srautui tarp hosto ir konteinerio. Antroji priskiria /32, kad adresas nesusidurtų su LAN priešdėliu, o ketvirtoji per shim siunčia tik konteinerio adresą.

Neperadresuokite viso LAN per naują sąsają. Įprastas prijungtas maršrutas lieka toks, koks yra, o hosto maršrutas sąmoningai siauras, kad vienas konteineris gautų kelią, o likusi segmento dalis nekeistų savo elgsenos. Numatytasis maršrutas į shim būtų kitokia konstrukcija su kitokiomis pasekmėmis. Laikykite jį konkretų, ir žalos spindulys lieka mažas.

Šios komandos keičia tinklo nustatymus veikiančiame hoste. Įrenginyje ar valdomoje platformoje naudokite tos platformos palaikomą konfigūravimo mechanizmą, nes interaktyvus pakeitimas root-shell aplinkoje gali neišgyventi atnaujinimo.

Nuspręskite, kaip išsaugomas šaltinis

Kai shim yra vietoje, konteineris gali pasiekti hostą, ir kyla klausimas, kokį šaltinio adresą neša atsakymas. Originalaus VPN šaltinio išsaugojimas yra švaresnis modelis: konteineris mato tikrąjį kliento adresą, o paslaugos žurnalai ir prieigos taisyklės gali juo naudotis.

Kad tai veiktų, konteinerio tinklo konfigūracija šiam keliui turi siųsti 10.95.0.0/24 srautą į 192.168.60.250 kaip savo šliuzą. Tai palaikomas maršruto ar šliuzo nustatymas pačios konteinerio konfigūracijos viduje, o ne hosto pusės gudrybė. Patvirtinkite jį konteinerio viduje, o ne manykite, kad nustatymas įsigaliojo. Numatytasis šliuzas, kuris vis dar rodo į LAN maršrutizatorių, toliau siųs atsakymus į tą pačią skylę.

Jei patvirtinta konstrukcija vietoj to slepia VPN šaltinius, susiaurinkite vertimą: tikrasis VPN telkinys, shim kaip išeinanti sąsaja ir konkretus konteineris bei paslauga.

iptables -t nat -A POSTROUTING -s 10.95.0.0/24 -o macvlan-vpn -j SNAT --to-source 192.168.60.250

Suderinkite shim kaip išėjimo sąsają, o ne tunelį. Taisyklė, kuri tunelį vadina išeinančia sąsaja, nesutaps su paketu, einančiu link konteinerio, ir būtent ši klaida paprastai būna tokioje sąrangoje. Laikykite taisyklę tokią siaurą kaip aukščiau esantis sakinys ir peržiūrėkite ją, kai telkinys pasikeis.

Tikrinkite iš kliento, o ne iš hosto

Užklausa iš paties hosto, susieta su shim adresu, įrodo, kad shim gali pasiekti konteinerį. Ji neįrodo, kad konteineris gali grąžinti srautą išsaugotam 10.95.0.x šaltiniui, nes to bandymo šaltinio adresas yra paties shim.

curl -sS --interface 192.168.60.250 -o /dev/null -w '%{http_code}\n' http://192.168.60.210:8080/health
sudo tcpdump -ni macvlan-vpn host 192.168.60.210

Pirmoji komanda tikrina atkarpą nuo hosto iki konteinerio, o antroji parodo, kas iš tikrųjų praeina per shim, kol tikras VPN klientas siunčia užklausą. Pažiūrėkite į šaltinio adresą įėjimo kelyje ir ar atsakymas pasirodo tuo pačiu srautu.

Hoste turi būti įjungtas persiuntimas, o persiuntimo keliui reikia leidimo VPN telkiniui į shim paslaugos prievade bei nustatytų atsakymų. Hoste esanti INPUT taisyklė neleidžia persiunčiamo srauto, ir tai dažna priežastis, kodėl paketas numetamas po to, kai maršrutizavimas atrodo teisingas.

Paleiskite tikrą programą su tikrais kredencialais, tada patikrinkite, ar antroji, nesusijusi paslauga tame pačiame konteineryje vis dar jums atsisako. Jei vienintelis būdas priversti tai veikti buvo atidaryti kiekvieną persiuntimo taisyklę, konstrukcija nebaigta. Taip pat atkreipkite dėmesį, kokį šaltinio adresą paslauga užregistravo, nes būtent jį naudos jos pačios prieigos taisyklės.

Susiję straipsniai