Homelab 网络系列:开篇 - 家庭网络为什么会变复杂

系列导航

  1. Homelab 网络系列:开篇 - 家庭网络为什么会变复杂
  2. Homelab 网络系列:RouterOS 主网关和 WRT 旁路由为什么要分工
  3. Homelab 网络系列:透明代理 VIP、VRRP 和 Fallback DNS
  4. Homelab 网络系列:NetBird ACL:Mobile Devices / MacBook 如何访问 Homelab / Hometown / Office 网络
  5. Homelab 网络系列:Backup Path:ZeroTier P2P 和 Sing-box Inbound 为什么还留着
  6. Homelab 网络系列:自动化和可恢复性:订阅生成、健康检查、配置同步、回滚

背景

很长一段时间里,我对“家庭网络”的理解都非常朴素:

  • 光猫拨号
  • 主路由 NAT
  • 交换机接内网设备
  • 需要出门访问的时候,开一个 VPN

如果只是手机、电脑、电视、NAS,这个模型其实很好用。问题在于 Homelab 这个东西一旦开始长出来,它就不再只是“家里的网络”。

我现在遇到的问题大概有这么几类:

  • 家里有需要长期运行的服务,有些只给自己用,有些需要从外面访问
  • Mobile Devices / MacBook 需要在外面访问 Homelab,也需要访问 Hometown / Office-JT / Office-SQ / DC-101
  • 有些设备希望透明代理,有些设备只需要普通直连,有些设备还需要跨站路由
  • 入口访问、DNS、证书、鉴权、转发路径不能互相打架
  • 网络挂了之后,人不一定在现场,所以 Fallback 和回滚路径必须提前设计

所以最后就变成了一个看起来有点夸张的组合:

  • RouterOS CHR 做主网关和边界 NAT
  • ImmortalWrt 做旁路能力承载,比如 Sing-box、NetBird、部分透明代理路径
  • PVE 承载 RouterOS / WRT / DNS / 入口服务等基础组件
  • NetBird 作为日常 Admin Overlay,让 Mobile Devices / MacBook 能访问 Homelab / Hometown / Office 侧网络
  • ZeroTier 和 Sing-box Inbound 作为 Backup Path,而不是主路径

这不是一个“推荐大家都这样搞”的方案,更像是一套不断被现实问题推出来的网络形态。

旧方案

最早的方案其实更像是“能跑就行”:直接让 OpenWrt / ImmortalWrt 承载所有服务。

它既是路由器,也是 DNS、透明代理、Overlay Peer、入口跳板,甚至还会顺手放一些脚本和小服务。这个阶段的优点很明显:

  • 设备少
  • 路径短
  • 配置集中
  • 出问题的时候基本只需要登录一台机器看

但用久之后,问题也很明显。路由器本来应该是一个稳定的网络底座,一旦上面叠了太多服务,任何一个服务重启、配置失误、依赖升级,都可能把基础网络一起带下去。

后来最容易想到的改法,是把所有东西都塞进主路由:

  • 主路由拨号、NAT、DHCP、DNS
  • 主路由上跑透明代理
  • 主路由上开 VPN
  • 主路由上做公网入口转发

如果网络规模小,这样确实省事。所有流量都经过一个设备,排查路径也短。

但我这里的问题是,主路由同时承担了“家里所有人正常上网”的职责。把实验性能力、代理策略、Overlay 节点、入口转发全部塞进去,风险会变得很集中。

典型的问题有几个:

  • 代理组件挂了,不应该影响普通设备上网
  • DNS 策略变更,不应该把公网服务入口解析搞乱
  • Overlay 路由调试,不应该动到家庭网络的默认出口
  • 入口服务调整,不应该依赖内网 DNS Rewrite 来绕过公网路径
  • 人在外面时,管理路径不能只剩一条

也就是说,主路由应该稳定,旁路能力应该可替换、可降级、可重启。

新方案

现在 Homelab 的核心思路是把职责拆开:

组件 职责
RouterOS CHR 主网关、DHCP、NAT、WAN/LAN 边界、公网入口 Hairpin
ImmortalWrt Sing-box、NetBird、透明代理 VIP、部分跨站路由
PVE 承载网络 VM/LXC 和基础服务
PVE Host Docker 上的 AdGuardHome 普通客户端 Upstream DNS、Fallback DNS、本地别名和 LAN Cache,不作为公网服务入口 Rewrite 中心
Traefik / Authelia HTTP(S) 服务入口和鉴权

为了后面几篇文章不一直抽象描述,核心 LAN 地址先放在这里:

地址 角色
10.1.1.1 RouterOS 主网关,普通客户端默认网关
10.1.1.100 PVE Host Docker 上的 AdGuardHome,普通客户端 Upstream DNS、Fallback DNS、本地别名和 LAN Cache
10.1.1.253 代理 VIP,需要透明代理的客户端把它当默认网关和 DNS
10.1.1.254 WRT 后端地址,健康时持有代理 VIP;代理路径的网关 Backend 和 Sing-box DNS Backend 都落在这里
flowchart LR
  normal["普通客户端
GW 10.1.1.1
DNS 10.1.1.100"] proxy["代理客户端
GW/DNS 10.1.1.253"] wan["WAN"] subgraph pve["PVE Host 10.1.1.100"] ros["RouterOS CHR VM
10.1.1.1
Main Gateway"] wrt["WRT LXC
10.1.1.254
Sing-box / NetBird"] adg["AdGuardHome Docker
10.1.1.100:53
LAN DNS Cache"] vip["Proxy VIP
10.1.1.253
VRRP"] end normal -->|GW| ros normal -->|DNS| adg proxy --> vip vip -->|Healthy Backend| wrt vip -.->|Fallback Backend| ros wrt -->|dns-local| adg ros -->|Ordinary DNS Upstream| adg ros --> wan wrt --> wan
flowchart LR
  normal["普通客户端
GW 10.1.1.1
DNS 10.1.1.100"] proxy["代理客户端
GW/DNS 10.1.1.253"] wan["WAN"] subgraph pve["PVE Host 10.1.1.100"] ros["RouterOS CHR VM
10.1.1.1
Main Gateway"] wrt["WRT LXC
10.1.1.254
Sing-box / NetBird"] adg["AdGuardHome Docker
10.1.1.100:53
LAN DNS Cache"] vip["Proxy VIP
10.1.1.253
VRRP"] end normal -->|GW| ros normal -->|DNS| adg proxy --> vip vip -->|Healthy Backend| wrt vip -.->|Fallback Backend| ros wrt -->|dns-local| adg ros -->|Ordinary DNS Upstream| adg ros --> wan wrt --> wan
flowchart LR
  normal["普通客户端
GW 10.1.1.1
DNS 10.1.1.100"] proxy["代理客户端
GW/DNS 10.1.1.253"] wan["WAN"] subgraph pve["PVE Host 10.1.1.100"] ros["RouterOS CHR VM
10.1.1.1
Main Gateway"] wrt["WRT LXC
10.1.1.254
Sing-box / NetBird"] adg["AdGuardHome Docker
10.1.1.100:53
LAN DNS Cache"] vip["Proxy VIP
10.1.1.253
VRRP"] end normal -->|GW| ros normal -->|DNS| adg proxy --> vip vip -->|Healthy Backend| wrt vip -.->|Fallback Backend| ros wrt -->|dns-local| adg ros -->|Ordinary DNS Upstream| adg ros --> wan wrt --> wan

这里最重要的取舍,是让 RouterOS 保持“边界设备”的角色,让 WRT 承担“弹性能力”的角色。

普通设备仍然走 RouterOS。需要透明代理的设备,通过 DHCP Option-set 拿到一个代理 VIP 作为默认网关和 DNS。这个 VIP 正常情况下由 WRT 持有,WRT 后面是 Sing-box 的 DNS / TUN / Route Policy;如果 WRT 的基础健康检查失败,VIP 会切回 RouterOS,至少还能保留普通 LAN/WAN Fallback。

这样做不是为了优雅,而是为了出问题时损失更可控:

  • WRT 挂了,普通设备不受影响
  • Sing-box 挂了,代理设备可以 Fallback 到 RouterOS
  • Fallback DNS 可以回到普通客户端也在使用的 AdGuardHome,保持解析和 LAN Cache 一致,但不把它当成公网服务入口的 Split DNS 中心
  • 公网服务入口从 LAN 访问时,仍然保持公网 DNS 视角,通过 RouterOS Hairpin NAT 回来

这也是我后来越来越不喜欢“内网 DNS 劫持公网域名”的原因。DNS 只能按名字做决策,但很多入口服务真正的差异在端口、协议、认证和后端服务上。把这些东西都塞给 DNS,维护到后面很容易变成另一种债。

NetBird 的位置

NetBird 在这套网络里不是“另一个给客户端翻出去的代理”,而是 Admin Overlay。

它解决的主要问题是:

  • Mobile Devices / MacBook 在外面可以访问 Homelab 的管理入口
  • Mobile Devices / MacBook 在外面可以访问 Homelab / Hometown / Office-JT / Office-SQ / DC-101
  • WRT 节点之间可以作为 Subnet Router,把受控的站点网络暴露给允许的 Portable Devices (Admin)
  • ACL 可以明确限制哪些 Admin 设备能访问哪些 Peer 和哪些站点路由

这里 Tailscale 只是一个顺手对比过的对象,不是这个系列的重点。真正有价值的是 NetBird 的 ACL、Peer Registry、Route Awareness 怎么和现有 RouterOS / WRT 网络配合。

Backup Path

虽然 NetBird 是当前主要的 Admin Overlay,但我没有把 ZeroTier 和 Sing-box Inbound 删掉。

原因很简单:异地网络问题最麻烦的地方,不是平时能不能通,而是出事时你能不能还有第二条路径进去。

现在的定位大概是:

  • NetBird:日常 Admin Overlay
  • ZeroTier:保留 P2P 能力,不再作为主要 Network Route
  • Sing-box Inbound:Homelab / Office-JT 的备用入口手段,由 WRT 承载

这几条路径不是为了“同时在线很酷”,而是为了避免远程故障时只剩一个入口。尤其是跨城市、现场距离比较远的时候,Backup Path 的价值会比平时看起来高很多。

最后的结论

家庭网络变复杂,通常不是因为一开始就想复杂,而是因为需求一点点越过了普通家用路由器的边界。

我的取舍是:

  • 主网关尽量稳定
  • 实验性和策略性能力放到旁路
  • 管理 Overlay 和用户流量分开
  • DNS 不承担它不擅长的入口分流职责
  • Backup Path 不追求优雅,只追求出事时还能进去

这套方案肯定不是最简单的,但它的目标也不是简单,而是把复杂性放在相对可控的位置。

后续准备怎么写

这个系列我大概会按决策拆,而不是按软件拆。后续章节放在开头的系列导航里,已经写完的文章会直接链接,没写到的先保留成题目。

每篇都尽量只讲一个问题。因为这套东西如果一次性全写出来,会变成一大坨拓扑名词和配置片段,读起来也没意义。