我的主机上的iptables 443redirect如何干扰来自我的Docker容器的出站HTTPS请求?

我最近诊断了一个涉及Docker和iptables的非常复杂的问题。

我有一个Ubuntu主机与以下的iptables设置:

 $ sudo iptables -L -t nat [...] Chain xyz (1 references) target prot opt source destination REDIRECT tcp -- anywhere anywhere tcp dpt:https /* xyz */ redir ports 8443 

这个规则是为了将所有来自端口443的入站stream量redirect到8443,这意味着将stream量redirect到一个基于Java的应用程序,这个应用程序与我的Docker容器无关,但是运行在同一台机器上,签署SSL证书。

当我使用Docker的默认networking设置在同一台计算机上运行Docker容器时,Docker(或OS)似乎将出站连接redirect到Ubuntu主机上的端口8443,并且在容器中发出wget HTTPS请求,因此,对本地的基于Java的应用程序来说,接受连接(大部分时间)并返回无效的(自签名)证书详细信息。 结果,容器内的应用程序最终与主机上的本地Java应用程序通话,而不是互联网上的真实服务器,他们应该与之通话。

我还证实,直接从Ubuntu主机发出的任何wget HTTPS请求都会触发Internet上的目标服务器。 只有在同一主机上运行的Docker容器启动的请求才会出现问题。

谁能解释为什么会发生这种情况

这个例子不完整。 你没有显示这个链条从哪里链接。 我会尽力回答,但是你可能想把你的IPtables规则减less到一个什么都不能做,只能重现你的问题的规则。

iptables的工作方式是传入的数据包应用了匹配的规则。 任何匹配它的规则,都会应用它的目标。

在你的情况下,可能发生的是你的出站数据包在这个规则上匹配,并且因此也被redirect。

由于REDIRECT目标位于预路由表上,并且不限于传入stream量,因此您需要以某种方式限制匹配。 最简单的,可能是添加! -i lo ! -i lo遵守规则。 这应该防止通过回送接口到达的数据包的匹配。