Introduzione
Nel mondo odierno della containerizzazione, Docker è emerso come una soluzione popolare per la distribuzione e la gestione delle applicazioni. Un caso d'uso comune prevede l'inoltro del traffico di rete da una porta specifica sul computer host a una porta all'interno di un contenitore Docker. Ciò può essere particolarmente utile quando si desidera esporre al mondo esterno un servizio in esecuzione all'interno del contenitore o quando è necessario impostare un proxy inverso per il bilanciamento del carico.
In questo articolo ti guideremo attraverso i passaggi necessari per inoltrare una porta a un contenitore Docker utilizzando iptables, un'utilità firewall potente e flessibile disponibile nella maggior parte delle distribuzioni Linux.
Identificare l'indirizzo IP del contenitore Docker
Esegui il comando seguente per trovare l'indirizzo IP del tuo contenitore Docker:
docker inspect -f '{{ .NetworkSettings.IPAddress }}' <CONTAINER_NAME_OR_ID>
Sostituirecon il nome o l'ID del tuo contenitore. Annotare l'indirizzo IP visualizzato nell'output.
Inoltro delle porte ai contenitori Docker
Utilizzando Iptables
Per inoltrare una porta a un contenitore Docker utilizzando iptables, puoi seguire questi passaggi:
Aggiungi regole iptables per l'inoltro: ora imposta le regole iptables per inoltrare la porta desiderata al tuo contenitore Docker. Sostituisci <HOST_PORT> con il numero di porta sul computer host, <CONTAINER_IP> con l'indirizzo IP del tuo contenitore e <CONTAINER_PORT> con il numero di porta all'interno del contenitore.
sudo iptables -t nat -A PREROUTING -p tcp --dport <HOST_PORT> -j DNAT --to-destination <CONTAINER_IP>:<CONTAINER_PORT>
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
Ad esempio, se desideri reindirizzare la porta 8080 dal computer host alla porta 80 su un contenitore Docker con un IP 172.21.0.7, esegui i comandi indicati:
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.21.0.7:80
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
Salva le regole di iptables: per far sì che le regole di iptables persistano dopo i riavvii, puoi salvarle utilizzando il comando iptables-save:
sudo iptables-save > /etc/iptables/rules.v4
Tieni presente che il percorso del file delle regole può variare a seconda della distribuzione Linux.
Rendi persistente la regola iptables: se stai utilizzando una distribuzione basata su Debian/Ubuntu, puoi installare il pacchetto iptables-persistent per rendere le regole persistenti dopo i riavvii:
sudo apt-get install iptables-persistent
Durante l'installazione, ti verrà chiesto se desideri salvare le regole attuali di iptables. Seleziona "Sì" per salvare le regole.
Per inoltrare una porta a un contenitore Docker utilizzando firewall-cmd, che fa parte dell'utilità firewalld sui sistemi basati su RHEL/CentOS/Fedora, attenersi alla seguente procedura:
Aggiungi le regole firewall-cmd per l'inoltro: ora configura le regole firewall-cmd per inoltrare la porta desiderata al tuo contenitore Docker. Sostituisci <HOST_PORT> con il numero di porta sul computer host, <CONTAINER_IP> con l'indirizzo IP del tuo contenitore e <CONTAINER_PORT> con il numero di porta all'interno del contenitore.
Innanzitutto, abilita il mascheramento sulla zona attiva:
sudo firewall-cmd --zone=public --add-masquerade --permanent
Successivamente, crea la regola di port forwarding:
sudo firewall-cmd --zone=public --add-forward-port=port=<HOST_PORT>:proto=tcp:toaddr=<CONTAINER_IP>:toport=<CONTAINER_PORT> --permanent
Ad esempio, per inoltrare la porta 8080 sul computer host alla porta 80 su un contenitore Docker con un indirizzo IP 172.17.0.7, dovresti utilizzare il seguente comando:
sudo firewall-cmd --zone=public --add-forward-port=port=8080:proto=tcp:toaddr=172.17.0.7:toport=80 --permanent
Ricaricare le regole del firewall: dopo aver aggiunto le regole, è necessario ricaricare la configurazione del firewalld affinché le modifiche abbiano effetto:
sudo firewall-cmd --reload
Ora, il port forwarding dovrebbe funzionare e tutto il traffico in arrivo su <HOST_PORT> sul computer host verrà inoltrato a <CONTAINER_PORT> sul contenitore Docker.
Utilizzando UFW
Per inoltrare una porta a un contenitore Docker utilizzando ufw (Uncomplicated Firewall), che è lo strumento firewall predefinito su Ubuntu e altri sistemi basati su Debian, è necessario seguire questi passaggi:
Abilita l'inoltro UFW: modifica il file di configurazione UFW in /etc/default/ufw:
sudo nano /etc/default/ufw
Trova la riga contenente DEFAULT_FORWARD_POLICY="DROP" e modificala in DEFAULT_FORWARD_POLICY="ACCEPT":
DEFAULT_FORWARD_POLICY="ACCEPT"
Salvare il file ed uscire dall'editor.
Configura l'inoltro IP: modifica il file di configurazione sysctl in /etc/sysctl.conf:
sudo nano /etc/sysctl.conf
Aggiungi o rimuovi il commento dalla seguente riga:
net.ipv4.ip_forward=1
Salvare il file ed uscire dall'editor. Applicare le modifiche eseguendo:
sudo sysctl -p
Aggiorna le regole UFW: innanzitutto crea un nuovo file di regole UFW per il port forwarding. Sostituisci <HOST_PORT> con il numero di porta sul computer host, <CONTAINER_IP> con l'indirizzo IP del tuo contenitore e <CONTAINER_PORT>> con il numero di porta all'interno del contenitore.
sudo nano /etc/ufw/before.rules
Aggiungi le seguenti righe all'inizio del file, dopo i commenti dell'intestazione:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport <HOST_PORT> -j DNAT --to-destination <CONTAINER_IP>:<CONTAINER_PORT>
COMMIT
Ad esempio, per inoltrare la porta 8080 sul computer host alla porta 80 su un contenitore Docker con un indirizzo IP 172.17.0.7 , aggiungeresti:
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.7:80
COMMIT
Salvare il file ed uscire dall'editor.
Ricarica UFW: infine, ricarica la configurazione UFW affinché le modifiche abbiano effetto:
sudo ufw disable
sudo ufw enable
Ora, il port forwarding dovrebbe funzionare e tutto il traffico in arrivo su <HOST_PORT> sul computer host verrà inoltrato a <CONTAINER_PORT> sul contenitore Docker.
Conclusione
In conclusione, inoltrare una porta a un contenitore Docker utilizzando iptables è un processo semplice che implica identificare l'indirizzo IP del contenitore, aggiungere le regole iptables necessarie e assicurarsi che le regole persistano dopo i riavvii. Seguendo i passaggi descritti in questo articolo, puoi assicurarti che il traffico inviato a una porta specifica sul computer host venga reindirizzato senza problemi alla porta corrispondente all'interno del contenitore. Questo approccio ti consente di esporre servizi in esecuzione all'interno di container, impostare proxy inversi o implementare il bilanciamento del carico, tra gli altri casi d'uso, migliorando così la flessibilità e l'efficienza della tua infrastruttura containerizzata.