Sök…


Introduktion

Det här ämnet handlar om hur du begränsar åtkomst till dina dockarcontainrar från omvärlden med iptables.

För otåliga människor kan du kontrollera exemplen. För de andra, läs kommentaravsnittet för att förstå hur du bygger nya regler.

Syntax

  • iptables -I DOCKER [RULE ...] [ACCEPT | DROP] // För att lägga till en regel a toppen av DOCKER-tabellen
  • iptables -D DOCKER [RULE ...] [ACCEPT | DROP] // Ta bort en regel från DOCKER-tabellen
  • ipset-återställning </etc/ipriends.conf // För att konfigurera om ipset- ipvänner

parametrar

parametrar detaljer
ext_if Ditt externa gränssnitt på Docker-värden.
XXX.XXX.XXX.XXX En särskild IP-adress för vilken Docker behållares åtkomst bör ges.
yyy.yyy.yyy.yyy En annan IP-adress som Docker behållar åtkomst bör ges.
ipfriends Ipset-namnet som definierar IP: erna som får åtkomst till dina Docker-behållare.

Anmärkningar

Problemet

Det är lite svårt att konfigurera iptables-regler för Docker-containrar. Till att börja med skulle du tro att "klassiska" brandväggsregler borde göra tricket.

Låt oss till exempel anta att du har konfigurerat en nginx-proxy-behållare + flera servicebehållare för att exponera via HTTPS vissa personliga webbtjänster. Då bör en regel som denna ge åtkomst till dina webbtjänster endast för IP XXX.XXX.XXX.XXX.

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

Det fungerar inte, dina containrar är fortfarande tillgängliga för alla.

Faktum är att Docker-containrar inte är värdtjänster. De förlitar sig på ett virtuellt nätverk i din värd, och värden fungerar som en gateway för detta nätverk. Och när det gäller gateways, hanteras inte dirigerad trafik av INPUT-tabellen utan av FORWARD-tabellen, vilket gör att regeln publiceras innan den är ineffektiv.

Men det är inte allt. I själva verket skapar Docker-demonen en hel del iptables-regler när den börjar göra sin magi när det gäller containernätverk. I synnerhet skapas en DOCKER-tabell för att hantera regler om containrar genom att vidarebefordra trafik från FORWARD-tabellen till denna nya tabell.

$ 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

Lösningen

Om du kontrollerar den officiella dokumentationen ( https://docs.docker.com/v1.5/articles/networking/) ges en första lösning för att begränsa Docker-behållarens åtkomst till en viss IP.

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

Att lägga till en regel överst på DOCKER-bordet är verkligen en bra idé. Det stör inte reglerna som automatiskt konfigurerats av Docker, och det är enkelt. Men två stora brister:

  • Först, vad händer om du behöver åtkomst från två IP istället för en? Här kan bara en src IP accepteras, andra kommer att släppas utan något sätt att förhindra det.
  • För det andra, vad händer om din dockare behöver tillgång till Internet? Pratiskt kommer ingen begäran att lyckas, eftersom bara servern 8.8.8.8 kan svara på dem.
  • Slutligen, om du vill lägga till andra logiker? Ge till exempel åtkomst till alla användare till din webbserver som serverar med HTTP-protokoll, men begränsa allt annat till särskild IP.

För den första observationen kan vi använda ipset . Istället för att tillåta en IP i regeln ovan tillåter vi alla IP: er från den fördefinierade ipset. Som en bonus kan ipset uppdateras utan nödvändighet att omdefiniera iptable-regeln.

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

För den andra observationen är detta ett kanoniskt problem för brandväggar: om du får kontakta en server via en brandvägg, bör brandväggen auktorisera servern att svara på din begäran. Detta kan göras genom att auktorisera paket som är relaterade till en etablerad anslutning. För dockarlogiken ger den:

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

Den sista observationen fokuserar på en punkt: iptables-regler är viktiga. Faktum är att ytterligare logik för att acceptera vissa anslutningar (inklusive den som gäller ESTABLICERADE anslutningar) måste placeras överst på DOCKER-tabellen, innan DROP-regeln som förnekar alla återstående anslutningar som inte matchar ipset.

Eftersom vi använder -I-alternativet iptable, som infogar regler längst upp i tabellen, måste tidigare iptables-regler införas i omvänd ordning:

// 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

Med allt detta i åtanke kan du nu kontrollera exemplen som illustrerar denna konfiguration.

Begränsa åtkomst på Docker-containrar till en uppsättning IP: er

Installera ipset om det behövs. Se din distribution för att veta hur du gör det. Som exempel är här kommandot för Debian-liknande distributioner.

$ apt-get update
$ apt-get install ipset

Skapa sedan en konfigurationsfil för att definiera en ipset som innehåller IP: erna för vilka du vill öppna åtkomst till dina Docker-behållare.

$ 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

Ladda den här ipset.

$ ipset restore < /etc/ipfriends.conf

Se till att din Docker-demon körs: inget fel bör visas efter att du har angett följande kommando.

$ docker ps

Du är redo att infoga dina iptables-regler. Du måste respektera beställningen.

// 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

Om du vill skapa nya regler måste du ta bort alla anpassade regler som du har lagt till innan du sätter in de nya.

$ 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

Konfigurera begränsningsåtkomst när Docker-demon startar

Pågående arbete

Vissa anpassade iptables-regler

Pågående arbete



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow