Docker-portpublisering kontra VPN: hvor svaret går hen
En publisert container svarer fra sin egen adresse før omvendt NAT. To design kan holde det svaret på den offentlige veien, med ulike kostnader.
Verten fortsetter å svare på SSH etter at en VPN med full tunnel er oppe, mens en Docker-publisert tjeneste på samme maskin blir stille. Det er ingenting galt med listeneren: containeren kjører, portmappingen finnes, og pakken ankommer. Containeren er frisk, og forespørselen når den faktisk. Det som er forskjellig, er hvor svaret starter når Linux velger ruten sin, og den forskjellen avgjør hvilket av de to designene nedenfor du trenger.
Følg tuple gjennom destinasjons-NAT
Ta en vert på 192.0.2.10 som publiserer TCP 2222 til en container på 172.30.240.5:22. En forespørsel fra 198.51.100.25 oversettes før den når containeren, og containeren svarer som seg selv.
WAN request: 198.51.100.25 -> 192.0.2.10:2222
after DNAT: 198.51.100.25 -> 172.30.240.5:22
container reply: 172.30.240.5:22 -> 198.51.100.25
Ved vertens rutevalg bærer svaret fortsatt containerens kildeadresse. Den omvendte oversettelsen gjenoppretter den publiserte tuple senere, og det er derfor pakken ser feil ut akkurat i det øyeblikket ruten velges.
Hvorfor en regel kun for verten overser det
En regel som bare velger WAN-tabellen for pakker fra 192.0.2.10 dekker vertens egne daemoner og overser dette videresendte svaret helt. Kildeadressen i svaret er 172.30.240.5, ikke verten.
Overkorreksjonen er å rute alt fra containeren gjennom WAN, noe som også fritar containerens urelaterte utgående forbindelser fra VPN-en. Det er en annen policy enn den som ble bedt om, og det overrasker vanligvis noen senere.
Post-DNAT-matching er en annen hook
Dockers dokumentasjon om brannmurer bemerker at vanlig brukerfiltrering ser destinasjonen etter DNAT, så å matche den publiserte porten 2222 i en vanlig regel er ikke det samme som å matche containerporten 22. Hvis den opprinnelige tuple er viktig, bruk den støttede opprinnelige-destinasjon-mekanismen i stedet for å gjette hvilken port som er synlig.
Denne hook-forvirringen produserer regler som ser riktige ut og aldri matcher. Sjekk tellerne på selve regelen før du skriver om policyen. En regel uten treff forteller deg at den evalueres et sted der pakken aldri når fram.
Design A: bær beslutningen som tilstand på forbindelsen
Et forbindelsesmerke kan bære inngangsbeslutningen gjennom oversettelsen, men det må gjenopprettes på pakken før det ruteoppslaget som betyr noe. Trinnene er:
- Reserver et merkefelt og en regelprioritet som ikke kolliderer med Docker, VPN-en eller en annen policyeier.
- Identifiser bare den tiltenkte nye WAN-forbindelsen på et punkt før DNAT der forbindelsessporing er tilgjengelig.
- Registrer beslutningen på forbindelsesmerket, uten å tvinge selve den opprinnelige forespørselen inn i WAN-tabellen.
- I retning svaret, gjenopprett bare dine egne merkebits på pakken før ruting.
- Velg en komplett WAN-tabell tidlig nok til at en VPN-regel ikke kan vinne først.
Den tabellen trenger de faktiske tilkoblede rutene og gatewayen. Den trenger også definert atferd når ruten mangler. Stille fall i tunnelen er det verste utfallet, fordi konfigurasjonen fortsatt ser ut til å virke. Feil lukket i stedet og logg det.
Design B: terminer på verten
En bevisst konfigurert frontend på vertssiden, som en TCP-proxy eller en omvendt proxy foran containeren, holder svaret med opprinnelse i vertens adresse. Regler skrevet for verten oppfører seg da som forventet, og containeren blir på sitt private nettverk.
Prisen er enda en bevegelig del med sin egen konfigurasjon, håndtering av kildeadresser og tilgangskontroll. Det er vanligvis den enklere støttede grensen, og det er ofte det riktige svaret når rutepolicyen skulle vedlikeholdes av én person som kan komme til å slutte.
Verifiser endringen, ikke hensikten
Åpne en ny autorisert forbindelse fra den offentlige siden, og bekreft at svaret forlater det tiltenkte grensesnittet. Sjekk deretter at en urelatert forespørsel som containeren starter, fortsatt følger VPN-en.
Ikke tøm maskinens forbindelsestabell for å teste én regel: eksisterende oppføringer beholder sin tidligere mapping, og tømmingen ødelegger alt annet på verten. Å publisere en port definerer nåbarhet. Det definerer ikke svarveien. Skriv ned det valgte designet med tabellnavnene, slik at neste person ikke må gjenoppdage det under en hendelse.