nftables 规则允许同一主机上的联网 Docker 容器使用其公共 URL

nftables 规则允许同一主机上的联网 Docker 容器使用其公共 URL

我在跑步同一主机上有两个 Docker 容器生活在 Docker 同一个桥接网络中,并且我已经设置了 nftables 来或多或少地限制所有流量(下面的规则)。

我唯一的问题(我知道的)是从一个容器到另一个容器的流量被阻止,如果容器使用另一个容器提供的服务的公共 URL

例如,服务 A 是一个具有公共 DNS 条目的 SMTP 服务器mail.acme.com,服务 B 是一个想要向 Web 服务器发送邮件的应用程序使用此 URL。SMTP 服务器已配置为可从外部访问(即像0.0.0.0:25:25在 docker compose 中一样进行端口转发)。

在这种特殊情况下,nftables 中的输入接口不是我的外部接口,而是容器所在的 Docker 网络的接口。流量不会通过路由FORWARD,Docker 添加的规则不适用,并且流量最终会到达被INPUT丢弃的地方。

我不想设置单独的规则来允许从 Docker 接口到允许端口的流量。

我正在寻找一种解决方案,允许服务使用各自的 URL,并且与 Docker 设置中使用的端口和接口无关。仅使用 nftables 是否可行?

到目前为止我想到的唯一办法就是,如果输入接口不是外部接口,则从跳转到INPUTFORWARD但感觉我不应该这样做。


以下是我的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

相关内容