Docker容器打iptables来代理

Docker容器打iptables来代理

我有两个 VPS,第一台机器(代理人从现在开始)用于代理和第二台机器(码头从现在开始)是 docker 主机。我想将 docker 容器本身内部生成的所有流量重定向到代理人,不暴露码头机器公共IP。

由于 VPS 之间的连接是通过互联网进行的,因此没有本地连接,因此在它们之间创建了一条隧道IP隧道如下:

代理人:

ip tunnel add tun10 mode ipip remote x.x.x.x local y.y.y.y dev eth0
ip addr add 192.168.10.1/24 peer 192.168.10.2 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

码头:

ip tunnel add tun10 mode ipip remote y.y.y.y local x.x.x.x dev eth0
ip addr add 192.168.10.2/24 peer 192.168.10.1 dev tun10
ip link set dev tun10 mtu 1492
ip link set dev tun10 up

PS:不知道有没有IP隧道可以用于生产,这是另一个问题,无论如何打算使用利布雷斯旺或者开放VPN作为 VPS 之间的隧道。

之后,在两个 VPS 上的 iptables 中添加 SNAT 规则和一些路由规则,如下所示:

代理人:

iptables -t nat -A POSTROUTING -s 192.168.10.2/32 -j SNAT --to-source y.y.y.y

码头:

iptables -t nat -A POSTROUTING -s 172.27.10.0/24 -j SNAT --to-source 192.168.10.2
ip route add default via 192.168.10.1 dev tun10 table rt2
ip rule add from 192.168.10.2 table rt2

最后但并非最不重要的一点是创建一个 docker 网络,并附加一个测试容器,如下所示:

docker network create --attachable --opt com.docker.network.bridge.name=br-test --opt com.docker.network.bridge.enable_ip_masquerade=false --subnet=172.27.10.0/24 testnet
docker run --network testnet alpine:latest /bin/sh

不幸的是,这一切都没有成功。那么问题是如何调试呢?这是正确的方法吗?您将如何通过代理进行重定向?

关于理论的一些话:来自 172.27.10.0/24 子网的流量命中 iptables SNAT 规则,源 IP 更改为 192.168.10.2。通过路由规则,它通过tun10设备进行路由,它是隧道。并命中另一个 iptables SNAT 规则,将 IP 更改为 yyyy,并最终到达目的地。

答案1

我想通过代理重定向docker容器内部生成的所有流量,以免暴露docker机器的公共IP。

如果这就是您想要的,那么两个 docker 实例之间不需要 NAT。

您确实需要在proxy实例上启用转发(例如通过 sysctl)。

如果公网IPproxy可见的inside ,那么您只需要在内部(而不是在)proxy内使用该公共 IP 进行 SNAT 。这也称为假面舞会。这是一个标准设置,谷歌搜索“masquerade”。proxydock

如果公网IPproxy不可见在里面proxy(即,当你这样做时列出ip addr),因为主机proxy(甚至更上面的其他主机)执行NAT,那么你应该避免双重NAT,并使dock主机看起来就像另一个容器一样。详细信息取决于主机上网络的设置方式(您没有说),但基本上隧道末端dock必须具有与proxy主机上的容器位于同一子网中的 IP。

隧道ipip未加密;您不应该使用此隧道,除非传输完全位于受信任的网络内(情况可能并非如此,因为您似乎需要不同的公共 IP 地址)。所以使用OpenVPN或易于设置的替代方案,例如丁克Libreswan设置起来并不那么容易。

编辑

一步步:

1) 验证隧道是否正常工作。上proxy,做ping 192.168.10.2。上dock,做ping 192.168.10.1。在tcpdump您有权访问的所有干预网络接口上进行调试。如果 ipip-tunnel 不起作用,请使用其他隧道并使其工作。

2) 删除所有iptables规则dock。设置通过隧道的默认路由。测试ip route get 8.8.8.8该路线是否有效。

3)假设eth0onproxy有公网IP,删除所有iptables规则,执行:

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o tun10 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -o eth0 -i tun10 -j ACCEPT

eth0这表示“转发数据包,通过将公共 IP 地址作为源地址来伪装所有转发的数据包eth0,并连接跟踪它们。来自的数据包tun10始终可以转发到eth0,传入的数据包只有在建立连接时eth0才会转发到tun10经过dock。”

通过执行ping 8.8.8.8on dock,同时运行tcpdumpontun10eth0on 来进行测试proxy。您应该看到数据包被转发,并且源被重写。

4)一旦一切正常,使其永久化:编辑/etc/sysctl.conf或编辑文件/etc/sysctl.d以使其具有net.ipv4.ip_forward = 1.使用启动脚本添加iptables规则,或者使用发行版提供的任何包来保存规则。

相关内容