Kvifor ein macvlan-container ikkje kan svare ein VPN-klient
Ein macvlan-container kan ikkje snakke med sin eigen vert, og svara kan gå ut gjennom feil gateway. Legg til ei shim-rute på vertssida og vel deretter ein kildemodell.
Sjå føre deg ein Linux-vert som avsluttar ein VPN og samstundes køyrer ein container på eit macvlan-nettverk. LAN-et er 192.168.60.0/24, containeren har 192.168.60.210, og VPN-klientar kjem frå 10.95.0.0/24. Klienten når tenesta, svaret kjem aldri tilbake, og kvar brannmurregel på verten ser korrekt ut. To separate avgrensingar skaper dette symptomet, og når ein rettar den eine, blir den andre ståande.
To avgrensingar, eitt symptom
Den første avgrensinga er isolasjon: macvlan-drivaren til Docker lèt ikkje ein container snakke med sin eigen vert gjennom foreldregrensesnittet. Trafikken mellom stabelen til verten og containeren har ingen veg, uansett korleis rutene på verten er skrivne.
Den andre avgrensinga er returvegen. Standard-gatewayen til containeren er vanlegvis LAN-rutaren, så eit svar som er adressert til ein VPN-klient går ut gjennom den rutaren. Viss rutaren ikkje har noka rute tilbake til VPN-poolen, blir svaret kasta ein stad i midten.
Dei to feila ser identiske ut frå klienten: ein førespurnad som kjem og eit svar som aldri kjem. Dei treng ulike reparasjonar, og ein brei masquerade-regel kan skjule kven av dei som framleis er øydelagd. Difor er den første testen eit opptak på containersida i staden for endå ei brannmurordning. Viss førespurnaden aldri dukkar opp der, er det isolasjonsavgrensinga som gjeld.
Bygg shimen på vertssida, smalt
Eit ekstra macvlan-grensesnitt på verten, knytt til same forelder i bru-modus, gjev stabelen til verten sin eigen identitet på det LAN-segmentet. Reserver ein adresse utanfor DHCP-poolen og utanfor containerområdet for det, og rut berre containeren gjennom det.
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
Den første kommandoen opprettar grensesnittet i bru-modus, som er den dokumenterte standarden for denne drivaren og den modusen du vil ha for trafikk mellom vert og container. Den andre tildeler eit /32 slik at adressa ikkje kolliderer med LAN-prefikset, og den fjerde sender berre adressa til containeren gjennom shimen.
Ikkje omdiriger heile LAN-et gjennom det nye grensesnittet. Den vanlege tilkopla ruta blir som ho er, og vertsruta er medvite smal slik at éin container får ein veg utan at resten av segmentet endrar åtferd. Ei standardrute mot shimen ville vore eit anna design med andre følgjer. Hald ho spesifikk, så blir skaderadiusen liten.
Desse kommandoane endrar nettverksinnstillingane på ein køyrande vert. På eit apparat eller ein administrert plattform brukar du den støtta konfigurasjonsmekanismen til den plattformen, fordi ei interaktiv endring i root-shell kanskje ikkje overlever ei oppgradering.
Avgjer korleis kjelda blir verna
Med shimen på plass kan containeren nå verten, og spørsmålet blir kva kjeldeadresse svaret ber. Å verna den opphavlege VPN-kjelda er den reinare modellen: containeren ser den verkelege adressa til klienten, og loggane og tilgangsreglane til tenesta kan bruke henne.
For at det skal verke, må nettverkskonfigurasjonen til containeren sende trafikk for 10.95.0.0/24 til 192.168.60.250 som gateway for denne vegen. Det er ei støtta rute- eller gatewayinnstilling inne i konfigurasjonen til containeren sjølv, ikkje eit triks på vertssida. Stadfest det frå innsida av containeren i staden for å gå ut frå at innstillinga har teke til å gjelde. Ein standard-gateway som framleis peikar på LAN-rutaren vil halde fram med å sende svar i det same holet.
Viss det godkjende designet i staden skjuler VPN-kjeldene, avgrens omsetjinga smalt: den verkelege VPN-poolen, shimen som utgåande grensesnitt, og den konkrete containeren og tenesta.
iptables -t nat -A POSTROUTING -s 10.95.0.0/24 -o macvlan-vpn -j SNAT --to-source 192.168.60.250
Match shimen som egress-grensesnitt, ikkje tunnelen. Ei regel som namngir tunnelen som utgåande grensesnitt vil ikkje matche ein pakke på veg mot containeren, og det er nettopp feilen eit slikt oppsett plar å innehalde. Hald regelen like smal som setninga over, og gå gjennom han når poolen endrar seg.
Verifiser frå klienten, ikkje frå verten
Ein førespurnad frå verten sjølv, bunden til adressa til shimen, provar at shimen kan nå containeren. Han provar ikkje at containeren kan sende trafikk tilbake til ei verna 10.95.0.x-kjelde, fordi kjeldeadressa i den testen er shimen si eiga.
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.210Den første kommandoen testar strekninga frå vert til container, og den andre viser kva som faktisk kryssar shimen medan ein ekte VPN-klient sender førespurnaden. Sjå på kjeldeadressa på vegen inn og om det dukkar opp eit svar med same flyt.
Vidaresending må vere slått på på verten, og vidaresendingsvegen treng ei løyve for VPN-poolen til shimen på tenesteporten samt etablerte svar. Ei INPUT-regel på verten autoriserer ikkje vidaresendt trafikk, og det er ein vanleg grunn til at pakken blir kasta etter at rutinga ser riktig ut.
Køyr den ekte applikasjonen med ekte legitimasjon, og kontroller deretter at ei andre, urelatert teneste på same containeren framleis avviser deg. Viss den einaste måten å få det til å verke var å opne kvar vidaresendingsregel, er designet ikkje ferdig. Noter òg kva kjeldeadresse tenesta registrerte, for det er den eigne tilgangsreglane vil bruke frå no av.