问题
Docker 容器网络不经过主机 TPROXY 配置的隧道。
设置
我的机器上运行着支持 TPROXY 的代理服务器(侦听 127.0.0.1:8080)。我配置 iptables 使用目标将流量重定向到此代理服务器,TPROXY
如下所示:
ip route add local default dev lo table 100
ip rule add fwmark 1 table 100
iptables -t mangle -N PROXY
# Ignore private IPs
iptables -t mangle -A PROXY -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A PROXY -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A PROXY -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A PROXY -d 192.0.0.0/24 -j RETURN
iptables -t mangle -A PROXY -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A PROXY -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A PROXY -p tcp -j TPROXY --on-port 8080 --on-ip 127.0.0.1 --tproxy-mark 1
iptables -t mangle -A PROXY -p udp -j TPROXY --on-port 8080 --on-ip 127.0.0.1 --tproxy-mark 1
iptables -t mangle -A PREROUTING -j PROXY
iptables -t mangle -N PROXY_SELF
# Ignore private IPs
iptables -t mangle -A PROXY_SELF -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY_SELF -d 100.64.0.0/10 -j RETURN
iptables -t mangle -A PROXY_SELF -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A PROXY_SELF -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A PROXY_SELF -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A PROXY_SELF -d 192.0.0.0/24 -j RETURN
iptables -t mangle -A PROXY_SELF -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY_SELF -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A PROXY_SELF -d 255.255.255.255/32 -j RETURN
iptables -t mangle -A PROXY_SELF -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A PROXY_SELF -m mark --mark 2 -j RETURN
iptables -t mangle -A PROXY_SELF -p tcp -j MARK --set-mark 1
iptables -t mangle -A PROXY_SELF -p udp -j MARK --set-mark 1
iptables -t mangle -A OUTPUT -j PROXY_SELF
对于本地生成的数据包,它按预期工作。但是,Docker 容器数据包通过主机时存在问题。由于我没有更改任何 Docker 默认网络/iptables 配置,因此它使用主机互联网连接设备 ( eth0
) 作为网关来传递传出网络。当我启用 iptables tproxy(上面的命令)将流量重定向到代理服务器时,源自 Docker 容器内部的流量不会到达代理服务器,并且无法访问互联网。我该如何解决?
调试
我LOG
对每个表中的每个链都使用了 iptables 目标,以查看数据包如何遍历,并调试(或猜测)问题所在。据我了解,对于本地生成的数据包,当它们通过mangle
表链时OUTPUT
,它们会被标记为 fwmark 1,然后由于, 和命令而路由到lo
设备(而不是默认的互联网连接设备) ,然后它们将收到在设备上,它通过表链中定义的目标重定向到代理服务器,以及代理过程的其余部分。另一方面,对于从 Docker 容器发送的数据包,它们首先在(默认 Docker 桥接网络设备)上接收,一旦它们被目标重定向,数据包eth0
ip route
ip rule
lo
tproxy
mangle
PREROUTING
docker0
tproxy
挂起在nat
表链中INPUT
,AFAIK 就在它们被移交给代理服务器进程之前。由于我没有看到来自代理服务器的任何日志消息,我猜这些数据包正在以某种方式被丢弃(?)。我还测试了以下内容:
- 运行绑定到的代理服务器
0.0.0.0
- 启用
net.ipv4.ip_forward
内核选项 - 让
docker0
数据包首先通过mangle
表链PREROUTING
,只需用 fwmark 1 标记它们(不跳转到tproxy
),然后将ip route
它们重新路由回lo
(类似于本地生成的数据包发生的情况),然后为该数据包应用 tproxy 重定向设备稍后收到的关联数据包lo
。这按预期工作转发的lo
数据包,但设备上接收到的相应数据包会挂在mangle
表链之后PREROUTING
,并且不会继续。
但没有任何结果...
任何帮助表示赞赏。
由于我是 Linux 上 iptables 高级网络的新手(从 3 天前开始完全开始),如果还需要提供更多信息,请告诉我。
干杯