Ricerca…


introduzione

Questo argomento riguarda come limitare l'accesso ai contenitori docker dal mondo esterno usando iptables.

Per le persone impazienti, puoi controllare gli esempi. Per gli altri, leggi la sezione delle note per capire come creare nuove regole.

Sintassi

  • iptables -I DOCKER [RULE ...] [ACCEPT | DROP] // Per aggiungere una regola alla parte superiore della tabella DOCKER
  • iptables -D DOCKER [RULE ...] [ACCEPT | DROP] // Per rimuovere una regola dalla tabella DOCKER
  • ripristino ipset </etc/ipfriends.conf // Per riconfigurare i propri IPs ipset

Parametri

parametri Dettagli
ext_if La tua interfaccia esterna sull'host Docker.
XXX.XXX.XXX.XXX Un particolare IP su cui deve essere fornito l'accesso ai contenitori Docker.
yyy.yyy.yyy.yyy Un altro IP su cui devono essere forniti i contenitori Docker.
ipfriends Il nome ipset che definisce gli IP autorizzati ad accedere ai contenitori Docker.

Osservazioni

Il problema

La configurazione delle regole di iptables per i contenitori Docker è un po 'complicata. All'inizio, penseresti che le regole del firewall "classiche" dovrebbero fare il trucco.

Ad esempio, supponiamo di aver configurato un contenitore proxy nginx + diversi contenitori di servizi per esporre via HTTPS alcuni servizi web personali. Quindi una regola come questa dovrebbe consentire l'accesso ai tuoi servizi Web solo per IP XXX.XXX.XXX.XXX.

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

Non funzionerà, i tuoi contenitori sono ancora accessibili a tutti.

Infatti, i container Docker non sono servizi host. Si basano su una rete virtuale nel tuo host e l'host funge da gateway per questa rete. E per quanto riguarda i gateway, il traffico indirizzato non viene gestito dalla tabella INPUT, ma dalla tabella FORWARD, che rende la regola postata prima inefficace.

Ma non è tutto. Infatti, il demone Docker crea molte regole di iptables quando inizia a fare la sua magia riguardo alla connettività di rete dei container. In particolare, viene creata una tabella DOCKER per gestire le regole relative ai contenitori inoltrando il traffico dalla tabella FORWARD a questa nuova tabella.

$ 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

La soluzione

Se si controlla la documentazione ufficiale ( https://docs.docker.com/v1.5/articles/networking/) , viene fornita una prima soluzione per limitare l'accesso al contenitore Docker a un particolare IP.

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

In effetti, aggiungere una regola nella parte superiore della tabella DOCKER è una buona idea. Non interferisce con le regole configurate automaticamente da Docker ed è semplice. Ma due grandi mancanze:

  • Innanzitutto, cosa succede se è necessario accedere da due IP anziché uno? Qui può essere accettato solo un IP src, altri verranno eliminati senza alcun modo per impedirlo.
  • In secondo luogo, cosa succede se la finestra mobile ha bisogno di accedere a Internet? Praticamente nessuna richiesta avrà successo, in quanto solo il server 8.8.8.8 potrebbe rispondere ad essi.
  • Infine, cosa succede se si desidera aggiungere altre logiche? Ad esempio, concedere l'accesso a qualsiasi utente al server web che serve sul protocollo HTTP, ma limitare tutto il resto a particolari IP.

Per la prima osservazione, possiamo usare ipset . Invece di consentire un IP nella regola sopra, consentiamo tutti gli IP dall'ipset predefinito. Come bonus, l'ipset può essere aggiornato senza la necessità di ridefinire la regola iptable.

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

Per la seconda osservazione, si tratta di un problema canonico per i firewall: se si è autorizzati a contattare un server attraverso un firewall, il firewall dovrebbe autorizzare il server a rispondere alla richiesta. Questo può essere fatto autorizzando pacchetti che sono collegati ad una connessione stabilita. Per la logica docker, fornisce:

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

L'ultima osservazione si concentra su un punto: le regole di iptables sono essenziali. Infatti, la logica aggiuntiva per ACCETTARE alcune connessioni (inclusa quella relativa alle connessioni ESTABLISHED) deve essere posta nella parte superiore della tabella DOCKER, prima della regola DROP che nega tutte le connessioni rimanenti che non corrispondono all'ipset.

Poiché utilizziamo l'opzione -I di iptable, che inserisce le regole nella parte superiore della tabella, le precedenti regole di iptables devono essere inserite in ordine inverso:

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

Tenendo tutto questo a mente, ora puoi controllare gli esempi che illustrano questa configurazione.

Limita l'accesso ai contenitori Docker a un set di IP

Innanzitutto, installa IPSET se necessario. Si prega di fare riferimento alla vostra distribuzione per sapere come farlo. Ad esempio, ecco il comando per le distribuzioni di tipo Debian.

$ apt-get update
$ apt-get install ipset

Quindi creare un file di configurazione per definire un IPS contenente gli IP per i quali si desidera aprire l'accesso ai contenitori Docker.

$ 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

Carica questo ipset.

$ ipset restore < /etc/ipfriends.conf

Assicurati che il tuo demone Docker sia in esecuzione: non dovrebbe essere mostrato alcun errore dopo aver inserito il seguente comando.

$ docker ps

Sei pronto per inserire le tue regole di iptables. È necessario rispettare l'ordine.

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

Se vuoi creare nuove regole, dovrai rimuovere tutte le regole personalizzate che hai aggiunto prima di inserirne di nuove.

$ 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

Configurare l'accesso alla restrizione all'avvio del daemon Docker

Lavori in corso

Alcune regole personalizzate di iptables

Lavori in corso



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow