有一台 linux 机器, 配置了一个 bridge0 网卡,绑定一个物理网卡, ip 为 192.168.20.10. 在上面开了个 fakeip 类型的透明网关虚拟机, ip 为 192.168.20.5, 虚拟机网卡桥接到宿主机 bridge0 网卡.
宿主机上还启用了 docker, docker 使用自定义虚拟网卡 br-xxx.
现在发现个问题: 宿主机 docker 容器无法正常走梯子, 宿主机本身走梯子流量正常. 因为梯子流量走的都是 fakeip, 下面以 7.0.0.11 举例, 抓包发现如下现象:
问题出在这里, 抓包发现透明网关的 icmp 响应 目的 mac 是宿主机的 bridge0, 而不是路由器网关, 这就导致 icmp 没办法经过路由器原路 返回到 宿主机, 再返回给宿主机的容器.
而宿主机直接 ping 7.0.0.11 没问题, 报文也是一样的回复路径, 但是由于目的 mac 是宿主机的 bridge0, 也算被宿主机收到了.
感觉有点像 hairpin-nat 这种类型的问题, 请问应该修改哪个环节的配置解决该问题?
1
kyonn OP 问题原因应该是 透明网关发现 icmp 的源 ip 是宿主机 bridge0 网卡, 所以目的 mac 就直接用 bridge0 网卡的, 而不是回复给路由器网关.
|
2
kyonn OP 宿主机直接加一条静态路由 : route add -net 7.0.0.0 netmask 255.0.0.0 gw 192.168.10.5 可以解决问题.
想知道比较正确的做法应该是怎样的? |
3
kyonn OP 宿主机上还有其他虚拟机, 这些虚拟机的容器内 到 7.0.0.11 是可达的, 抓包发现路径也跟前面的一样, 响应报文不会经过路由器网关. 也就是说, 报文的去程和回程也是不同的, 但是可达.
|
4
yinmin 46 天前
你这个是不对称路由,不稳定的,应该避免。
方法一: 路由器 192.168.20.1 加 MASQUERADE: iptables -t nat -A POSTROUTING -s 192.168.20.0/24 -d 7.0.0.0/8 -j MASQUERADE 方法二: 每个客户端机器都加静态路由: ip route add 7.0.0.0/8 via 192.168.20.5 (linux) route add 7.0.0.0 mask 255.0.0.0 192.168.20.5 (windows) |
5
kyonn OP @yinmin 有些难以取舍. 还有别的方法吗?
方法一多加了一层 NAT, 性能倒是其次, 关键是 透明网关 上的统计信息无法再看到实际的源 ip 了. 方案二每台机器都要配置, 最早还开了 dchp option121 直接下发 7.0.0.0/8 的静态路由给所有客户端, 后来发现米家的中枢网关会被这条下发的静态路由规则搞死, 上不了网, 因此就把 option 121 关掉了. |
6
yinmin 46 天前 via iPhone
方式三:将客户端机器的网关配置成透明网关 ip
|
8
yinmin 42 天前
@kyonn 以前我发现 tplink 这种硬路由设置不对称路由蛮正常的,但是软路由就是不正常,最近好像突然搞明白了原因。
你试试在主路由 192.168.20.1 不加 MASQUERADE ,改成 NOTRACK ,试试是否 OK: iptables -t raw -A PREROUTING -s 192.168.20.0/24 -d 7.0.0.0/8 -j NOTRACK |
9
kyonn OP @yinmin 不太行, 主路由上之前已经有了条 mangle rule, 把目标是 7.0.0.0/8 的路由标记, 转发给一个新的路由表处理. 这个路由表再转发给 透明网关.
|
10
yinmin 40 天前 via iPhone
@kyonn 不冲突的呢,这是在 raw 表,告诉 iptables 不用 track 。
原因是:默认 iptables 转发也会跟踪 tcp 状态的,不对称路由只有单程无法跟踪到 tcp 状态,导致主路由 iptables 阻断连接。这条命令让 iptables 转发数据即可,别跟踪状态,与路由无关。 |
12
yinmin 40 天前 via iPhone
家宽硬路由器只在 nat 时才会跟踪连接状态,不会在静态路由时去跟踪 tcp 连接状态,所以很多硬路由能跑不对称路由。
软路由大都使用 iptables 或 nftables ,这个防火墙比较严格,在静态路由的时候也会去跟踪 tcp 状态,所以很多软路由不能跑不对称路由。解决方案有 2 种: MASQUERADE 或者 NOTRACK 。 |
13
yinmin 40 天前 via iPhone
静态路由要保留、去掉 MASQUERADE 加 NOTRACK ,如果不行的话,-A 改成-I ,也就是插入 raw 第一条
|
14
yinmin 40 天前 via iPhone
接#13 客户端的静态路由去掉,主路由加静态路由,然后先加 MASQUERADE 能通,说明主路由 OK ,然后 MASQUERADE 改 NOTRACK 。
|