Zoeken…


Invoering

Dit onderwerp gaat over het beperken van de toegang tot uw docker-containers van buiten de wereld met behulp van iptables.

Voor ongeduldige mensen kunt u de voorbeelden bekijken. Lees voor de anderen het gedeelte over opmerkingen om te begrijpen hoe u nieuwe regels kunt maken.

Syntaxis

  • iptables -I DOCKER [REGEL ...] [ACCEPT | DROP] // Een regel toevoegen bovenaan de DOCKER-tabel
  • iptables -D DOCKER [REGEL ...] [ACCEPTEREN | DROP] // Een regel verwijderen uit de DOCKER-tabel
  • ipset herstel </etc/ipfriends.conf // Om uw ipset ipfriends opnieuw te configureren

parameters

parameters Details
ext_if Uw externe interface op Docker host.
XXX.XXX.XXX.XXX Een specifiek IP-adres waartoe Docker-containers toegang moeten krijgen.
yyy.yyy.yyy.yyy Een ander IP-adres waartoe Docker-containers toegang moeten krijgen.
ipfriends De ipset-naam die de IP's definieert die toegang hebben tot uw Docker-containers.

Opmerkingen

Het probleem

Het configureren van iptables-regels voor Docker-containers is een beetje lastig. In eerste instantie zou je denken dat "klassieke" firewallregels voldoende zijn.

Laten we bijvoorbeeld aannemen dat u een nginx-proxycontainer + meerdere servicecontainers hebt geconfigureerd om sommige persoonlijke webservices via HTTPS te ontmaskeren. Dan zou een regel als deze alleen toegang moeten geven tot uw webservices voor IP XXX.XXX.XXX.XXX.

$ iptables -A INPUT -i eth0 -p tcp -s XXX.XXX.XXX.XXX -j ACCEPT
$ iptables -P INPUT DROP

Het werkt niet, uw containers zijn nog steeds voor iedereen toegankelijk.

Docker-containers zijn inderdaad geen hostdiensten. Ze vertrouwen op een virtueel netwerk in uw host en de host fungeert als een gateway voor dit netwerk. En met betrekking tot gateways, wordt gerouteerd verkeer niet afgehandeld door de INPUT-tabel, maar door de FORWARD-tabel, waardoor de eerder geposte regel niet effectief is.

Maar het is niet alles. Docker daemon maakt zelfs veel iptables-regels wanneer het zijn magie begint te doen met betrekking tot de netwerkverbinding van containers. In het bijzonder wordt een DOCKER-tabel gemaakt om regels met betrekking tot containers af te handelen door verkeer van de FORWARD-tabel naar deze nieuwe tabel door te sturen.

$ iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-ISOLATION  all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (2 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             172.18.0.4           tcp dpt:https
ACCEPT     tcp  --  anywhere             172.18.0.4           tcp dpt:http

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

De oplossing

Als u de officiële documentatie controleert ( https://docs.docker.com/v1.5/articles/networking/) , wordt een eerste oplossing gegeven om de Docker-containertoegang tot één bepaald IP te beperken.

$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP

Het is inderdaad een goed idee om een regel boven aan de DOCKER-tabel toe te voegen. Het interfereert niet met de regels die automatisch worden geconfigureerd door Docker, en het is eenvoudig. Maar twee grote tekortkomingen:

  • Ten eerste, wat als u toegang moet hebben vanaf twee IP-adressen in plaats van één? Hier kan slechts één src-IP worden geaccepteerd, de andere wordt verwijderd zonder enige manier om dat te voorkomen.
  • Ten tweede, wat als uw docker toegang tot internet nodig heeft? In principe zal geen enkel verzoek slagen, omdat alleen de server 8.8.8.8 hierop zou kunnen reageren.
  • Tot slot, wat als u andere logica wilt toevoegen? Geef bijvoorbeeld elke gebruiker toegang tot uw webserver die werkt met het HTTP-protocol, maar beperk al het andere tot een bepaald IP-adres.

Voor de eerste observatie kunnen we ipset gebruiken . In plaats van één IP toe te staan in de bovenstaande regel, staan we alle IP's van de vooraf gedefinieerde ipset toe. Als bonus kan de ipset worden bijgewerkt zonder dat de iptable-regel opnieuw hoeft te worden gedefinieerd.

$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP

Voor de tweede observatie is dit een canoniek probleem voor firewalls: als u via een firewall contact kunt opnemen met een server, moet de firewall de server machtigen om op uw verzoek te reageren. Dit kan worden gedaan door pakketten te autoriseren die betrekking hebben op een bestaande verbinding. Voor de docker-logica geeft het:

$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT

De laatste observatie richt zich op één punt: iptables-regels zijn essentieel. Inderdaad, aanvullende logica om sommige verbindingen te ACCEPTEREN (inclusief die betreffende GEVESTIGDE verbindingen) moet bovenaan de DOCKER-tabel worden geplaatst, vóór de DROP-regel die alle resterende verbindingen weigert die niet overeenkomen met de ipset.

Omdat we de optie -I van iptable gebruiken, die regels boven aan de tabel invoegt, moeten eerdere iptables-regels in omgekeerde volgorde worden ingevoegd:

// Drop rule for non matching IPs
$ iptables -I DOCKER -i ext_if -m set ! --match-set my-ipset src -j DROP
// Then Accept rules for established connections
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT 
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 3rd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 2nd custom accept rule
$ iptables -I DOCKER -i ext_if ... ACCEPT // Then 1st custom accept rule

Met dit alles in gedachten, kunt u nu de voorbeelden bekijken die deze configuratie illustreren.

Beperk de toegang op Docker-containers tot een reeks IP's

Installeer eerst ipset indien nodig. Raadpleeg uw distributie om te weten hoe u dit moet doen. Als voorbeeld is hier het commando voor Debian-achtige distributies.

$ apt-get update
$ apt-get install ipset

Maak vervolgens een configuratiebestand om een ipset te definiëren met de IP's waarvoor u de toegang tot uw Docker-containers wilt openen.

$ vi /etc/ipfriends.conf
# Recreate the ipset if needed, and flush all entries
create -exist ipfriends hash:ip family inet hashsize 1024 maxelem 65536
flush
# Give access to specific ips
add ipfriends XXX.XXX.XXX.XXX
add ipfriends YYY.YYY.YYY.YYY

Laad deze ipset.

$ ipset restore < /etc/ipfriends.conf

Zorg ervoor dat uw Docker-daemon actief is: er mag geen fout worden weergegeven na het invoeren van de volgende opdracht.

$ docker ps

U bent klaar om uw iptables-regels in te voegen. U moet de bestelling respecteren.

// All requests of src ips not matching the ones from ipset ipfriends will be dropped.
$ iptables -I DOCKER -i ext_if -m set ! --match-set ipfriends src -j DROP
// Except for requests coming from a connection already established.
$ iptables -I DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT

Als u nieuwe regels wilt maken, moet u alle aangepaste regels verwijderen die u hebt toegevoegd voordat u de nieuwe invoegt.

$ iptables -D DOCKER -i ext_if -m set ! --match-set ipfriends src -j DROP
$ iptables -D DOCKER -i ext_if -m state --state ESTABLISHED,RELATED -j ACCEPT

Configureer restrictietoegang wanneer de Docker-daemon start

Lopende werkzaamheden

Enkele aangepaste iptables-regels

Lopende werkzaamheden



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow