本页目录

家庭网络架构实战:有线 Mesh、单臂旁路由与 Fail-Open

这套网络的目标不是堆设备,而是同时解决三个问题:多房间稳定覆盖、按设备选择代理路径,以及旁路由故障时不拖垮全屋网络。最终结构是:光猫桥接 → 主路由拨号 → 4 个 AP 有线回传;N100 单网口设备承担透明代理和 DNS,核心工作站则绕过旁路由,自行管理代理。

本文既是架构复盘,也是可以照着检查自己网络的设计说明。文中的主机名、SSID、订阅地址和公网节点均已泛化;.1.7.8 等仅用于说明同一私网内的角色关系。

设计结论先行

  • Mesh 节点尽量使用有线回传,无线漫游不能弥补回传链路本身的拥塞。
  • 单臂旁路由的流量会从同一个 LAN 接口进出,回程对称和 ICMP Redirect 必须单独处理。
  • DNS、透明代理和 DHCP 网关耦合后,应设计 Fail-Open;代理坏了可以降级,不能让全屋断网。
  • 关键工作站可以直连主路由并运行自己的 TUN,与全屋透明代理隔离故障域。
  • 配置应从一份真源派生,目标端只维护自己的 DNS、TUN 和入站差异。

一、物理拓扑

光猫只做光电转换(桥接,不拨号不路由不 NAT),公网 IP 直落主路由 PPPoE 接口,无双重 NAT。全屋约 120m² 四室,单 AP 无法覆盖所有房间(尤其主卧和次卧隔两道承重墙),4 AP 有线 Mesh 覆盖死角 + 统一 SSID 无缝漫游。全部 AP 走有线回传,不占用无线带宽。

家庭网络物理拓扑(v2.1) · 120m² 四室 · 4 AP 有线 Mesh 覆盖 Internet GPON · 电信 ONT 光猫 · 桥接 主路由 .1 (RP01) PPPoE 拨号 · NAT · DHCP · Mesh root 全有线回传 客厅 .62 RC06 · 入户区 主卧 .67 RP03 · 隔两墙 书房 .80 RP03 · N100 挂这里 次卧 .227 RP03 · 最远端 N100 .7 (旁路由) 单网口 · 挂书房 AP LAN 工作站 .8 (WiFi)

二、Mesh 网络

节点IP硬件位置覆盖难点回传
root.1RP01入户客厅中心
leaf.62RC06客厅覆盖入户区有线
leaf.67RP03主卧隔两道承重墙有线
leaf.80RP03书房核心设备区有线
leaf.227RP03次卧最远,单 AP 无信号有线

无线侧使用一个主 SSID(5 GHz,日常设备)和一个独立的 2.4 GHz IoT SSID。IoT 网络是否隐藏并不构成安全边界;真正的隔离应依靠访客网络、VLAN 或防火墙策略。

三、关键主机

设备IP角色连接系统
ONT— (桥接,无 IP)光电转换光纤入,以太网出电信 GPON
小米主路由.1PPPoE/NAT/DHCP/Mesh rootWAN 接光猫MiWiFi(RP01)
N100 旁路由.7透明代理 + DNS(AdGuard Home)有线单网口,挂书房 AP LANiStoreOS
核心工作站.8开发与自托管服务,⁠静态网关指向 .1Wi-Fi,连接书房 APLinux
旧节点.9退役旁路由,仅保留维护入口Wi-FiWindows

关键设计:核心工作站(.8)的静态网关指向主路由(.1),不受旁路由透明代理影响。它自行运行 TUN 模式的 mihomo,并使用返回真实地址的 DNS,因此与普通家庭设备形成两个独立的故障域。

四、DHCP 与 DNS

  • 网关⁠:DHCP 默认下发 .7(N100),普通设备经旁路由转发。核心工作站例外,静态网关指向 .1。
  • DNS:DHCP 只发布 .7(N100 上的 AdGuard Home)。不要把公网 DNS 作为“备用”同时下发,因为客户端可以绕过主 DNS,过滤与分流结果会变得不可预测。组件故障时由 Fail-Open 临时接管 :53。
  • 租约⁠:1–2 小时。较短租约便于修改网关配置后加快收敛,但不能替代网关高可用。
  • 地址池⁠:192.168.31.5–250。

正常 DNS 链路

DNS 链路:客户端 → AdGuard → mihomo fake-ip 分流 → 上游 客户端 AdGuard :53 广告过滤 + 缓存 · Docker mihomo :1053 fake-ip 分流 国内: UDP 223.5.5.5 国外: DoH 1.1.1.1 fake-ip 模式下,AdGuard 收上游响应全是 198.18.x 段,mihomo 内部映射还原真实 IP。 本方案不在 AdGuard 层验证 DNSSEC;fake-ip 是合成响应,启用前需单独验证整条解析链。 DHCP 仅发布 AdGuard;是否存在 DoH/DoT 绕过仍需通过流量观测确认。

五、流量路径

正常模式

流量路径:旁路由代理 + 回国直连双路径 客户端 N100 (.7) · nftables prerouting 发夹弯:MASQUERADE 改源→.7 ① 大陆 IP 防火墙 return 不进 mihomo,直连回国 ② 其余流量 mihomo 分流 国内直连 / 国外走代理 主路由 .1 PPPoE → 公网 工作站 (.8) 网关→.1,直连主路由,不经旁路由 ① 大陆 IP 靠 china_ip 集合(~3.7k chnroute)在防火墙 prerouting 就 return,物理上不进 mihomo,回国流量硬防护。

① 大陆 IP 在防火墙层 return,物理上不进 mihomo——回国流量硬防护。单网口发夹弯(同 br-lan 进出)转发回 .1,⁠必须 MASQUERADE 改源成 .7,否则回程不对称直接断网。

② fake-ip 漏命中 geosite 的 CN 域名⁠(拿到 198.18.0.0/15 地址)仍会进入 mihomo,可由规则尾部的 GEOIP,CN,DIRECT 在解析真实地址后兜底。核心工作站使用自己的 TUN 和真实地址 DNS,不依赖这条路径。

Fail-Open 模式(mihomo/AdGuard 挂了)

Fail-Open:代理组件故障时降级为直连 客户端 N100 (.7) · 仍是网关 nft redirect 已移除 · MASQ 注入 主路由 .1 PPPoE · DNS 接管 公网 触发条件:mihomo 或 AdGuard 进程异常 → nikki-failopen(procd)自愈 行为:nftables redirect 整表删除 → 全流量直通主路由 → DNS :53 重定向到主路由 无代理 · 无广告过滤 · 全直连 —— 降级保底,不断网

这里的 Fail-Open 有明确边界:它依赖 N100 上仍能运行的守护进程,只覆盖 mihomo 或 AdGuard Home 退出、卡死等软件故障。N100 断电、内核死机或 LAN 链路中断时,.7 作为默认网关会整体不可达,仍会导致普通客户端断网。要覆盖这一层故障,需要 VRRP/双机热备,或由主路由健康检查后自动改发 DHCP 网关;当前架构没有实现。

六、分流策略与回国流量防护

曾发生 CN 域名漏命中 geosite → MATCH,PROXY → 美国节点回连国内服务器 → GFW 识别"回国流量"封 VPS IP。现采用双层防护⁠:

第一层(硬,防火墙):bypass_china_mainland_ip=1(v4)填充 nft china_ip 集合(~3.7k chnroute)。大陆 IP 在 prerouting 就 return,物理上到不了 mihomo,与域名是否命中 geosite 无关。

  • 单网口发夹弯需 table inet bypass_masq 把转发流量 MASQUERADE 改源成 .7。
  • v6 暂不开防火墙旁路(避免 v6 发夹弯翻车),v6 CN 走 mihomo GEOIP,CN 兜底。

第二层(兜底,mihomo 规则):规则尾 GEOSITE,cn,DIRECTGEOIP,CN,DIRECTMATCH,PROXY。fake-ip 漏网的 CN 域名进 mihomo 后,GEOIP,CN 解析真实 IP 拦截。

关键 sysctl

参数原因
net.ipv4.conf.*.send_redirects0否则 .7 发 ICMP 重定向,客户端绕过 .7 直连 .1 形成"双路径":同目标客户端直连 + mihomo 代拨同时存在,经主路由同一公网 IP NAT 后触发服务器 PAWS 丢弃时间戳较小的那条 → i/o timeout 风暴(闲鱼等 App 卡死真凶)。⁠对所有单臂/发夹弯旁路由方案都适用⁠,不只是本机
net.ipv4.conf.*.rp_filter0允许非对称,配合发夹弯

出国线路

三台 VPS 分布在不同网络线路上,延迟和稳定性差异来自回国线路的 QoS 等级:

线路全称优先级特点适合
CN2 GIAChina Telecom Next Gen Carrier最高电信顶级线路,全程 CN2 骨干不经过 163 网,QoS 最低,晚高峰基本不掉速对延迟/稳定性有要求的主力节点
9929China Unicom Premium中高联通精品线路,类似 CN2 GIA 但走联通骨干,北方联通宽带用户最优联通用户直连最优
4837China Unicom Standard普通联通标准国际线路,晚高峰拥堵明显但价格便宜备线/冷备/预算敏感

节点与协议如何选

不在架构文档里固化供应商、套餐价格或某次测速结果:这些信息变化快,也无法代表不同地区、运营商和晚高峰时段的体验。更稳妥的选型方法是用自己的接入网络持续测量:

  1. 分别记录工作日白天和晚高峰的 RTT、抖动、丢包率与 TCP/UDP 吞吐。
  2. 主节点和备节点选择不同上游或不同路由,避免看似多节点、实际共享同一故障域。
  3. 同时测试 TCP 与 UDP 协议;协议表现取决于链路质量,不能从一次延迟测试推导长期结论。
  4. 切换策略应考虑业务体验。自动切换适合节点质量接近的场景;质量差异很大时,手动切换更容易发现降级。
  5. 把原始结果交给 Prometheus Blackbox Exporter 或同类探针保存,用一周以上的分位数而非瞬时最低值做决定。

这套网络选择手动 Selector:主节点异常时报警,由维护者确认后切换。代价是恢复不完全自动,收益是不会静默落到一个“能连通但体验很差”的节点。

提速项

  • tcp-concurrent: true:并发拨号多解析 IP 取最快。
  • QUIC reject 规则故意保留:AND,(DST-PORT,443),(NETWORK,UDP),(NOT,GEOSITE,cn),REJECT 强制外网 HTTP/3→h2,治"QUIC-over-Hy2 空闲后复用挂死",放开会复发。

IPv6 为什么不开硬旁路⁠:v4 硬旁路的关键是发夹弯 MASQUERADE(改源成 .7 保证回程对称),这个操作依赖 N100 有固定的内网 v4 地址。但 v6 地址是 SLAAC 动态分配的,没有稳定的内网地址做 SNAT 锚点——发夹弯的回程对称在 v6 上无法可靠实现,强行开只会随机断流。所以 v6 CN 当前只靠 mihomo 规则层 GEOIP,CN 兜底,不走防火墙 prerouting 硬旁路。 监控⁠:N100、核心工作站和主路由的关键组件接入 Prometheus + Grafana,见 monitoring.md。节点可用性由 Prometheus Blackbox Exporter 探测;这里保留人工确认后的切换策略。

七、N100 关键组件

组件地址/路径说明
mihomo 内核/usr/bin/mihomo,procd via /etc/init.d/nikki透明代理+TUN
mihomo API127.0.0.1:9090健康探测
mihomo mixed:7890(SOCKS5+HTTP)显式代理入口
mihomo redir:7891透明代理 redirect 入站
mihomo DNS:1053(fake-ip)AdGuard 上游
Nikki dashboardhttp://<side-router-ip>:9090/uiWeb 控制台,仅限内网访问
AdGuard HomeDocker host 网络,http://<side-router-ip>:8083DNS 广告过滤,上游指向 :1053
failopen daemon/usr/local/sbin/nikki-failopen.sh,procd健康检查+自动 fail-open
CN 旁路 SNAT/etc/nikki/scripts/bypass-masq.{nft,sh} + firewall include发夹弯 masquerade,持久化

N100 迁移动机与硬件选型:原先旁路由跑在桌面机 WiFi 上,WiFi 抖动全屋断网;换 N100(低功耗 x86,iStoreOS,单千兆口)挂书房 AP LAN 口做有线旁路由,从此与 WiFi 解耦。

八、nftables 结构

处理顺序⁠(prerouting → forward → postrouting):

nftables 处理顺序:prerouting → forward → postrouting 入站包 fw4 forward(policy drop) nikki dstnat / mangle_prerouting 透明代理入口 · 按目的地分流 大陆 IP / 私网 → return,不进代理(直连) 其余流量 → DNAT :7891 或标记 TUN bypass_masq postrouting 发夹弯 SNAT 锚点 CN 直连流量 → MASQUERADE(src→.7,回程对称) fw4 srcnat_lan(docker MASQUERADE) 出站 大陆 IP 在 prerouting 就 return,物理上不进 mihomo,与域名是否命中 geosite 无关。 bypass_masq 独立成表,nikki 重启/fail-open 不影响回程对称的 SNAT 锚点。

table inet fw4(OpenWrt 防火墙)

  • forward:policy drop;放行 TUN 流量 + LAN→WAN 转发
  • srcnat_lan:docker MASQUERADE

table inet nikki(透明代理规则)

  • china_ip 集合:~3.7k chnroute CIDR(由 bypass_china_mainland_ip=1 填充)
  • dstnat / mangle_prerouting_lan:大陆 IP / 私网 / 198.18 命中 → return 旁路;其余 DNAT TCP→:7891 或标记 TUN
  • mangle_output:本机出站 → TUN
  • fail-open 时整表删除

table inet bypass_masq(CN-IP 旁路的发夹弯 SNAT)

  • postrouting(nat hook,priority srcnat+5):iifname br-lan oifname br-lan ip daddr != {私网+198.18+组播} masquerade
  • 只命中被 china_ip 旁路、需转发回 .1 的公网 CN 直连流量,改源成 .7 保证回程对称
  • 独立于 table nikki,nikki 重启不影响⁠;持久化靠 firewall.bypass_masq include

table inet failopen(故障注入,恢复时删除)

  • srcnat:MASQUERADE <lan-cidr> → 非本地
  • dns:DNAT :53 → .1:53

九、自托管服务与故障域

以下服务当前依赖核心工作站的 Wi-Fi。wifi-watchdog(systemd timer)可以恢复短暂的射频或驱动异常,但它不能把无线链路变成高可用基础设施;长期运行的入口和监控服务应迁移到有线节点。

服务用途可用性
DERPTailscale 中继
rathole内网穿透(见 rathole-tunnel.md)
paste/mdserve笔记分享
Prometheus监控采集
sunshine游戏串流
本地 LLMAI 推理(见 local-llm.md)

十、守护进程

守护位置场景
nikki-failopenN100(procd)mihomo/AdGuard 进程异常
通电自启N100(BIOS)停电恢复
wifi-watchdog核心工作站(systemd timer)Wi-Fi 驱动/射频异常
sync-mihomo-to-router核心工作站(systemd timer)真源→旁路由配置漂移
sync-subscribe核心工作站(systemd timer)真源→移动端配置漂移

配置派生流水线

家里三处需要 mihomo 配置:核心工作站(TUN 自代理)、N100(全屋透明代理)和移动端导入文件。三份的节点列表、代理分组、分流规则必须一致⁠,但 DNS、TUN、入站方式各不相同。如果各自独立维护必然漂移。

方案⁠:只手动编辑 <config-root>/config.yaml,其中包含 proxiesproxy-groupsrules;两条 timer 驱动的脚本从它派生目标配置。

#1 本机⁠:直接使用真源。TUN device Meta + 本地 AdGuard + fake-ip + controller。

#2 N100 旁路由⁠(sync-mihomo-to-router.sh,timer 03:45):

  • 从真源只抽 proxies/proxy-groups/rules 三段 → /etc/nikki/profiles/home.yaml
  • 本机 mihomo -t 校验真源 → scp 到 N100 → nikki -t 校验 → 旧档备份(带时间戳)→ 校验失败自动回滚 → reload Nikki
  • DNS/TUN/sniffer 由 N100 本地 UCI mixin 注入,不进 profile——这些是目标端特有,不应从真源覆盖

#3 移动端配置⁠(sync-subscribe.sh):

  • 输出 clash.yaml(Clash 导入)+ sub.txt(v2rayN base64 分享链接)
  • 脱本机化消毒:剔除 external-controller+secret(泄漏即被控)、tun 整段(手机不需要)、nameserver:127.0.0.1(漫游设备到不了)、PROCESS-NAME 规则(手机永不匹配)
  • DNS 替换为 fake-ip + 公网 DoH,国外域名走出口解析防泄漏
  • 若通过公网分发,入口使用独立域名和不可预测的路径令牌;Web 服务器只暴露派生文件,不暴露真源、控制器密钥或目录列表

两条 timer 错开运行,避免同时读取或写入目标配置。修改真源后也可手动执行对应脚本;脚本必须保持幂等,并在替换前完成语法校验和备份。

十一、上线后的验证清单

先把旁路由地址放进环境变量,避免示例命令里出现真实地址:

SIDE_ROUTER_IP=192.168.31.7

正常模式至少验证以下项目:

# 客户端的默认路由是否指向旁路由
ip route show default

# DNS 是否只经过 AdGuard,并能得到预期的 fake-ip 响应
dig @"$SIDE_ROUTER_IP" example.com

# 在旁路由上确认转发、重定向与 SNAT 规则存在
ssh "root@$SIDE_ROUTER_IP" 'nft list ruleset'

# 两个进程及其监听端口是否存活
ssh "root@$SIDE_ROUTER_IP" 'pgrep -a mihomo; ss -lntup'

Fail-Open 应在维护窗口演练,而不是等故障发生后猜测。分别停止 mihomo 和 AdGuard Home,确认守护进程撤销透明代理规则、接管 DNS,客户端仍能直连;随后恢复服务,并确认规则没有重复注入。最后单独模拟 N100 断电,验证监控确实报警,同时接受当前架构下普通客户端会断网这一事实。

场景预期结果
mihomo 进程退出自动撤销重定向,降级为直连
AdGuard Home 进程退出:53 被接管到可用 DNS,客户端继续解析
N100 重启后恢复配置只注入一次,路由和 DNS 回到正常模式
N100 断电或网口掉线当前无网关热备,普通客户端断网并触发告警
核心工作站离线普通家庭设备不受影响;自托管服务离线

十二、已知风险

风险影响缓解
核心工作站 Wi-Fi 单点隧道与中继等自托管服务同时离线长期迁到有线节点;watchdog 只作为短期止血
N100 单网口发夹弯单臂拓扑回程不对称必断MASQUERADE + bypass_masq nft 表保障回程对称
mihomo/AdGuard 进程挂全屋断网(DHCP 网关仍指向 .7)nikki-failopen(procd)进程级自愈
N100 硬件、电源或链路故障默认网关不可达,普通客户端断网当前仅监控告警;后续引入双机网关或主路由侧自动切换
主路由硬件/固件故障全屋断网(PPPoE+NAT+DHCP 全挂)暂无热备;原计划 N100 做主路由未落地
光猫桥接ONT 只做光电转换,不拨号不路由不 NAT,公网 IP 直落主路由基本不是故障源,无双重 NAT

详细评估和恢复流程见 network-recovery.md

变更记录

日期变更
2026-06-21N100 旁路由上线,旧工作站旁路由退役;DHCP 网关/DNS 从 .8 切到 .7;部署 Fail-Open 与 Wi-Fi watchdog
2026-06-24公网订阅修复:原样照搬本机 config 导致泄漏本机 DNS+管理口 secret+tun,sync-subscribe.sh 加脱本机化消毒;旁路由 profile 重跑刷新;新增 sync-mihomo-to-router.timer
2026-06-27关 ICMP send_redirects:治闲鱼等 App 卡死(双路径 PAWS 丢包风暴根因);CN-IP 防火墙旁路上线(bypass_china_mainland_ip=1 + table inet bypass_masq);tcp-concurrent + CN DNS 改明文 UDP 223.5.5.5;节点洞察
2026-08-11公开版文档泛化主机、SSID、订阅入口与节点信息;补充设计原则和验证方法

相关文档