EasyTier 与 mwan3: VPN 回程路由修复

发布于 2026-05-27 10:48 2904 字 15 min read

Madobi Nanami avatar

Madobi Nanami

Nanami 的个人技术博客,记录网络、运维、虚拟化与逆向的实践。

博主使用了 EasyTier 在家, 学校, 境内外公网服务器之间通过 协议建立了一个三层 VPN 网络. 平日里在学校或出门在外都会通过这个 VPN 网络连接家里的设备, 访问家里搭建的业务. 在博主今天尝试在学校连接家里服务器上的 SMB 时, 发现全部连接失败, 故着手研究原因. 网络拓扑架构 Topology 在 HomeLab 中, 有三台设备代理了 网段,...

前言

博主使用了 EasyTier 在家, 学校, 境内外公网服务器之间通过 WireGuard 协议建立了一个三层 VPN 网络. 平日里在学校或出门在外都会通过这个 VPN 网络连接家里的设备, 访问家里搭建的业务. 在博主今天尝试在学校连接家里服务器上的 SMB 时, 发现全部连接失败, 故着手研究原因.

网络拓扑架构

Topology
Topology
  • 在 HomeLab 中, 有三台设备代理了 192.168.1.0/24 网段, 即其他设备可以走这三个节点访问该网段. 且对于该网段的访问没有专门的 ACL 限制, 所有设备均可访问
  • 在校园节点中, 网关代理了 192.168.20.0/24 网段, 同样可以被所有设备访问

链路状态

  • 相关节点状态: HomeLab (在线), Router-School (在线)
  • 链路通信状态
  • 校园节点在网关上与 192.168.1.0/24 段的设备通信正常, 但下游设备与该网段的通信时不正常
  • HomeLab 中所有节点的网络通信状态与子网代理状态都是正常的
  • 疑点: 下游设备与 192.168.1.14/32 通信时正常, 但与该网段中其他所有设备通信都不正常. 表现为 ICMP Ping 无回包, 业务数据访问不通

问题分析

造成该故障最常见的原因可能有以下几点

  • 回程路由缺失
  • 反向路径过滤 (rp_filter) 导致回包被丢弃
  • IP 转发未开启
  • EasyTier 的出口策略 / 策略路由冲突

我们这边逐个来排查

1. 回程路由缺失

  • 请求: 192.168.20.0/24 → 网关 → tun0 → VPN → 192.168.1.0/24
  • 回包: 192.168.1.0/24 → VPN → 网关 tun0 → ??? → 192.168.20.0/24

网关自身访问时, 源地址通常是 tun0 的 IP (10.0.64.253), 这个地址天然在 VPN 路由域内, 对端可以直接回包. 而下游设备访问时, 源地址保留为 192.168.20.x, 如果对端节点没有去往 192.168.20.0/24 的路由, 回包就会丢失或走默认路由被丢弃.

这里检查校园网关的路由表

root@X-wrt-School:~# ip rou
default via 10.131.0.1 dev pppoe-wan proto static metric 40 
default via 10.151.0.1 dev pppoe-xwan01 proto static metric 41 
default via 10.141.0.1 dev pppoe-xwan02 proto static metric 42 
default via 10.141.0.1 dev pppoe-xwan03 proto static metric 43 
default via 10.151.0.1 dev pppoe-xwan04 proto static metric 44 
10.0.64.0/24 dev tun0 proto kernel scope link src 10.0.64.253 
10.0.64.0/24 dev tun0 proto static metric 65535 
10.10.64.0/24 dev tun0 proto static metric 65535 
10.131.0.1 dev pppoe-wan proto kernel scope link src 10.131.15.37 
10.141.0.1 dev pppoe-xwan02 proto kernel scope link src 10.141.102.228 
10.141.0.1 dev pppoe-xwan03 proto kernel scope link src 10.141.40.183 
10.151.0.1 dev pppoe-xwan01 proto kernel scope link src 10.151.10.205 
10.151.0.1 dev pppoe-xwan04 proto kernel scope link src 10.151.32.226 
169.254.0.0/16 dev br-lan proto kernel scope link src 169.254.254.254 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 
192.168.1.0/24 dev tun0 proto static metric 65535 
192.168.3.0/24 dev tun0 proto static metric 65535 
192.168.20.0/24 dev br-lan proto kernel scope link src 192.168.20.1 
192.168.20.0/24 dev br-lan proto bird scope link metric 32 
192.168.100.0/24 dev tun0 proto static metric 65535

可以看到, 192.168.1.0/24 正常从 tun0 出口

然后检查 HomeLab 节点中设备的路由表

nanami114@NanamiWork-Server:~$ ip rou
default via 192.168.1.1 dev vmbr0 proto kernel onlink 
10.0.64.0/24 dev tun0 proto static metric 65535 
10.10.64.0/24 dev tun0 proto static metric 65535 
192.168.1.0/24 dev vmbr0 proto kernel scope link src 192.168.1.8 
192.168.3.0/24 dev tun0 proto static metric 65535 
192.168.20.0/24 dev tun0 proto static metric 65535 
192.168.100.0/24 dev tun0 proto static metric 65535

可以看到这里也是正常的, 因此该原因被排除

2. 反向路径过滤 (rp_filter) 导致回包被丢弃

这里直接检查校园网关的 rp_filter 策略

root@X-wrt-School:~# sysctl net.ipv4.conf.all.rp_filter
net.ipv4.conf.all.rp_filter = 0
root@X-wrt-School:~# sysctl net.ipv4.conf.tun0.rp_filter
net.ipv4.conf.tun0.rp_filter = 0
root@X-wrt-School:~# sysctl net.ipv4.conf.br-lan.rp_filter
net.ipv4.conf.br-lan.rp_filter = 0

可以看到, 所有相关网络接口的 rp_filter 均为 0, 证明这里没有问题, 故排除该原因

3. IP 转发未开启

首先网关本身使用的系统为 OpenWrt, 该系统为专业的软路由系统, 因此可以直接排除该原因. 但为了严谨, 这里还是检查一下

root@X-wrt-School:~# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1

4. EasyTier 的出口策略 / 策略路由冲突

在第一项检查中我们可以看到, 路由表中存在多个 pppoe-wan, 说明这是一个多拨的网络环境. 因此可能造成下游流量在转发时被路由策略规则劫持, 导致回包走到了错误的物理接口, 而非回到 tun0.

root@X-wrt-School:~# ip rule show
0:      from all lookup local
1001:   from all iif pppoe-wan lookup 1
1002:   from all iif pppoe-xwan01 lookup 2
1003:   from all iif pppoe-xwan02 lookup 3
1004:   from all iif pppoe-xwan03 lookup 4
1005:   from all iif pppoe-xwan04 lookup 5
2001:   from all fwmark 0x100/0x3f00 lookup 1
2002:   from all fwmark 0x200/0x3f00 lookup 2
2003:   from all fwmark 0x300/0x3f00 lookup 3
2004:   from all fwmark 0x400/0x3f00 lookup 4
2005:   from all fwmark 0x500/0x3f00 lookup 5
2061:   from all fwmark 0x3d00/0x3f00 blackhole
2062:   from all fwmark 0x3e00/0x3f00 unreachable
32766:  from all lookup main
32767:  from all lookup default

通过这条输出, 我们可以注意到:

  • 下游设备 192.168.20.x → 网关 → 匹配 main 路由表走 tun0 → VPN → 192.168.1.y (正常发出)
  • 回包到达网关 tun0 后, 内核会进行路由查找. 此时, 如果回包被打上了某个 fwmark (例如 0x100), 就会命中规则 2001: from all fwmark 0x100/0x3f00 lookup 1, 从而使用路由表 1 进行转发.

这里我们查看路由表 1 的具体路由信息

root@X-wrt-School:~# ip route show table 1
default via 10.131.0.1 dev pppoe-wan metric 40 
10.0.64.0/24 dev tun0 proto kernel scope link src 10.0.64.253 metric 256 
10.0.64.0/24 dev tun0 proto static scope link metric 65535 
10.10.64.0/24 dev tun0 proto static scope link metric 65535 
10.131.0.1 dev pppoe-wan proto kernel scope link src 10.131.15.37 
10.141.0.1 dev pppoe-xwan02 proto kernel scope link src 10.141.102.228 metric 3 
10.141.0.1 dev pppoe-xwan03 proto kernel scope link src 10.141.40.183 metric 4 
10.151.0.1 dev pppoe-xwan01 proto kernel scope link src 10.151.10.205 metric 2 
10.151.0.1 dev pppoe-xwan04 proto kernel scope link src 10.151.32.226 metric 5 
169.254.0.0/16 dev br-lan proto kernel scope link src 169.254.254.254 metric 256 
192.168.1.0/24 dev tun0 proto static scope link metric 65535 
192.168.3.0/24 dev tun0 proto static scope link metric 65535 
192.168.20.0/24 dev br-lan proto bird scope link metric 32 
192.168.20.0/24 dev br-lan proto kernel scope link src 192.168.20.1 metric 256 
192.168.100.0/24 dev tun0 proto static scope link metric 65535

从输出的路由表信息来看, 已经存在去往 192.168.20.0/24 的正确路由, 这说明单纯的回程缺失已经被排除. 但下游设备无法通信, 此时问题大概率出现在连接跟踪表记 (conntrack) 与防火墙过滤的联合作用上.

首先我们查看 OpenWrt 的防火墙配置

OpenWrt 防火墙中 EasyTier 接口的出入站配置
OpenWrt 防火墙中 EasyTier 接口的出入站配置
可以看到, EasyTier 接口的出入配置都是正确且有效的, 那么接下来我们对问题进行深入分析与排查

深入分析

mwan3 的标记机制

mwan3 会在 mangle 表的 PREROUTING 和 OUTPUT 中挂载 mwan3_hook. 核心逻辑如下

  • CONNMARK restore: 恢复连接上保存的标记 (fwmark).
  • 如果恢复后标记为 0, 则根据入接口 (mwan3_ifaces_in) 或策略 (mwan3_rules) 打上新标记, 最后 CONNMARK save, 将标记保存到连接跟踪里.
  • 此后所有属于该连接的包都会自动被还原相同标记, 并通过 ip rule 的 fwmark 匹配, 强制走对应的路由表 (如 table 1~5).

当前链路存在的问题

当 192.168.20.x 首次访问 192.168.1.x 时

  • 出站 (br-lan → 网关 → tun0): 该包在 PREROUTING 或 OUTPUT 链被 mwan3 打上某个标记 (例如 0x100), 并 CONNMARK save 保存.
  • 回包 (tun0 → 网关 → 应回到 br-lan): 回包进入 PREROUTING → mwan3_hook → CONNMARK restore 直接将标记恢复为 0x100. 由于标记非零, 后续 mwan3_ifaces_in 等链都被跳过 (它们要求 mark match 0x0/0x3f00). 回包带着 0x100 进入路由查找, 命中 ip rule 中的 2001: from all fwmark 0x100/0x3f00 lookup 1, 使用 table 1 转发.

尽管 table 1 有去往 192.168.20.0/24 的直连路由, 理论上可以通, 但实际环境中常被以下两种隐形过滤阻断:

  1. filter 表 FORWARD 链的状态跟踪丢弃 大多数 OpenWrt 默认防火墙 FORWARD 链允许 ESTABLISHED ,RELATED 状态, 丢弃 INVALID. 当回包带着被强制改变的路由标记走过路由后, 连接跟踪可能将其状态标记为 INVALID (因为出方向走的是 main 表或不同的路由表, 回包却走 table 1, 属于非对称路由, conntrack 可能视其为无效), 随后被 FORWARD 链丢弃.

  2. 反向路径校验 (即使 rp_filter=0 仍有其他机制) 某些内核版本在策略路由下仍会做额外的路径校验, 或者 secure_redirects 等参数造成丢弃. 但更常见的是第 1 点.

因此, 即使路由存在, 包也可能在送到 br-lan 之前就被 filter 规则或 conntrack 剔除.

故障修复

快速恢复

最快且最可靠的办法是让回包不再经过 FORWARD 转发路径, 而是直接进网关本机. 将下游设备的源地址伪装为网关 VPN 接口的地址即可.

iptables -t nat -A POSTROUTING -s 192.168.20.0/24 -o tun0 -j MASQUERADE

执行完后看效果:

C:\Users\Nanami114>ping 192.168.1.4

Pinging 192.168.1.4 with 32 bytes of data:
Reply from 192.168.1.4: bytes=32 time=11ms TTL=63
Reply from 192.168.1.4: bytes=32 time=11ms TTL=63
Reply from 192.168.1.4: bytes=32 time=11ms TTL=63
Reply from 192.168.1.4: bytes=32 time=12ms TTL=63

Ping statistics for 192.168.1.4:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 11ms, Maximum = 12ms, Average = 11ms

C:\Users\Nanami114>ping 192.168.1.8

Pinging 192.168.1.8 with 32 bytes of data:
Reply from 192.168.1.8: bytes=32 time=7ms TTL=63
Reply from 192.168.1.8: bytes=32 time=7ms TTL=63
Reply from 192.168.1.8: bytes=32 time=7ms TTL=63
Reply from 192.168.1.8: bytes=32 time=7ms TTL=63

Ping statistics for 192.168.1.8:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 7ms, Maximum = 7ms, Average = 7ms

可以看到, 此时下游设备已经可以正常收到对端设备 ICMP Ping 的回包. 接下来查看业务流量状态:

SMB
SMB
这里可以看到, 此时 SMB 流量已经可以正常通讯, 说明整个网络链路已经恢复, 下游设备恢复了与 192.168.1.0/24 段的正常通讯.

当然, 这个方法虽然恢复快速但也存在不妥:

  • 所有下游设备去往 192.168.1.0/24 的通讯, 都会被目标设备识别为 10.0.64.253 在与其通信, 也就是校园网关在与其通信. 为了解决这个问题, 下面我们进行深度修复.

根因修复: 调整 mangle 规则, 避免 VPN 回程路由被标记

  • 精准修复命令 在 mwan3_hook 中 CONNMARK save 之前插入一条规则: 如果包是从 tun0 进入且目标是 192.168.20.0/24, 则将其标记清零, 并让 conntrack 保存清零后的标记. 这样该连接后续流量将不再受多线策略影响.

首先查看 mwan3_hook 接口编号

root@X-wrt-School:~# iptables -t mangle -L mwan3_hook --line-numbers
Chain mwan3_hook (2 references)
num  target     prot opt source               destination         
1    CONNMARK   all  --  anywhere             anywhere             mark match 0x0/0x3f00 CONNMARK restore mask 0x3f00
2    mwan3_ifaces_in  all  --  anywhere             anywhere             mark match 0x0/0x3f00
3    mwan3_local  all  --  anywhere             anywhere             mark match 0x0/0x3f00
4    mwan3_rules  all  --  anywhere             anywhere             mark match 0x0/0x3f00
5    mwan3_connected  all  --  anywhere             anywhere            
6    CONNMARK   all  --  anywhere             anywhere             CONNMARK save mask 0x3f00

可以看到 mwan3_connected 是第五条, CONNMARK save 是第六条. 我们需要在这两条之间插入标记清零的规则

iptables -t mangle -I mwan3_hook 6 -i tun0 -d 192.168.20.0/24 -j MARK --set-mark 0

mwan3_hook 链中插入的 mangle 规则
mwan3_hook 链中插入的 mangle 规则
这里可以看到, 刚才插入的规则已经生效. 此时看下游设备效果. 这里使用下游设备连接对端物理设备的 SSH, 连接两次即可在终端内看到上一次连接的 IP 地址.

Linux NanamiWork-Server 7.0.0-3-pve #1 SMP PREEMPT_DYNAMIC PMX 7.0.0-3 (2026-04-21T22:56Z) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed May 27 16:19:00 2026 from 192.168.20.2
nanami114@NanamiWork-Server:~$

可以看到, 这里显示 Last login: Wed May 27 16:19:00 2026 from 192.168.20.2, 证明改动已经生效, 并已经恢复了与目标设备的连接. 至此, 整个 VPN 网络的修复就已完成.

后记

本人非专业网络运维, 如有疏漏或错误, 还请指出! 如果您觉得文章不错, 还请分享给有需要的


相关阅读

随机文章

加载中...