这是我第一次在这里发帖,所以我会尽力解释。
我使用 strongswan(bypass-lan 插件)在我的主机(Ubuntu 22.04)上安装了 IPSec 隧道。通过 ipsec statusall 确认,连接已建立且稳定。
我在 Docker 中声明了一个桥接网络 (app),其子网与 strongswan leftsubnet (10.22.10.0/24) 完全相同。
我无法访问右侧设置。
我使用 app 网络获得了一个带有容器的 docker-compose 堆栈。
我向我的一个容器添加了一些设置和一个固定 IP 以进行测试:
撰写信息
问题:
我完全无法访问容器内的隧道...但我可以 ping 或访问容器内的互联网。
我尝试添加在其他技术博客上找到的 iptables 规则:
iptables -j SNAT -t nat -I POSTROUTING 1 -o ${OUT_INTERFACE} -d ${VPN_NETWORK} -s ${DOCKER_NETWORK} --to-source ${VPN_HOST_IP}
没有任何成功,但我不太清楚 iptables 是如何工作的,下面是我所做的:
${OUT_INTERFACE} = app-network-name (br-hash)
${VPN_NETWORK} = rightsubnet
${DOCKER_NETWORK} = leftsubnet
${VPN_HOST_IP} = left host public IP
我发现那些有同样问题但没有反应或不起作用的人:
这里和这里
我知道docker在隔离阶段(1和2)有一些规则。
已经过去了将近一周的测试失败,希望有人能成为我的救星
谢谢
编辑
我在另一台具有相同设置的服务器上尝试了此操作,但没有成功。为了添加更多详细信息,以下是 iptables 中的现有规则:网络接口为 br-7b5f3aa28bb9,子网为 10.22.10.0/24
iptables -S
-A FORWARD -o br-7b5f3aa28bb9 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-7b5f3aa28bb9 -j DOCKER
-A FORWARD -i br-7b5f3aa28bb9 ! -o br-7b5f3aa28bb9 -j ACCEPT
-A FORWARD -i br-7b5f3aa28bb9 -o br-7b5f3aa28bb9 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i br-7b5f3aa28bb9 ! -o br-7b5f3aa28bb9 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-2 -o br-7b5f3aa28bb9 -j DROP
iptables -S -t nat
-A POSTROUTING -i br-7b5f3aa28bb9 -m policy --dir in --pol ipsec -j ACCEPT
-A POSTROUTING -s 10.22.10.0/24 ! -o br-7b5f3aa28bb9 -j MASQUERADE
-A DOCKER -i br-7b5f3aa28bb9 -j RETURN
mangle 表中没有任何内容。
如果有人能看出这里出了什么问题,因为我的 POC 服务器现在已经关闭了 :/
谢谢
编辑2
我设法让它工作,问题是:我为容器使用了多个网络接口,并且目的地没有通过好的接口定向,我添加了这个:
iptables -t nat -I POSTROUTING -d 10.5.18.38 ! -s 10.22.10.0/24 -j SNAT --to-source 10.22.10.1
这样,一旦我们请求通过 ipsec 隧道传输的 IP,流量就会被 nat 到良好的源,所以我们需要添加这 2 条规则以使一切正常工作:
iptables -t nat -I POSTROUTING -s $DOCKER_NETWORK -d $REMOTE_NETWORK -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -I POSTROUTING -d $REMOTE_NETWORK ! -s $DOCKER_NETWORK -j SNAT --to-source $DOCKER_NETWORK_GATEWAY
非常感谢@ecdsa 对 iptables 的解释
答案1
该 NAT 规则不正确,因为这基本上是 Docker 已经在做的事情(将私有 Docker 网络通过 NAT 转换为主机的 IP)。
由于 VPN 的本地流量选择器(leftsubnet
)是 Docker 网络而不是该 IP,因此流量不会通过隧道传输。
您希望避免对符合 IPsec 策略的流量发生任何 NAT(包括 Docker 配置的 NAT)。这可以通过如下防火墙规则来实现:
iptables -t nat -I POSTROUTING -s ${DOCKER_NETWORK} -m policy --dir out --pol ipsec -j ACCEPT
这必须是中的第一个规则POSTROUTING
(因此是-I
)。可选择添加-d ${VPN_NETWORK}
到远程网络上的过滤器,这可以避免对 Docker 网络中的不相关流量进行 IPsec 策略查找。