Ich habe gerade Docker ausprobiert. Es ist großartig, scheint aber mit ufw nicht gut zu funktionieren. Standardmäßig manipuliert Docker die iptables ein wenig. Das Ergebnis ist kein Fehler, aber nicht das, was ich erwartet hatte. Weitere Informationen finden Sie unter Die Gefahren von UFW + Docker
Mein Ziel ist es, ein System wie dieses einzurichten
Host (running ufw) -> docker container 1 - nginx (as a reverse proxy)
-> docker container 2 - node web 1
-> docker container 3 - node web 2
-> .......
Ich möchte den eingehenden Datenverkehr (z. B. den Zugriff einschränken) über ufw verwalten, daher möchte ich nicht, dass Docker meine iptables berührt. Hier ist mein Test
Umgebung:
- ein neu installiertes Ubuntu 14.04 (Kernel: 3.13.0-53)
- Docker 1.6.2
- Die UWW-Weiterleitung ist aktiviert. ( UFW-Weiterleitung aktivieren )
--iptables=false
wurde dem Docker-Daemon hinzugefügt.
Erster Versuch
docker run --name ghost -v /home/xxxx/ghost_content:/var/lib/ghost -d ghost
docker run --name nginx -p 80:80 -v /home/xxxx/nginx_site_enable:/etc/nginx/conf.d:ro --link ghost:ghost -d nginx
Kein Glück. Der erste Befehl ist in Ordnung, aber der zweite Befehl gibt einen Fehler aus
Error response from daemon: Cannot start container
Zweiter Versuch
Dann fand ich Folgendes : Container können nicht mit --iptables = false # 12701 verknüpft werden
Nach dem Ausführen des folgenden Befehls sieht alles in Ordnung aus.
sudo iptables -N DOCKER
Ich habe jedoch festgestellt, dass ich keine ausgehenden Verbindungen innerhalb von Containern herstellen kann. Zum Beispiel:
xxxxg@ubuntu:~$ sudo docker exec -t -i nginx /bin/bash
root@b0d33f22d3f4:/# ping 74.125.21.147
PING 74.125.21.147 (74.125.21.147): 56 data bytes
^C--- 74.125.21.147 ping statistics ---
35 packets transmitted, 0 packets received, 100% packet loss
root@b0d33f22d3f4:/#
Wenn ich --iptables=false
vom Docker-Daemon entferne , ist die Internetverbindung von Containern wieder normal, aber das UFW funktioniert nicht "richtig" (naja ... meiner Definition nach).
Was ist die beste Vorgehensweise für Docker + UFW? Kann mir jemand helfen?
Vielen Dank.
Bart.
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_OAntworten:
Ich hatte ein solches Problem wie vor Monaten und habe mich kürzlich entschlossen, das Problem zusammen mit der Lösung in meinem Blog zu beschreiben. Hier ist die Verknüpfung.
Die Verwendung
--iptables=false
hilft Ihnen bei dem von Ihnen beschriebenen Fall nicht viel. Hier reicht es einfach nicht. Standardmäßig kann keiner Ihrer Container eine ausgehende Verbindung herstellen.Es gibt einen kleinen Schritt, den Sie auf Ihrem Weg zu Containern hinter UFW hier weglassen. Sie können Dateien mit Inhalten wie folgt verwenden
--iptables=false
oder erstellen/etc/docker/daemon.json
Das Ergebnis ist das gleiche, aber für die letztere Option müssen Sie den gesamten Docker-Dienst neu starten
service docker restart
oder sogar einen Neustart durchführen, wenn Docker die Möglichkeit hatte, iptables-Regeln hinzuzufügen, bevor Sie diese Funktion deaktiviert haben.Wenn es fertig ist, machen Sie einfach zwei weitere Dinge:
Daher richten Sie in UFW die Standardweiterleitungsrichtlinie für die Annahme und Verwendung ein:
Auf diese Weise erreichen Sie das unübersichtliche Verhalten von Docker in Ihren iptables-Regeln und gleichzeitig wird Docker mit dem erforderlichen Routing ausgestattet, damit Container ausgehende Verbindungen problemlos ausführen können. Die UFW-Regeln werden jedoch ab diesem Zeitpunkt weiterhin eingeschränkt.
Ich hoffe, dies löst das Problem für Sie und alle, die hier auf der Suche nach einer Antwort sind.
Ich habe das Problem und die Lösung unter https://www.mkubaczyk.com/2017/09/05/force-docker-not-bypass-ufw-rules-ubuntu-16-04/ ausführlicher beschrieben.
quelle
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:
--iptables=false
, einschließlich der Konfigurationsdatei/etc/docker/daemon.json
.DROP
anstelle von auf die Standardregel zurückgesetztACCEPT
./etc/ufw/after.rules
.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: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: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-Port80
und nicht den Host-Port verwenden8080
.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:
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:
Wenn auch nur für einen bestimmten Container, z. B. die IP-Adresse 172.17.0.2:
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.
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.
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.Mehr
https://github.com/chaifeng/ufw-docker
Verwendung
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 :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 Befehlufw allow 8080
kann das öffentliche Netzwerk den Dienst und alle veröffentlichten Ports besuchen, deren Container-Port ist8080
. 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:
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: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: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 dieufw-user-forward
Kette und denufw 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 installierenWir können dieses Skript nur auf Manager-Knoten verwenden, um Firewall-Regeln im Swarm-Modus zu verwalten.
after.rules
Dateien auf allen Knoten, einschließlich Managern und MitarbeiternDieses 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 .quelle
172.16.0.0
mit172.17.0.0
Ich habe zwei Stunden damit verbracht, die obigen Vorschläge und andere Beiträge auszuprobieren. Die einzige Lösung, die funktionierte, war von Tsunas Post in diesem Github-Thread :
quelle
Hier nicht zu sagen, dass Lösungen falsch sind, aber sie sehen ein bisschen "furchterregend" und fehleranfällig für jemanden aus, der nach einer schnellen Ein-Schritt-Anleitung sucht . Ich bin auch kürzlich mit diesem Problem gekommen, habe alle ähnlichen Antworten online gelesen und zum Zeitpunkt des Schreibens nichts schnelles und klares gefunden. Überraschenderweise ist meine alternative Lösung leicht zu verstehen und zu verwalten und funktioniert: Implementieren Sie einfach Ihre Firewall außerhalb Ihres Host-Computers .
Die Behandlung der Firewall als erstklassiger Bürger scheint viele Vorteile zu haben.
quelle
Ich mag den für die iptables erforderlichen Betriebsaufwand nicht: false flag im Docker-Daemon. Nach allem, was ich sehe, und bitte korrigieren Sie mich, wenn ich falsch liege, sind alle Lösungen viel zu komplizierte Hacks.
Fügen Sie dies einfach in /etc/ufw/after.rules vor dem * Filterabschnitt ein:
Es besteht keine Notwendigkeit, sich mit Docker-Netzwerken oder unnötigen Hacks herumzuschlagen.
quelle
Sie sind sich nicht ganz sicher, was Sie fragen, aber nach allem, was ich sammeln kann, möchten Sie besser kontrollieren, wer auf Ihre Apps zugreifen kann, die in Docker ausgeführt werden? Ich habe hier eine ähnliche Frage beantwortet, um den Datenverkehr über einen Front-End-Proxy anstatt mit IP-Tabellen zu steuern. Blockieren Sie den externen Zugriff auf Docker-Container
Hoffe das hilft
Dylan
Bearbeiten
Mit dem obigen Ansatz können Sie dann UFW verwenden, um nur eingehende Verbindungen zu Port 80 (dh dem Proxy) zuzulassen. Dies reduziert die Port-Exposition auf ein Minimum und bietet den zusätzlichen Bonus, dass Sie den Datenverkehr über eine Proxy-Konfiguration und DNS steuern können
quelle
Für das, was es wert ist, hier ein Nachtrag zu @ mkubaczyks Antwort für den Fall, dass mehr Brückennetzwerke am gesamten Setup beteiligt sind. Diese können von Docker-Compose-Projekten bereitgestellt werden. So können die richtigen Regeln generiert werden, sofern diese Projekte von gesteuert werden
systemd
./etc/systemd/system/[email protected]
/usr/local/bin/update-iptables-for-docker-bridges
Offensichtlich wird dies nicht so gut skaliert.
Es ist auch bemerkenswert, dass das gesamte Grundkonzept die Quelle jeder Verbindung für die in einem Container ausgeführten Anwendungen verschleiert.
quelle
Ich habe gerade ein kleines Skript erstellt, das das Problem mit der ufw-Firewall und den Docker-Iptables löst. Sie können einen Blick auf Repo nehmen hier . Es basiert stark auf den UFW- Regeln von Chaifeng / Ufw-Docker , automatisiert jedoch den manuellen Prozess. Sie müssen lediglich den Container mit einem speziellen Etikett ausführen
UFW_MANAGED=TRUE
. Bitte teilen Sie mir Ihre Rückmeldungen mit. Natürlich ist Code Mist, aber hoffentlich funktioniert es.quelle