家庭网络分层拓扑:从远端笔记本到双出口的完整链路

目录 / Step 导航

上一篇《OpenWrt 双出口分流》讲的是旁路网关内部怎么做第二出口。这一篇把镜头拉远,讲整张网络的分层拓扑:一台远端的公司笔记本,是怎么穿过 NAS 的 VPN、被两段策略路由接力、最终从境外出口上网的;以及家里每一类设备各自走哪条路、为什么。

文中所有公网 IP、商业服务商品牌、个人域名与主机名均已抹去,只保留可复用的结构。


一、全景图

先上完整的数据流图,后面逐层拆解:

                                  ┌──────────────────────────────────────────────┐
 公司笔记本(远端,任意网络)        │                家庭内网 192.168.0.0/24         │
      │                           │                                              │
      │ VPN 隧道(加密)           │   ┌─────────── NAS (.4) ────────────┐        │
      └───────────────────────────┼──►│ VPN Server → tun0 172.x.y.0/24  │        │
                                  │   │                                 │        │
                                  │   │ ip rule: from 172.x.y.0/24      │        │
                                  │   │          lookup 100             │        │
                                  │   │ table 100: default via .254 ────┼──┐     │
                                  │   │                                 │  │     │
                                  │   │ NAS 自身流量: default via .1 ───┼──┼──►  │──► 国内家宽(直连)
                                  │   └─────────────────────────────────┘  │     │
                                  │                                        ▼     │
 家里普通设备(手机/电视/PC)───────┼──────────────────────────────► 旁路网关 (.254)│
                                  │                             OpenWrt 虚拟机   │
                                  │                                     │        │
                                  │              TPROXY 全局透明代理      │        │
                                  │        fwmark 0x1 → lookup 100 → 代理内核    │
                                  │                    │                         │
                                  │        ┌───────────┴───────────┐             │
                                  │        ▼                       ▼             │
                                  │   默认(未命中规则)        命中媒体域名        │
                                  │        │                       │             │
                                  └────────┼───────────────────────┼─────────────┘
                                           ▼                       ▼
                                      主出口(境外A)        第二出口(境外B,
                                      金融/工作/默认         WireGuard 节点池
                                                            + 自动故障切换)

三个层次一句话概括:

  1. 接入层(NAS):把远端设备"拉进"家庭内网,并用策略路由决定它的流量交给谁。
  2. 代理层(旁路网关):把到达的流量透明地劫进代理内核,按域名分流到两个境外出口。
  3. 出口层:主出口(生命线)+ 第二出口(媒体流量、多节点冗余)。

二、四类终端,四种出口画像

同一张家庭网络,不同设备的流量走完全不同的路——这是整个设计的出发点:

终端路径最终出口为什么
公司笔记本(远端)VPN → NAS → 策略路由 → 旁路网关 → 代理境外(主出口/分流)人在外面,也要和在家一样的网络环境
家里普通设备默认网关指向旁路网关 → 代理境外(主出口/分流)全家默认出海,域名分流自动生效
NAS 本机默认路由直指上游网关国内直连NAS 跑的是下载/备份/内网服务,走国内又快又稳,也不占代理带宽
开发用笔记本自己的独立 VPN 隧道境外(独立于本拓扑)故障隔离:排查家庭网络时,这台机器不受影响,反之亦然

注意最后一行的价值:留一台不依赖这套拓扑的机器。旁路网关重启、代理挂掉时,你需要一台还能上网、还能 SSH 进各设备排障的"生命线终端"。


三、第一棒:NAS 上的接入与策略路由

远端的公司笔记本通过 VPN 拨进 NAS(很多 NAS 系统自带 VPN Server 套件),拿到一个 VPN 子网的地址(本文记作 172.x.y.0/24,NAS 侧接口是 tun0)。

默认情况下,VPN 客户端的流量会跟着 NAS 自己的默认路由走——也就是国内直连。但我们想让它走代理。在 NAS 上加两条东西即可

# 1. 独立路由表:VPN 客户端的"默认路由"指向旁路网关(而不是上游网关)
ip route add default via 192.168.0.254 dev <内网接口> table 100
ip route add 172.x.y.0/24 dev tun0 table 100   # 回程路由也要在这张表里

# 2. 策略路由:只有源地址来自 VPN 子网的流量才查这张表
ip rule add from 172.x.y.0/24 lookup 100

生效后的 ip rule 长这样:

0:      from all lookup local
1:      from 172.x.y.0/24 lookup 100     ← 只有 VPN 客户端命中
32766:  from all lookup main             ← NAS 自身流量照旧
32767:  from all lookup default

这一段的精髓是按源地址切割路由决策

别忘了打开转发和 NAT/放行(各系统写法不同,思路一致):VPN 子网 → 内网接口允许 FORWARD;如果旁路网关上没有回程路由,就在 NAS 上对这段做 SNAT,让回包能找回来。


四、第二棒:旁路网关上的透明代理

流量到达旁路网关后,进入上一篇讲过的代理平面,这里只画重点。

旁路网关是台 OpenWrt 虚拟机,单臂部署(只有一个桥接口,既收内网流量,也从同一条线出去)。它不做路由层分流,而是全局透明代理:

到达的转发流量 / 本机流量
      │  防火墙 mangle 链打上 fwmark 0x1
      ▼
ip rule: from all fwmark 0x1 lookup 100
      ▼
table 100: local default dev lo        ← 流量被"扣留"在本机
      ▼
TPROXY 重定向 → 代理内核监听端口
      ▼
按域名分流:
  ├─ 默认(金融/工作/一切未命中)──► 主出口(境外A)
  └─ geosite:youtube 等媒体域名 ───► 第二出口(境外B,WireGuard 节点池)

配套机制(详见上一篇):


五、两段 ip rule 的接力:各管一段,互不知情

这套拓扑里最容易混淆的,是 NAS 和旁路网关上各有一条 lookup 100 的 ip rule,但它们是完全不同的两回事:

NAS 上的规则旁路网关上的规则
规则from 172.x.y.0/24 lookup 100from all fwmark 0x1 lookup 100
匹配依据源地址(谁发的)防火墙标记(被 mangle 链盖过章的)
table 100 内容default via 旁路网关local default dev lo
作用把 VPN 客户端流量送到网关把打了标的流量扣进代理
谁维护手工/开机脚本代理服务自动增删

表号都叫 100 纯属巧合(两台机器各有各的路由表空间),但正好提醒我们:策略路由是逐跳生效的。NAS 只负责"下一跳给谁",它不知道也不需要知道网关后面是代理;网关只管"到达我的流量按域名分流",它不在乎流量是家里设备发的还是 VPN 穿进来的。两段规则通过"把包送到对方门口"完成接力,没有任何共享状态。

这种分层解耦的直接好处:加一台新的接入设备(比如再来一路 VPN),只动 NAS 的规则;换一个出口节点,只动网关的代理配置——互不牵连。


六、故障域分析:每一层挂了会怎样

设计时把"谁挂了影响谁"想清楚,出问题时就不会慌:

故障影响范围表现与恢复
旁路网关重启家里设备 + 公司笔记本断网代理内核拉起需要几十秒,期间"打不开",自愈,不用管
第二出口节点挂只有媒体域名自动故障切换约 6 分钟内换下一个节点;期间媒体域名连接失败,其余一切正常
主出口挂默认流量(金融/工作)不会自动切到第二出口——宁可暂时不通,也不换国家 IP 去登录银行
NAS 挂只有公司笔记本家里设备不经过 NAS,完全无感;笔记本重连 VPN 即可
上游家宽挂全部物理层问题,谁也救不了
代理挂但网关活着家里设备 + 笔记本kill switch 兜底:断网而不是裸奔直连

两个值得强调的设计决策:

  1. 主出口挂 ≠ 切第二出口。金融和工作服务的 IP 归属地突变,轻则风控验证,重则封号。所以默认流量没有任何 fallback 规则——这是故意的。
  2. 重启网关前心里有数。接入层(NAS 的 ip rule)是静态的,重启网关不影响它;恢复顺序永远是"网关代理拉起 → 全链路自愈",不需要人工干预任何一层。

七、一个运维细节:会悄悄残留的重复 ip rule

旁路网关重启后,偶尔会看到 fwmark 规则出现两条一模一样的副本

32764:  from all fwmark 0x1 lookup 100
32765:  from all fwmark 0x1 lookup 100

翻代理服务的脚本能找到原因——它的启动/停止逻辑是不对称的

# start 时:
ip rule add fwmark 1 lookup 100      # 加一条
# stop 时:
ip rule del fwmark 1 lookup 100      # 只删一条(del 一次只删一个实例)

开机过程中 start 逻辑被触发了两次(没有经过 stop),就叠成两条。之后每次 restart 都是"删一条、加一条",净数不变——这个重复副本不会自愈,会永久残留

处理原则:


八、小结

回看整张图,这套拓扑的骨架就三句话:

  1. 接入归接入,代理归代理。NAS 用"源地址策略路由"决定谁的流量交给网关,网关用"fwmark + TPROXY"决定流量怎么出海——两段 ip rule 各管一段,通过下一跳接力,零共享状态。
  2. 出口画像按设备定制。远端笔记本全量出海、家里设备默认出海、NAS 直连国内、开发机独立隧道互为备份——同一张网,四种画像。
  3. 故障域预先划清。每一层挂掉影响谁、会不会自愈、要不要 fallback,都是设计时定好的——尤其是"主出口挂了绝不自动换国家"这条底线。

分层的代价是多一跳、多一处配置;换来的是每一层都可以独立变更、独立排障、独立演进。对一张要长期运行的家庭网络来说,这笔账很划算。