V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
kyonn
V2EX  ›  程序员

求助个透明网关问题

  •  
  •   kyonn · 46 天前 · 1521 次点击
    这是一个创建于 46 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有一台 linux 机器, 配置了一个 bridge0 网卡,绑定一个物理网卡, ip 为 192.168.20.10. 在上面开了个 fakeip 类型的透明网关虚拟机, ip 为 192.168.20.5, 虚拟机网卡桥接到宿主机 bridge0 网卡.

    宿主机上还启用了 docker, docker 使用自定义虚拟网卡 br-xxx.

    现在发现个问题: 宿主机 docker 容器无法正常走梯子, 宿主机本身走梯子流量正常. 因为梯子流量走的都是 fakeip, 下面以 7.0.0.11 举例, 抓包发现如下现象:

    1. 宿主机 docker 容器 ping 7.0.0.11, icmp 流量先到 br-xxx 网卡, 再经过 src nat 从宿主机 bridge0 网卡发出到路由器网关 192.168.20.1. 网关因为配置了 7.0.0.0/8 的路由, 会将流量再转发给 192.168.20.5, 即又发给了 宿主机, 再转到宿主机的透明网关虚拟机. 透明网关虚拟机回复 icmp 报文,

    问题出在这里, 抓包发现透明网关的 icmp 响应 目的 mac 是宿主机的 bridge0, 而不是路由器网关, 这就导致 icmp 没办法经过路由器原路 返回到 宿主机, 再返回给宿主机的容器.

    而宿主机直接 ping 7.0.0.11 没问题, 报文也是一样的回复路径, 但是由于目的 mac 是宿主机的 bridge0, 也算被宿主机收到了.

    感觉有点像 hairpin-nat 这种类型的问题, 请问应该修改哪个环节的配置解决该问题?

    14 条回复    2025-03-15 20:19:11 +08:00
    kyonn
        1
    kyonn  
    OP
       46 天前
    问题原因应该是 透明网关发现 icmp 的源 ip 是宿主机 bridge0 网卡, 所以目的 mac 就直接用 bridge0 网卡的, 而不是回复给路由器网关.
    kyonn
        2
    kyonn  
    OP
       46 天前
    宿主机直接加一条静态路由 : route add -net 7.0.0.0 netmask 255.0.0.0 gw 192.168.10.5 可以解决问题.

    想知道比较正确的做法应该是怎样的?
    kyonn
        3
    kyonn  
    OP
       46 天前
    宿主机上还有其他虚拟机, 这些虚拟机的容器内 到 7.0.0.11 是可达的, 抓包发现路径也跟前面的一样, 响应报文不会经过路由器网关. 也就是说, 报文的去程和回程也是不同的, 但是可达.
    yinmin
        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)
    kyonn
        5
    kyonn  
    OP
       46 天前
    @yinmin 有些难以取舍. 还有别的方法吗?

    方法一多加了一层 NAT, 性能倒是其次, 关键是 透明网关 上的统计信息无法再看到实际的源 ip 了.
    方案二每台机器都要配置, 最早还开了 dchp option121 直接下发 7.0.0.0/8 的静态路由给所有客户端, 后来发现米家的中枢网关会被这条下发的静态路由规则搞死, 上不了网, 因此就把 option 121 关掉了.
    yinmin
        6
    yinmin  
       46 天前 via iPhone
    方式三:将客户端机器的网关配置成透明网关 ip
    kyonn
        7
    kyonn  
    OP
       46 天前
    @yinmin 好的, 多谢.
    yinmin
        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
    kyonn
        9
    kyonn  
    OP
       40 天前
    @yinmin 不太行, 主路由上之前已经有了条 mangle rule, 把目标是 7.0.0.0/8 的路由标记, 转发给一个新的路由表处理. 这个路由表再转发给 透明网关.
    yinmin
        10
    yinmin  
       40 天前 via iPhone
    @kyonn 不冲突的呢,这是在 raw 表,告诉 iptables 不用 track 。

    原因是:默认 iptables 转发也会跟踪 tcp 状态的,不对称路由只有单程无法跟踪到 tcp 状态,导致主路由 iptables 阻断连接。这条命令让 iptables 转发数据即可,别跟踪状态,与路由无关。
    kyonn
        11
    kyonn  
    OP
       40 天前
    @yinmin 我把之前在主机上添加的路由规则删了, 去主路由上加了你说的规则, 不起作用, 还是不通.
    yinmin
        12
    yinmin  
       40 天前 via iPhone
    家宽硬路由器只在 nat 时才会跟踪连接状态,不会在静态路由时去跟踪 tcp 连接状态,所以很多硬路由能跑不对称路由。

    软路由大都使用 iptables 或 nftables ,这个防火墙比较严格,在静态路由的时候也会去跟踪 tcp 状态,所以很多软路由不能跑不对称路由。解决方案有 2 种: MASQUERADE 或者 NOTRACK 。
    yinmin
        13
    yinmin  
       40 天前 via iPhone
    静态路由要保留、去掉 MASQUERADE 加 NOTRACK ,如果不行的话,-A 改成-I ,也就是插入 raw 第一条
    yinmin
        14
    yinmin  
       40 天前 via iPhone
    接#13 客户端的静态路由去掉,主路由加静态路由,然后先加 MASQUERADE 能通,说明主路由 OK ,然后 MASQUERADE 改 NOTRACK 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   957 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:47 · PVG 05:47 · LAX 14:47 · JFK 17:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.