LAN 客户端直到启用策略路由才走路由器 VPN
转发规则只负责放行数据包,从不选择接口。真正决定哪些 LAN 客户端使用路由器 VPN 的,是单独的策略表和规则。
路由器通过隧道上网,身后那台笔记本却仍然报告 ISP 地址。添加放行规则没有用,这个失败很有启发:过滤回答的是数据包能否通过,而不是它去往哪里。接口早已由一次与客户端列表毫无关系的路由查找决定。把查找修好,防火墙就不再是嫌疑对象。
过滤规则无法选择接口
Linux 路由器上的数据包流向先执行路由决策,再经过 forward 钩子。等规则匹配到出站隧道设备时,内核早已决定隧道就是出口。如果主表仍然偏好 WAN 默认路由,数据包正前往 ISP,刚写下的放行规则根本看不到它。仅凭这一条顺序事实,就能解释为什么整页的新防火墙规则毫无作用。
下面的例子使用 br-lan 上 192.168.8.0/24 的 LAN、隧道设备 tun0,以及 192.168.8.23 上一台应当走隧道的机顶盒。
改规则之前先读查找结果
让内核代那台客户端解析一条路由。返回内容包含出口设备和将被选中的源地址,确认诊断所需的全部信息都在其中。如果返回的是 WAN 设备,数据包根本没有机会碰到你的规则。
ip -4 route get 198.51.100.7 from 192.168.8.23
对应当留在普通路径上的客户端重复同样的查询。两个结果都指向同一设备时,说明还没有任何按源地址的策略生效,问题出在路由而不是过滤。
把表挂到你想覆盖的客户端上
策略路由会在主表之前插入一次规则查找。建一张默认路由为隧道的表,再把这张表绑定到选择器:入接口、源地址或防火墙标记。优先级决定顺序,主表排在列表很靠后的 32766,所以编号小的规则先被查询。接口选择器覆盖网桥上的每台客户端;地址选择器只覆盖一台机器。
ip -4 route add default dev tun0 table 200
ip -4 rule add iif br-lan lookup 200 priority 200
固件界面通常提供与策略路由页或 VPN 策略页相同的对象。那里的设备列表比手写规则更好维护,也通常能在改变规则语法的升级后继续存在。
选择器要有意识地选。接口规则简短且面向未来,但它也会捕获路由器自身发到该网桥的管理流量。源地址规则精确,但设备列表一变就得改。把选择写下来,因为下一个问“为什么这台设备行为不同”的人会需要它。
把本地目的地留在隧道之外
新表只认识你放进去的路由。缺少 LAN 前缀,打印机和 NAS 的流量就会跟着隧道默认路由消失。throw 路由会在此表结束查找,把决定交回主表。
ip -4 route add throw 192.168.8.0/24 table 200
省掉那条路由,本地共享就会中断;选择器比预想的更宽时,路由器自身的管理会话也可能消失。接着把源地址问题定下来:仍带 LAN 地址的隧道数据包需要远端知道回程,而在隧道上做 masquerading 就去掉了这个要求,同时也去掉了远端将看到的客户端身份。
运行时添加的规则和路由在重启或固件升级后就会消失。把它们加入路由器的启动机制,重启一次,再从客户端复测:它的公网地址、应当在 WAN 上的第二台客户端,以及新建连接期间的隧道计数器。