ich rennezwei Docker-Container auf demselben HostIch lebe im selben Bridge-Netzwerk wie Docker und habe Nftables so eingerichtet, dass mehr oder weniger der gesamte Datenverkehr eingeschränkt wird (Regeln siehe unten).
Mein einziges Problem (das ich kenne) ist, dassDer Verkehr von einem Container zum anderen wird blockiert, wenn ein Container verwendetdie öffentliche URL des vom anderen Container bereitgestellten Dienstes.
Beispielsweise ist Dienst A ein SMTP-Server mit einem öffentlichen DNS-Eintrag mail.acme.com
und Dienst B eine App, die E-Mails an den Webserver senden möchte.mit dieser URL. Der SMTP-Server ist so konfiguriert, dass er von außen zugänglich ist (d. h. Portweiterleitung wie 0.0.0.0:25:25
in Docker Compose).
In diesem speziellen Fall ist die Eingabeschnittstelle in nftables nicht meine externe Schnittstelle, sondern die Schnittstelle des Docker-Netzwerks, in dem sich der Container befindet. Der Datenverkehr wird nicht weitergeleitet FORWARD
, die von Docker hinzugefügten Regeln gelten nicht und der Datenverkehr landet dort, INPUT
wo er gelöscht wird.
Ich möchte keine individuellen Regeln einrichten, um Datenverkehr von den Docker-Schnittstellen zu den zulässigen Ports zuzulassen.
Ich suche nach einer Lösung, die es den Diensten ermöglicht, ihre jeweiligen URLs zu verwenden und die unabhängig von den im Docker-Setup verwendeten Ports und Schnittstellen ist. Ist dies überhaupt nur mit nftables möglich?
Das Einzige, was mir bisher eingefallen ist, ist, von zu zu springen, INPUT
wenn FORWARD
die Eingabeschnittstelle keine externe Schnittstelle ist, aber das fühlt sich so an, als sollte ich das nicht tun.
Hier sind meine INPUT
Regeln:
chain INPUT {
type filter hook input priority filter; policy drop;
ct state vmap { invalid : drop, established : accept, related : accept }
iifname "lo" accept
iifname "externalif0" icmp type echo-request accept
iifname "externalif0" icmpv6 type echo-request accept
}
Das passiert, wenn ein Container versucht, einen anderen Container zu erreichenauf demselben Host: (Ich habe einen Teil der Ablaufverfolgungsausgabe abgeschnitten, der nicht so relevant erschien)
trace id 196c1ae6 ip filter trace_chain packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
trace id 196c1ae6 ip nat PREROUTING packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
trace id e7c2ca4b ip filter INPUT packet: iif "dockerbr0" ip saddr <containerip> ip daddr <public host ip> tcp sport 33546 tcp dport 443
Und hier istAußenverkehrzum gleichen Dienst:
trace id 29f9da6c ip filter trace_chain packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443
trace id 29f9da6c ip nat PREROUTING packet: iif "externalif0" ip saddr <someip> ip daddr <public host ip> sport 36382 tcp dport 443
trace id 29f9da6c ip nat DOCKER rule iifname != "dockerbr0" dport 443 dnat to <dockerip>:443 (verdict accept)
trace id 29f9da6c ip filter FORWARD packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> daddr <containerip> sport 36382 tcp dport 443
trace id 29f9da6c ip filter DOCKER rule iifname != "dockerbr0" oifname "dockerbr0" daddr <containerip> tcp dport 443 accept (verdict accept)
trace id 29f9da6c ip nat POSTROUTING packet: iif "externalif0" oif "dockerbr0" ip saddr <someip> ip daddr <containerip> sport 36382 tcp dport 443
Auch auf dem Host:
iptables-legacy -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT