在 Azure K8S 中运行的容器上的 iptables 中使用 fwmark

在 Azure K8S 中运行的容器上的 iptables 中使用 fwmark

我有一个奇怪的用例,在 Azure Kubernetes 中运行的 pod 需要通过专用 VPN 隧道将流量从特定端口路由到特定目标。但这些目标是私有 IP,因此不同目标可以具有相同的 IP。除了路由之外,pod 还是目标连接到的 OpenVPN 服务器。示例:

到达端口 10 的通信通过 VPN IP 10.118.0.2 路由到 IP 10.0.0.4:80

同时我们还可以得到:

到达端口 20 的通信通过 VPN IP 10.118.0.3 路由到 IP 10.0.0.4:80

尽管目标 IP 相同,但它们是不同的机器。因此,为了实现这一点,我想出了这个可能的解决方案:

/sbin/iptables --table mangle --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump MARK --set-mark "10"
/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip rule add prio "10" from all fwmark "10" lookup "10"
/sbin/ip route add "10.0.0.4" via "10.118.0.2" table 10

这将允许两种通信同时工作,并将流量路由到正确的机器。但我看到的是数据包在 mangle 表中被标记。但之后永远不会到达 NAT 表。我发现它与 rt_filter 有关。下面有更多相关信息。目前它正在工作,如下所示:

/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip route add "10.0.0.4" via "10.118.0.2"

但是,如果建立了第二条路线,如第一个示例所示,命令将如下所示:

/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "20" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip route add "10.0.0.4" via "10.118.0.3"

这会在主路由表中为同一目标创建另一条路由。但这样一来,用户在访问 192.168.0.100 时可能会被路由到与 10.118.0.3 或 10.118.0.2 连接的机器。

除了这个规则之外,对于所有规则,这一条始终处于启用状态,以允许流量返回到 tap0 接口,然后通过该接口与 10.118.0.X 进行通信:

iptables -t nat -A POSTROUTING -o tap0 -j MASQUERADE

不幸的是,我无法知道用户源 IP,否则这个问题很容易解决。到达此端口的任何通信的源 IP 始终相同,因为通信需要通过另一个服务来掩盖真正的源 IP。

我在其他主题中看到,为了标记容器/pod 中的传入数据包,我需要禁用 rt_filter。但是我无法做到这一点,它说这是一个只读文件系统,我不知道是否有可能在 Azure Kubernetes 集群中更改这一点。

除了标记数据包之外还有其他解决方案吗?或者在数据包标记方面还缺少其他东西?

答案1

所以我终于找到了解决方案。问题在于 PREROUTING 中数据包的损坏。在 POSTROUTING 中损坏数据包(因此,在 eth0 退出时),它们能够从 tap0 返回到 eth0,然后返回到客户端。最终结果如下所示:

/sbin/iptables --table mangle --insert POSTROUTING --destination "192.168.0.100" -o eth0 -p tcp --dport "10" --jump MARK --set-mark "10"
/sbin/iptables --table nat --insert PREROUTING --destination "192.168.0.100" -i eth0 -p tcp --dport "10" --jump DNAT --to-destination "10.0.0.4:80"
/sbin/ip rule add prio "10" from all fwmark "10" lookup "10"
/sbin/ip route add "10.0.0.4" via "10.118.0.2" table 10

相关内容