Se for deg en Linux-vert som avslutter en VPN og samtidig kjører en container på et macvlan-nettverk. LAN-et er 192.168.60.0/24, containeren har 192.168.60.210, og VPN-klienter kommer fra 10.95.0.0/24. Klienten når tjenesten, svaret kommer aldri tilbake, og hver brannmurregel på verten ser korrekt ut. To separate begrensninger skaper det symptomet, og når man retter den ene, blir den andre stående.

To begrensninger, ett symptom

Den første begrensningen er isolasjon: Docker sin macvlan-driver lar ikke en container snakke med sin egen vert gjennom foreldregrensesnittet. Trafikk mellom vertens stabel og containeren har ingen vei, uansett hvordan rutene på verten er skrevet.

Den andre begrensningen er returveien. Containerens standard-gateway er vanligvis LAN-ruteren, så et svar adressert til en VPN-klient går ut gjennom den ruteren. Hvis ruteren ikke har noen rute tilbake til VPN-poolen, blir svaret forkastet et sted i midten.

De to feilene ser identiske ut fra klienten: en forespørsel som ankommer og et svar som aldri kommer. De trenger forskjellige reparasjoner, og en bred masquerade-regel kan skjule hvilken av dem som fortsatt er ødelagt. Derfor er den første testen en opptak på containersiden i stedet for nok en brannmurendring. Hvis forespørselen aldri dukker opp der, er det isolasjonsbegrensningen som gjelder.

Bygg shimen på vertssiden, smalt

Et ekstra macvlan-grensesnitt på verten, knyttet til samme forelder i bro-modus, gir vertens stabel sin egen identitet på det LAN-segmentet. Reserver en adresse utenfor DHCP-poolen og utenfor containerområdet for den, og rut bare containeren gjennom den.

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 oppretter grensesnittet i bro-modus, som er den dokumenterte standarden for denne driveren og modusen du vil ha for trafikk mellom vert og container. Den andre tildeler et /32 slik at adressen ikke kolliderer med LAN-prefikset, og den fjerde sender bare containerens adresse gjennom shimen.

Ikke omdiriger hele LAN-et gjennom det nye grensesnittet. Den vanlige tilkoblede ruten blir som den er, og vertsruten er bevisst smal slik at én container får en vei uten at resten av segmentet endrer atferd. En standardrute mot shimen ville vært et annet design med andre konsekvenser. Hold den spesifikk, så blir skaderadiusen liten.

Disse kommandoene endrer nettverksinnstillingene på en kjørende vert. På et apparat eller en administrert plattform bruker du den støttede konfigurasjonsmekanismen til den plattformen, fordi en interaktiv endring i root-shell kanskje ikke overlever en oppgradering.

Bestem hvordan kilden bevares

Med shimen på plass kan containeren nå verten, og spørsmålet blir hvilken kildeadresse svaret bærer. Å bevare den opprinnelige VPN-kilden er den renere modellen: containeren ser klientens virkelige adresse, og tjenestens logger og tilgangsregler kan bruke den.

For at det skal virke, må containerens nettverkskonfigurasjon sende trafikk for 10.95.0.0/24 til 192.168.60.250 som gateway for denne veien. Det er en støttet rute- eller gatewayinnstilling inne i containerens egen konfigurasjon, ikke et triks på vertssiden. Bekreft det fra innsiden av containeren i stedet for å anta at innstillingen har trådt i kraft. En standard-gateway som fortsatt peker på LAN-ruteren vil fortsette å sende svar i det samme hullet.

Hvis det godkjente designet i stedet skjuler VPN-kildene, avgrens oversettelsen smalt: den virkelige VPN-poolen, shimen som utgående grensesnitt, og den konkrete containeren og tjenesten.

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, ikke tunnelen. En regel som navngir tunnelen som utgående grensesnitt vil ikke matche en pakke på vei mot containeren, og det er nettopp feilen en slik oppsett pleier å inneholde. Hold regelen like smal som setningen over, og gjennomgå den når poolen endres.

Verifiser fra klienten, ikke fra verten

En forespørsel fra verten selv, bundet til shimens adresse, beviser at shimen kan nå containeren. Den beviser ikke at containeren kan sende trafikk tilbake til en bevart 10.95.0.x-kilde, fordi kildeadressen i den testen er shimens egen.

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

Den første kommandoen tester strekningen fra vert til container, og den andre viser hva som faktisk krysser shimen mens en ekte VPN-klient sender forespørselen. Se på kildeadressen på veien inn og om det dukker opp et svar med samme flyt.

Videresending må være aktivert på verten, og videresendingsveien trenger en tillatelse for VPN-poolen til shimen på tjenesteporten samt etablerte svar. En INPUT-regel på verten autoriserer ikke videresendt trafikk, og det er en vanlig grunn til at pakken forkastes etter at rutingen ser riktig ut.

Kjør den ekte applikasjonen med ekte legitimasjon, og kontroller deretter at en andre, urelatert tjeneste på samme container fortsatt avviser deg. Hvis den eneste måten å få det til å virke var å åpne hver videresendingsregel, er designet ikke ferdig. Noter også hvilken kildeadresse tjenesten registrerte, for det er den egne tilgangsregler vil bruke fra nå av.

Relaterte artikler