Het verzoek komt aan met het tunnel-IP als bestemming en verlaat dezelfde container met de bestemming van een buurdienst. Tussen die twee momenten heeft DNAT de bestemming herschreven, en het pakket was geen input meer voor de VPN-container. Nu is het doorgestuurd verkeer, beoordeeld door een andere regel. Die verschuiving verklaart waarom een firewallregel die juist lijkt voor het tunneladres geen effect heeft op de vertaalde verbinding.

Volg het pakket na de vertaling

Neem een clientpool van 10.90.0.0/24 en een tunneladres van 10.90.0.1. Twee containers staan op één bridge: 192.0.2.2 draait de VPN en 192.0.2.3 draait de applicatie. Een client verbindt met 10.90.0.1:8080, en de DNAT-regel in de namespace van de VPN-container herschrijft dat naar het echte adres en de poort van de applicatie. Een route stuurt het pakket dan over de bridge. Die adressen zijn illustratief, geen implementatierecept.

De poort waarop de applicatie echt luistert, kan afwijken van elke poort die op de host is gepubliceerd. Lees de listener in de container in plaats van aan te nemen dat beide nummers overeenkomen.

De toestemming hoort op het doorstuurpad

De VPN-container heeft IP-doorsturen nodig en een doorsturingsbeslissing die beperkt is tot de clientpool, het adres van de applicatie en de bedoelde poort. Bestaande antwoorden hebben hun eigen toestemming nodig. Een regel die overeenkomt met het oorspronkelijke tunneladres komt na DNAT niet overeen, omdat de bestemming al is veranderd. Een INPUT-toestemming is de verkeerde haak voor verkeer dat niet meer aan deze host is gericht.

Houd de scope smal: één bronbereik, één bestemming, één dienst. Een ruime doorstuurregele is makkelijker te schrijven en veel moeilijker later te verdedigen.

docker exec vpn-container ip route get 192.0.2.3
docker exec vpn-container iptables -t nat -S
docker exec vpn-container iptables -S FORWARD

Dockers ketens zijn niet de ketens van je container

Regels in de namespace van de container zijn niet de regels van de Docker-host. Wanneer verkeer van de tunnelinterface naar de bridge gaat, kan de bridge-firewall van de host een andere beslissing nemen. Met de iptables-backend van Docker zijn de gedocumenteerde doorstuurketens en de overeenkomsten na DNAT de plek waar die beslissing verschijnt.

De firewallreferentie van Docker beschrijft die ketens en de overeenkomst na DNAT. Repareer een ontbrekende acceptatie niet door Dockers firewallbeheer uit te schakelen of elke keten ruim te maken, want dat verwijdert de grens die je probeert te gebruiken.

Maak de terugweg een bewuste keuze

Als het bronadres behouden blijft, ziet de applicatie 10.90.0.x en moet antwoorden terugrouteren via de VPN-container. Anders stuurt de gewone Docker-gateway ze naar de host, die de tunnel niet bezit. Het alternatief is een smalle bronvertaling op de VPN-container, die het antwoord vereenvoudigt maar de client voor de applicatie verbergt. Kies bewust en schrijf op welke je hebt gekozen.

Test een nieuwe toegestane verbinding vanaf een gewone client en bevestig daarna dat ongerelateerde poorten gesloten blijven. Als een pakket verdwijnt, onderzoek dan de VPN-namespace, de namespace van de applicatie en het eigen log van de applicatie. Een ping naar de bridge-gateway is geen acceptatietest voor de dienst.

Houd de regels in de ondersteunde opstartconfiguratie van de container, want interactieve wijzigingen verdwijnen wanneer hij opnieuw wordt gemaakt. Het publiceren van een hostpoort is een ander blootstellingspad en is niet nodig alleen omdat de dienst via de tunnel bereikbaar is.

Gerelateerde artikelen