我在跑步同一主機上的兩個 Docker 容器生活在 Docker 相同的橋接網路中,並且我設定了 nftables 來或多或少地限制所有流量(規則如下)。
我唯一的問題(據我所知)是從一個容器到另一個容器的流量被阻止,如果容器使用其他容器提供的服務的公共 URL。
例如,服務 A 是具有公共 DNS 條目的 SMTP 伺服器mail.acme.com
,服務 B 是想要將郵件發送到網路伺服器的應用程式使用此網址。 SMTP 伺服器配置為可從外部存取(即像0.0.0.0:25:25
docker compose 中那樣的連接埠轉送)。
在這種特殊情況下,nftables 中的輸入接口不是我的外部接口,而是容器所在的 Docker 網路的接口FORWARD
。INPUT
地方。
我不想設定單獨的規則來允許從 Docker 介面到允許連接埠的流量。
我正在尋找一種解決方案,允許服務使用各自的 URL,並且與 Docker 設定中使用的連接埠和介面無關。單獨使用 nftables 是否有可能實現這一點?
到目前為止,我唯一想到的是如果輸入接口不是外部接口,則從 跳到INPUT
,FORWARD
但感覺我不應該這樣做。
這是我的INPUT
規則:
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
}
這就是當一個容器嘗試到達另一個容器時會發生的情況在同一主機上:(我截斷了一些追蹤輸出,這似乎不太相關)
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
這是外部交通到相同的服務:
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
也在主機上:
iptables-legacy -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT