Hvorfor en macvlan-container ikke kan svare en VPN-klient
En macvlan-container kan ikke tale med sin egen vært, og dens svar kan forlade netværket gennem den forkerte gateway. Tilføj en shim-rute på værtssiden, og vælg derefter en kildemodel.
Forestil dig en Linux-vært, der afslutter en VPN og samtidig kører en container på et macvlan-netværk. 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 aldrig tilbage, og hver firewallregel på værten ser korrekt ud. To separate begrænsninger skaber det symptom, og når man retter den ene, bliver den anden på sin plads.
To begrænsninger, ét symptom
Den første begrænsning er isolation: Dockers macvlan-driver tillader ikke, at en container taler med sin egen vært gennem moderinterfacet. Trafik mellem værtens stak og containeren har ingen vej, uanset hvordan ruterne på værten er skrevet.
Den anden begrænsning er returvejen. Containerens standardgateway er normalt LAN-routeren, så et svar adresseret til en VPN-klient forlader netværket gennem den router. Hvis routeren ikke har en rute tilbage til VPN-puljen, bliver svaret kasseret et sted midt på vejen.
De to fejl ser identiske ud fra klienten: en anmodning, der ankommer, og et svar, der aldrig kommer. De kræver forskellige reparationer, og en bred masquerade-regel kan skjule, hvilken af dem der stadig er i stykker. Derfor er den første test en optagelse på containerens side i stedet for endnu en firewallændring. Hvis anmodningen aldrig dukker op der, er det isolationsbegrænsningen, der er i spil.
Byg shimmen på værtssiden, snævert
Et ekstra macvlan-interface på værten, knyttet til den samme moder i bridge-tilstand, giver værtens stak sin egen identitet på det LAN-segment. Reserver en adresse uden for DHCP-puljen og uden for containerens område til den, og rut kun containeren gennem 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 kommando opretter interfacet i bridge-tilstand, som er den dokumenterede standard for denne driver og den tilstand, du vil have til trafik mellem vært og container. Den anden tildeler et /32, så adressen ikke kolliderer med LAN-præfikset, og den fjerde sender kun containerens adresse gennem shimmen.
Omdiriger ikke hele LAN'et gennem det nye interface. Den almindelige tilsluttede rute forbliver som den er, og værtsruten er bevidst snæver, så en container får en vej, uden at resten af segmentet ændrer adfærd. En standardrute mod shimmen ville være et andet design med andre konsekvenser. Hold den specifik, så forbliver skadesradiusen lille.
Disse kommandoer ændrer netværket på en kørende vært. På et apparat eller en administreret platform skal du bruge den pågældende platforms understøttede konfigurationsmekanisme, fordi en interaktiv ændring via root-shell måske ikke overlever en opgradering.
Beslut, hvordan kilden bevares
Med shimmen på plads kan containeren nå værten, og spørgsmålet bliver, hvilken kildeadresse svaret bærer. At bevare den oprindelige VPN-kilde er den renere model: containeren ser klientens rigtige adresse, og tjenestens logfiler og adgangsregler kan bruge den.
For at det skal virke, skal containerens netværkskonfiguration sende trafik for 10.95.0.0/24 til 192.168.60.250 som sin gateway for denne vej. Det er en understøttet rute- eller gatewayindstilling inde i containerens egen konfiguration, ikke et trick på værtssiden. Bekræft det inde fra containeren i stedet for at antage, at indstillingen har fået virkning. En standardgateway, der stadig peger på LAN-routeren, vil fortsætte med at sende svar ned i det samme hul.
Hvis det godkendte design i stedet skjuler VPN-kilderne, skal du afgrænse oversættelsen snævert: den rigtige VPN-pulje, shimmen som det udgående interface og den konkrete container og tjeneste.
iptables -t nat -A POSTROUTING -s 10.95.0.0/24 -o macvlan-vpn -j SNAT --to-source 192.168.60.250
Match shimmen som egress-interface, ikke tunnelen. En regel, der udpeger tunnelen som det udgående interface, matcher ikke en pakke på vej mod containeren, og det er netop den fejl, denne slags opsætning plejer at indeholde. Hold reglen lige så snæver som sætningen ovenfor, og gennemgå den, når puljen ændrer sig.
Verificer fra klienten, ikke fra værten
En anmodning fra værten selv, bundet til shimmens adresse, beviser, at shimmen kan nå containeren. Den beviser ikke, at containeren kan sende trafik tilbage til en bevaret 10.95.0.x-kilde, fordi kildeadressen i den test er shimmens 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.210Den første kommando tester benet fra vært til container, og den anden viser, hvad der faktisk krydser shimmen, mens en rigtig VPN-klient sender anmodningen. Se på kildeadressen på vejen ind, og om der dukker et svar op med samme flow.
Videresendelse skal være aktiveret på værten, og videresendelsesvejen har brug for en tilladelse for VPN-puljen til shimmen på tjenesteporten plus etablerede svar. En INPUT-regel på værten autoriserer ikke videresendt trafik, hvilket er en almindelig grund til, at pakken kasseres, efter at rutningen ser korrekt ud.
Kør den rigtige applikation med rigtige legitimationsoplysninger, og kontroller derefter, at en anden, urelateret tjeneste på den samme container stadig afviser dig. Hvis den eneste måde at få det til at virke var at åbne hver videresendelsesregel, er designet ikke færdigt. Noter også, hvilken kildeadresse tjenesten registrerede, for det er den, dens egne adgangsregler vil bruge fremover.