传出的 docker 数据包不遵守路由规则

传出的 docker 数据包不遵守路由规则

我有一个私有 Docker 主机 (A),通过 Wireguard 隧道连接到云环境中的公共“路由器”(B)。

线卫:

(Docker Container)
eth0 172.17.0.2
|
docker0 172.17.0.1
(A) eth0 192.168.1.2 --- Internet (can't accept conns)
wg0 10.0.16.6
|
wg0 10.0.16.5
(B) 
eth0 public IP Q
|
USER

这个想法是让流量首先通过其公共 IP 到达 B,然后将请求转发到 B 并将响应转发回来。

我已关注本指南,特别是策略路由部分。

A上的wireguard配置如下:

[Interface]
Address = 10.0.16.6/30
Table = 123

PreUp = ip rule add from 10.0.16.6 table 123 priority 456
PostDown = ip rule del from 10.0.16.6 table 123 priority 456

[Peer]
AllowedIPs = 0.0.0.0/0
Endpoint = Q:51820
PersistentKeepalive = 30

由于以下规则,源为 10.0.16.6 且目标为原始发送者的数据包应通过 wg0 接口路由:

0:  from all lookup local
456:    from 10.0.16.6 lookup 123 ### This one
32766:  from all lookup main
32767:  from all lookup default

因此,在 A 上,来自 B 的数据包从wireguard 接口(目标地址为 10.0.16.6)进入并正确路由到 docker http 服务器。

然后,当响应数据包从 docker 容器返回到 A 时,它具有容器的源地址。这意味着上面的路由规则不会像 http 服务器在主机 A 上运行时那样得到遵守。

数据包最终在路由后进行 NAT,然后在 A eth0 而不是 A wg0 上发送。

我希望数据包在 NAT 阶段之后重新路由。

离开 docker 容器的任何常规流量不应通过 wg0 接口,只有来自 wg0 接口的流量(如参考指南建议的那样)。

如果需要任何进一步的信息,我很乐意提供例如iptables -L

答案1

如果你想要全部来自 Docker 容器的流量传出 Docker 主机的 WireGuard 连接,您可以使用您概述的策略路由技术 - 但使用Docker容器的策略路由规则中的IP地址:

ip rule add from 172.17.0.2 table 123 priority 456

Docker 主机的但是,IP 地址不适用于此规则来路由从容器转发的流量,因为应用了 SNAT主机已经做出了路由决定。

所以如果你需要仅返回流量源自 WireGuard 连接的数据要路由回 WireGuard 连接,您需要在 Docker 主机上使用连接标记。该技术的核心是三个步骤:

  1. 在通过 WireGuard 接口传入的新连接上设置自定义连接标记:

     iptables -t mangle -A PREROUTING -i wg0 -m state --state NEW -j CONNMARK --set-mark 1
    
  2. 在传出连接上,将连接标记复制到数据包标记:

     iptables -t mangle -A PREROUTING ! -i wg0 -m connmark --mark 1 -j MARK --set-mark 1
    
  3. 使用策略路由规则中的数据包标记将数据包路由回 WireGuard 接口:

     ip rule add fwmark 1 table 123 priority 456
    

请参阅您链接的指南的配套文章的“Connmark on the Intermediate Server”部分,了解更多说明和注意事项:WireGuard 端口从 Internet 转发到其他网络

相关内容