Problem
Dieses Problem gibt es schon lange.
Das Deaktivieren von iptables in Docker führt zu anderen Problemen.
Rollback ändert sich zuerst
Wenn Sie Ihren Server gemäß der aktuellen Lösung im Internet geändert haben, setzen Sie diese Änderungen zuerst zurück, einschließlich:
- Aktivieren Sie die iptables-Funktion von Docker. Entfernen Sie alle Änderungen wie
--iptables=false
, einschließlich der Konfigurationsdatei /etc/docker/daemon.json
.
- Die Standard-FORWARD-Regel von UFW wird
DROP
anstelle von auf die Standardregel zurückgesetzt ACCEPT
.
- Entfernen Sie die Regeln für das Docker-Netzwerk in der UFW-Konfigurationsdatei
/etc/ufw/after.rules
.
- Wenn Sie Docker-Konfigurationsdateien geändert haben, starten Sie Docker zuerst neu. Wir werden die UFW-Konfiguration später ändern und können sie dann neu starten.
Lösen von UFW- und Docker-Problemen
Diese Lösung muss nur eine UFW-Konfigurationsdatei ändern. Alle Docker-Konfigurationen und -Optionen bleiben die Standardeinstellungen. Muss die Docker-Iptables-Funktion nicht deaktivieren.
Ändern Sie die UFW-Konfigurationsdatei /etc/ufw/after.rules
und fügen Sie am Ende der Datei die folgenden Regeln hinzu:
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
-A DOCKER-USER -j ufw-user-forward
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j RETURN
COMMIT
# END UFW AND DOCKER
Verwenden Sie den Befehl sudo systemctl restart ufw
, um UFW nach dem Ändern der Datei neu zu starten. Jetzt kann das öffentliche Netzwerk nicht auf veröffentlichte Docker-Ports zugreifen, der Container und das private Netzwerk können sich regelmäßig besuchen, und die Container können auch von innen auf das externe Netzwerk zugreifen.
Wenn Sie öffentlichen Netzwerken beispielsweise den Zugriff auf die vom Docker-Container bereitgestellten Dienste ermöglichen möchten, lautet der Service-Port eines Containers 80
. Führen Sie den folgenden Befehl aus, damit die öffentlichen Netzwerke auf diesen Dienst zugreifen können:
ufw route allow proto tcp from any to any port 80
Mit diesem Befehl kann das öffentliche Netzwerk auf alle veröffentlichten Ports zugreifen, deren Container-Port 80 ist.
Hinweis: Wenn wir einen Port mithilfe der Option veröffentlichen -p 8080:80
, sollten wir den Container-Port 80
und nicht den Host-Port verwenden 8080
.
Wenn es mehrere Container mit einem Service-Port von 80 gibt, wir jedoch nur möchten, dass das externe Netzwerk auf einen bestimmten Container zugreift. Wenn die private Adresse des Containers beispielsweise 172.17.0.2 lautet, verwenden Sie den folgenden Befehl:
ufw route allow proto tcp from any to 172.17.0.2 port 80
Wenn das Netzwerkprotokoll UDP ist, z. B. ein DNS-Dienst, können Sie den folgenden Befehl verwenden, um dem externen Netzwerk den Zugriff auf alle veröffentlichten DNS-Dienste zu ermöglichen:
ufw route allow proto udp from any to any port 53
Wenn auch nur für einen bestimmten Container, z. B. die IP-Adresse 172.17.0.2:
ufw route allow proto udp from any to 172.17.0.2 port 53
Wie es funktioniert?
Die folgenden Regeln ermöglichen es den privaten Netzwerken, sich gegenseitig zu besuchen. In der Regel sind private Netzwerke vertrauenswürdiger als öffentliche Netzwerke.
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
Mit den folgenden Regeln kann UFW verwalten, ob die öffentlichen Netzwerke die vom Docker-Container bereitgestellten Dienste besuchen dürfen. Damit können wir alle Firewall-Regeln an einem Ort verwalten.
-A DOCKER-USER -j ufw-user-forward
Die folgenden Regeln blockieren Verbindungsanforderungen, die von allen öffentlichen Netzwerken initiiert wurden, ermöglichen jedoch internen Netzwerken den Zugriff auf externe Netzwerke. Beim TCP-Protokoll wird verhindert, dass aktiv eine TCP-Verbindung aus öffentlichen Netzwerken hergestellt wird. Beim UDP-Protokoll werden alle Zugriffe auf Ports, die kleiner als 32767 sind, blockiert. Warum ist dieser Hafen? Da das UDP-Protokoll zustandslos ist, ist es nicht möglich, das Handshake-Signal, das die Verbindungsanforderung initiiert, wie TCP zu blockieren. Für GNU / Linux finden wir den lokalen Portbereich in der Datei/proc/sys/net/ipv4/ip_local_port_range
. Der Standardbereich ist32768 60999
. Wenn Sie von einem laufenden Container aus auf einen UDP-Protokolldienst zugreifen, wird der lokale Port zufällig aus dem Portbereich ausgewählt, und der Server gibt die Daten an diesen zufälligen Port zurück. Daher können wir davon ausgehen, dass der Überwachungsport des UDP-Protokolls in allen Containern kleiner als 32768 ist. Aus diesem Grund möchten wir nicht, dass öffentliche Netzwerke auf die UDP-Ports zugreifen, die kleiner als 32768 sind.
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j RETURN
Mehr
https://github.com/chaifeng/ufw-docker
sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
chmod +x /usr/local/bin/ufw-docker
Verwendung
ufw-docker help
ufw-docker install
ufw-docker status
ufw-docker allow webapp
ufw-docker allow webapp 80
ufw-docker allow webapp 53/udp
ufw-docker list webapp
ufw-docker delete allow webapp 80/tcp
ufw-docker delete allow webapp
Update: 2018-09-10
Der Grund für die Wahl ufw-user-forward
, nichtufw-user-input
mit ufw-user-input
Profi:
Einfach zu bedienen und zu verstehen, unterstützt ältere Versionen von Ubuntu.
8080
Verwenden Sie beispielsweise den folgenden Befehl , damit die Öffentlichkeit einen veröffentlichten Port besuchen kann, dessen Container-Port ist :
ufw allow 8080
Con:
Es werden nicht nur Ports von Containern verfügbar gemacht, sondern auch Ports des Hosts.
Zum Beispiel, wenn ein Dienst auf dem Host ausgeführt wird und der Port ist 8080
. Mit dem Befehl ufw allow 8080
kann das öffentliche Netzwerk den Dienst und alle veröffentlichten Ports besuchen, deren Container-Port ist 8080
. Wir möchten jedoch nur den auf dem Host ausgeführten Dienst oder nur den in Containern ausgeführten Dienst verfügbar machen, nicht die beiden.
Um dieses Problem zu vermeiden, müssen wir möglicherweise für alle Container einen Befehl ähnlich dem folgenden verwenden:
ufw allow proto tcp from any to 172.16.0.3 port 8080
mit ufw-user-forward
Profi:
Es können keine Dienste verfügbar gemacht werden, die gleichzeitig mit demselben Befehl auf Hosts und Containern ausgeführt werden.
Wenn Sie beispielsweise den Port 8080
von Containern veröffentlichen möchten , verwenden Sie den folgenden Befehl:
ufw route allow 8080
Das öffentliche Netzwerk kann auf alle veröffentlichten Ports zugreifen, deren Container-Ports sind 8080
.
Auf den Port 8080
des Hosts kann das öffentliche Netzwerk jedoch immer noch nicht zugreifen. Wenn Sie dies möchten, führen Sie den folgenden Befehl aus, damit die Öffentlichkeit separat auf den Port auf dem Host zugreifen kann:
ufw allow 8080
Con:
Unterstützt ältere Versionen von Ubuntu nicht und der Befehl ist etwas komplizierter. Sie können jedoch mein Skript https://github.com/chaifeng/ufw-docker verwenden .
Fazit
Wenn wir eine ältere Version von Ubuntu verwenden, können wir ufw-user-input
chain verwenden. Vermeiden Sie jedoch die Offenlegung von Diensten, die nicht verfügbar gemacht werden sollten.
Wenn wir eine neuere Version von Ubuntu verwenden, bei der es sich um einen ufw route
Unterbefehl handelt, verwenden wir besser die ufw-user-forward
Kette und den ufw route
Befehl, um die Firewallregeln für Container zu verwalten.
Update: 6. Oktober 2018
Das Skript ufw-docker unterstützt jetzt Docker Swarm. Weitere Informationen finden Sie im neuesten Code unter https://github.com/chaifeng/ufw-docker
Für den Docker Swarm-Modus installieren
Wir können dieses Skript nur auf Manager-Knoten verwenden, um Firewall-Regeln im Swarm-Modus zu verwalten.
- Ändern aller
after.rules
Dateien auf allen Knoten, einschließlich Managern und Mitarbeitern
- Bereitstellen dieses Skripts auf Manager-Knoten
Dieses Skript wird im Docker Swarm-Modus ausgeführt und fügt einen globalen Dienst hinzu ufw-docker-agent
. Aus diesem Projekt wird auch automatisch das Bild chaifeng / ufw-docker-agent erstellt .
iptables -N DOCKER
Startet eine neue Kette mit diesem Namen ... Vielleicht können Sie die iptables aktiviert lassen (ich meine, ohne sie zu entfernen,--iptables=false
und dann können Sie einen "Post-Befehl" für den Kettenstart ausführen. Ich habe keine Antwort darauf, was die beste Vorgehensweise ist o_O