旁路网关拓扑:单臂同网段与职责拆分

最常见的旁路网关单臂形态:小主机与全家设备处在同一二层网段,例如主路由在 192.168.1.1,旁路机在 192.168.1.88。此时主路由仍负责拨号或上级 NAT,小主机并不取代它的DHCP 服务,而是作为可选默认网关出现在终端的路由表里。你要做的第一件事,是把「谁发默认路由、谁发 DNS」写成明确表格:若继续由主路由下发 DHCP,可在保留池里给旁路机静态绑定,再在 DHCP 选项里把默认网关改为旁路机地址,或仅为特定 VLAN、特定 MAC 下发不同网关。

OpenWrt 旁路网关 相比,Linux 小主机的优势在于包管理、内核版本与nftables工具链更贴近服务器习惯;代价是你要自己维护转发防火墙远程管理通道,避免一次改路由就把自己锁在 SSH 之外。若你已在单机上跑通过 Ubuntu 上 TUN 与 systemd,旁路场景只是把「流量来源」从本机进程扩展到转发数据面:内核先把包递交给本机协议栈,再由 Clash TUN策略路由决定出口。

命名约定:下文以 Mihomo(Clash Meta 内核)与 nftables 为例;接口名请用 ip link 替换为你的 eth0enp1s0 等真实名称。示例规则仅用于说明结构,上线前请按你的网段收紧匹配条件。

客户端侧:DHCP 网关、静态路由与 DNS 指向

终端是否走旁路网关,取决于默认路由的下一跳。最省事的做法是在主路由 DHCP 里把网关改成旁路机 IP;若不能全局改,至少给需要代理的设备静态 DHCP绑定并单独下发网关。DNS建议与网关策略一致:要么把 DNS 也指向旁路机,由 ClashDNS 模块或本地转发器统一处理;要么继续用主路由 DNS,但要接受分流与解析路径可能分叉的风险。关于 fake-ip 与路由器 Web 管理页打不开等现象,可对照 fake-ip 与局域网绕过Meta DNS 与 fake-ip-filter 两篇文章,把「解析阶段」和「转发阶段」拆开验证。

若你只想让部分网段走旁路,而其它设备继续直连主路由,可在主路由上写静态路由或基于策略的路由,把特定子网的默认下一跳指到旁路机。无论采用哪种 DHCP 变体,都建议先在单台测试机上手动设置 IPv4 网关与 DNS,确认通断后再批量下发,避免全家断网时才回滚。

内核转发:sysctl 与接口角色

旁路网关要转发来自局域网的非本机目的地址流量,必须打开IPv4 转发。在多数发行版上,临时生效可执行 sysctl -w net.ipv4.ip_forward=1;持久化则写入 /etc/sysctl.d/*.confsysctl --system。若你同时启用 IPv6,还要评估 net.ipv6.conf.all.forwarding 与上游运营商前缀 Delegation 的组合,这部分与 IPv6 双栈 场景叠加时更需谨慎,本文以 IPv4 旁路为主轴。

打开转发后,Linux 会把「目的 IP 不是本机」的包进入 FORWARD 路径。此时若没有任何防火墙规则,转发可能被默认策略拒绝;若规则过宽,又可能把管理口暴露到不该暴露的网段。建议从最小放行开始:仅允许来自可信 LAN 前缀、且从 LAN 接口进入、再从同一接口或上游接口出去的转发,并记录被拒绝的计数器以便审计。

Example sysctl drop-in (paths vary by distro)
# /etc/sysctl.d/99-ipforward.conf
net.ipv4.ip_forward = 1

nftables:放行转发、反欺骗与最小 NAT

nftables 负责三件事:转发过滤反地址欺骗、以及在需要时做源地址伪装。单臂旁路拓扑里,终端发往公网的包会先到达旁路机,再由旁路机查路由,通常下一跳仍是主路由;若你的上游期望看到「来自主路由网段的源地址」,而旁路机直接以终端私网源地址转发,可能被上游丢弃,这时需要在旁路机出口做 MASQUERADESNAT。反之,若主路由已做 NAT 且旁路机仅做策略路由回注,则不一定需要二次伪装——以你的主路由是否「只认识旁路机 MAC」为准。

下面给出一个教学骨架:定义 inet 表,在 forward 钩子上放行已建立连接与来自 LAN 的新建连接;在 postrouting 对离开上行接口的流量做伪装。请把 LAN_IFUP_IF192.168.1.0/24 换成你的真实拓扑。

Illustrative nftables skeleton (replace IF names and prefixes)
flush ruleset

table inet filter {
  chain input {
    type filter hook input priority filter; policy drop;
    iif "lo" accept
    ct state established,related accept
    # TODO: insert SSH/management rules for your admin subnet
  }

  chain forward {
    type filter hook forward priority filter; policy drop;
    ct state established,related accept
    iif "LAN_IF" oif "UP_IF" ip saddr 192.168.1.0/24 accept
    iif "UP_IF" oif "LAN_IF" ct state established,related accept
  }

  chain output {
    type filter hook output priority filter; policy accept;
  }
}

table ip nat {
  chain postrouting {
    type nat hook postrouting priority srcnat; policy accept;
    oifname "UP_IF" masquerade
  }
}

上线 nft -f 规则文件前,务必保留带外管理(云控制台、IPMI、串口)或时间窗口,避免 policy drop 把自己锁在外面。若你暂时只需要「能转发」,可先把 forward 策略设为 accept 做白盒验证,再逐步收紧。与 ClashTUN 协同阶段,常见还需要在 natmangle 表里为 tproxyredirect 预留链位,具体取决于你内核侧采用「纯 TUN 路由」还是「透明代理端口」组合;原理层建议并行阅读 TUN 模式深度解析,理解本机生成流量转发流量在协议栈上的差异。

远程操作提示:错误的路由或 NAT 可能让管理 SSH 会话中断。首次合入 nftablesTUN 时,优先在本地显示器厂商控制台操作,并先备份可启动的旧规则集。

Clash TUN:与旁路网关协同的关键项

在旁路机上启用 TUN 时,建议显式关注:tun.enablestackauto-routestrict-routeauto-redirect(若版本支持)以及 dns-hijack。当只有旁路机本机能走代理、而局域网终端仍直连时,往往不是「allow-lan 没开」这么简单,而是转发流量没有进入 Clash 所挂接的路径:要么需要 tproxy 把转发 TCP/UDP 导入本地监听端口,要么通过策略路由把特定源网段的默认出口改写到 TUN 接口所在的路由表。面板与 API 侧,记得为局域网管理段开启 allow-lan 并绑定安全监听地址,细节可参考 局域网共享与 bind-address

DNS规则必须与网关场景一致:订阅规则集更新失败时,旁路机会退化成「能 ping、不能浏览」的半残状态,这与 订阅与节点维护 里强调的「先保证配置面」同一逻辑。分流写法上,旁路网关更忌讳过宽的 MATCH,建议按 规则分流最佳实践 收敛命中顺序,并用连接日志对照真实域名。

Illustrative YAML fragment (adapt to your core version)
tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true
  strict-route: true

allow-lan: true
bind-address: "*"

上述片段仅为示意:strict-routeauto-route多出口公司 VPN虚拟化网桥并存时可能引入意料之外的路由优先级,需要以 ip ruleip route show table 实测为准。若你更倾向图形客户端管理策略,可在桌面使用成熟客户端编辑同一套配置,再同步到旁路机;选型可参考 如何选择适合自己的 Clash 客户端

逐步验证:从 ping 网关到出口 IP

建议把验证拆成五级:(1) 终端能 ping 旁路机 LAN 地址;(2) 旁路机能 ping 主路由与上游 DNS;(3) 打开转发与 nftables 后,终端能把默认网关切到旁路机且仍能访问国内站点;(4) 在旁路机上用 tcpdump -ni LAN_IF 观察来自终端的 SYN 是否到达;(5)Clash 连接日志里看到对应五元组被策略组命中。出口 IP 测试建议使用两个不同地理归属的检测域名交替访问,避免把 CDN 调度误判为「规则没生效」。

若第 (4) 步有流量而第 (5) 步无日志,优先回到「转发路径是否进入本机代理」这一层,而不是急着改节点。超时与 TLS 报错的分层读法,可继续用 连接日志与 TLS 排障 的对照表,把路由问题远端握手问题区分开。

排障:只有本机走代理的常见根因

症状 A:旁路机本机访问外网走策略组,但其它设备仍显示运营商出口。优先检查 net.ipv4.ip_forwardFORWARD 默认策略、以及反向路径过滤(rp_filter)是否把非对称路径丢弃。症状 B:终端把 DNS 指到主路由,但网关指到旁路机,导致解析与转发路径不一致。此时要么统一 DNS,要么在旁路机对 53 端口做透明转发到 Clash DNS 监听地址。症状 C:能打开国内站点,国际站点间歇失败,多与 fake-ipUDP 路径有关,按前文链接文章逐项关闭变量做对照实验。

记录每一次变更对应的路由表快照nft 计数器,比在社交平台上「抄一段神秘配置」更能稳定复现。旁路网关的价值,正在于把复杂问题拆成可观测的几段:DHCP、转发、防火墙、内核路由、用户态代理。

结语:旁路不等于「少做路由」

Clash 旁路网关并不是把主路由的复杂度「搬家」到小主机上就算完成;相反,它要求你把Linux 内核转发nftablesTUN 三条链路对齐到同一套观测方法:路由表、计数器、连接日志彼此能互证。相比一次性脚本,把 sysctlnftsystemd 单元写进仓库或内部 Wiki,才能在换机、升级内核后快速恢复现场。

相比其它同类工具,Clash 在「把域名分流策略组连接日志放在同一套心智模型里」方面更顺手;当你把旁路机从「能 ping」推进到「能解释每一次命中」时,全屋终端的透明转发才算真正落地。若你希望桌面端也获得同样清晰的策略编辑与更新节奏,成熟客户端在可视化与稳定性上往往更省心。

立即免费下载 Clash,开启流畅上网新体验,把旁路机上验证过的 TUN规则同步到日常设备,减少在多套工具之间来回切换的成本。