Docker-poorten publiceren versus de VPN: waar de reactie heen gaat
Een gepubliceerde container antwoordt vanuit zijn eigen adres vóór reverse NAT. Twee ontwerpen kunnen dat antwoord op het openbare pad houden, met verschillende kosten.
De host blijft SSH beantwoorden nadat een VPN met volledige tunnel omhoogkomt, terwijl een met Docker gepubliceerde dienst op dezelfde machine stilvalt. Er is niets mis met de listener: de container draait, de poorttoewijzing bestaat en het pakket komt aan. De container is gezond en het verzoek bereikt hem echt. Wat verschilt, is waar het antwoord begint wanneer Linux zijn route kiest, en dat verschil bepaalt welk van de twee ontwerpen hieronder je nodig hebt.
Volg de tuple door de bestemmings-NAT
Neem een host op 192.0.2.10 die TCP 2222 publiceert naar een container op 172.30.240.5:22. Een verzoek van 198.51.100.25 wordt vertaald voordat het de container bereikt, en de container antwoordt als zichzelf.
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
Bij de routebeslissing van de host draagt het antwoord nog het bronadres van de container. De omgekeerde vertaling herstelt het gepubliceerde tuple later, en daarom ziet het pakket er precies op het moment dat de route wordt gekozen verkeerd uit.
Waarom een regel alleen voor de host het mist
Een regel die de WAN-tabel alleen kiest voor pakketten van 192.0.2.10 dekt de eigen daemons van de host en mist dit doorgestuurde antwoord volledig. Het bronadres op het antwoord is 172.30.240.5, niet de host.
De overcorrectie is alles van de container via de WAN routeren, waardoor ook de niet-verwante uitgaande verbindingen van de container buiten de VPN vallen. Dat is een ander beleid dan gevraagd, en het verrast later meestal iemand.
Post-DNAT-matching is een andere hook
De documentatie van Docker over firewalls merkt op dat gewone gebruikersfiltering de bestemming na de DNAT ziet, dus de gepubliceerde poort 2222 in een normale regel matchen is niet hetzelfde als containerpoort 22 matchen. Als het oorspronkelijke tuple belangrijk is, gebruik dan het ondersteunde oorspronkelijke-bestemming-mechanisme in plaats van te raden welke poort zichtbaar is.
Deze hookverwarring levert regels op die er correct uitzien en nooit matchen. Controleer de tellers op de regel zelf voordat je het beleid herschrijft. Een regel zonder treffers vertelt je dat hij wordt geëvalueerd op een plek waar het pakket nooit komt.
Ontwerp A: de beslissing als verbindingsstatus dragen
Een verbindingsmarkering kan de inkomende beslissing door de vertaling dragen, maar moet vóór de routeopzoeking die ertoe doet weer op het pakket staan. De stappen zijn:
- Reserveer een markeringsveld en regelprioriteit die niet botsen met Docker, de VPN of een andere beleidseigenaar.
- Identificeer alleen de bedoelde nieuwe WAN-verbinding op een punt vóór DNAT waar verbindingsregistratie beschikbaar is.
- Leg de beslissing vast op de verbindingsmarkering, zonder het oorspronkelijke verzoek zelf naar de WAN-tabel te dwingen.
- Herstel in de antwoordrichting alleen je eigen markeringsbits op het pakket vóór het routeren.
- Kies een volledige WAN-tabel vroeg genoeg zodat een VPN-regel niet als eerste kan winnen.
Die tabel heeft de echte verbonden routes en de gateway nodig. Hij heeft ook gedefinieerd gedrag nodig wanneer de route ontbreekt. Stil in de tunnel vallen is de slechtste uitkomst, omdat de configuratie er nog steeds werkend uitziet. Faal in plaats daarvan gesloten en log het.
Ontwerp B: op de host termineren
Een bewust geconfigureerde frontend aan de hostkant, zoals een TCP-proxy of een reverse proxy vóór de container, houdt het antwoord afkomstig van het hostadres. Regels die voor de host zijn geschreven gedragen zich dan zoals verwacht, en de container blijft op zijn privénetwerk.
De prijs is nog een bewegend onderdeel met eigen configuratie, bronadresafhandeling en toegangscontroles. Het is meestal de eenvoudigere ondersteunde grens, en het is vaak het juiste antwoord wanneer het routeringsbeleid door één persoon zou worden onderhouden die misschien vertrekt.
Verifieer de wijziging, niet de bedoeling
Open een nieuwe geautoriseerde verbinding vanaf de openbare kant en bevestig dat het antwoord de bedoelde interface verlaat. Controleer daarna of een niet-verwant verzoek dat de container start nog steeds de VPN volgt.
Leeg de verbindingstabel van de machine niet om één regel te testen: bestaande vermeldingen houden hun eerdere toewijzing, en het legen breekt al het andere op de host. Een poort publiceren definieert bereikbaarheid. Het definieert niet het antwoordpad. Schrijf het gekozen ontwerp op met de tabelnamen, zodat de volgende persoon het niet tijdens een incident opnieuw hoeft te ontdekken.