这是我家里实际跑通的一套方案,写于 2026-10-28。主路由不动、只加一台旁路由虚拟机,国内直连、国外走节点、全屋去广告,全部验证过才写出来。文中的内网地址是我家的网段(192.168.123.0/24),你照着改成自己家的就行;节点链接、密码一律不写,贴你自己的。
零、下载地址
- OpenWrt 系统镜像(ImmortalWrt 24.10.6,x86-64):下载目录,本文用的是其中不带 efi 的 qcow2 文件:immortalwrt-24.10.6-x86-64-generic-ext4-combined.qcow2.gz,sha256 是
bb5762fb9fe990374e44c933764992b21f8c0e1002e463accafcfa848c6a6455,下载完先校验再用。 - AdGuard Home:官方 Releases 页,本文用的是 v0.107.79,x86-64 的包是
AdGuardHome_linux_amd64.tar.gz。 - PassWall:不用单独下载,在 LuCI 的软件包里搜索
luci-app-passwall安装即可。 - 虚拟机软件:QNAP 的 Virtualization Station 在 AppCenter 里装,主路由 Padavan 不用刷机。
一、方案总览:为什么选旁路由
主路由继续当出口和 DHCP 服务器,不刷机、不动它的系统;旁路由只做两件事:分流代理和DNS 过滤。好处是主路由挂了、旁路由挂了,都能一键回滚,不会全家断网。
设备 ── DHCP(网关指向旁路由)──> 旁路由虚拟机 192.168.123.3
├── 国内流量 ──> 直连出去
├── 国外流量 ──> 走节点
└── DNS ──> AdGuard 过滤广告 ──> PassWall 的分流 DNS 解析
主路由 192.168.123.1:出口 + DHCP,本身不跑代理
最终形态:
| 项目 | 数值 / 选择 |
|---|---|
| 主路由 | Padavan R2100,固件 3.4.3.9,LAN 192.168.123.1 |
| 旁路由宿主机 | QNAP TS-464C2,Virtualization Station(QKVM) |
| 旁路由虚拟机 | 1 核 CPU / 1GB 内存 / 2GB 磁盘,VirtIO 网卡 |
| 旁路由系统 | ImmortalWrt 24.10.6,x86-64 generic ext4 combined,不带 efi 版 |
| 旁路由地址 | 192.168.123.3/24,网关 192.168.123.1 |
| 代理 | PassWall,Xray,模式“中国列表以外” |
| 去广告 | AdGuard Home,管理页面 192.168.123.3:3000,DNS 53 端口 |
| 分流方式 | 主路由 DHCP 下发网关和 DNS,设备全部自动(DHCP) |
二、先说放弃的一条路:Docker macvlan
一开始我试过 NAS Docker + macvlan 跑 OpenWrt,容器里的 br-lan 能拿到 192.168.123.2,容器内访问 LuCI 也正常,但局域网里的电脑和手机访问一律 ERR_CONNECTION_TIMED_OUT。
结论:LuCI 没死,是 macvlan over QNAP 虚拟交换机(qvs0)的入向转发有问题。容器内 ping 不通 NAS 本身是 macvlan 宿主隔离,属正常,不算故障。折腾到这一步就该换路线,别在 macvlan 上死磕。
三、虚拟机怎么建
在 QNAP 的 Virtualization Station 里建一台虚拟机,关键参数一个都不能错:
- 名称:
openwrt;系统模板随便选一个(只是标签,不是真系统)。 - CPU 1 核、内存 1GB;BIOS 选传统 BIOS,不要改 UEFI。
- 硬盘:新建映像 2GB,VirtIO + Writeback。
- 网卡:只建 1 张,VirtIO,桥接接 NAS 的那个虚拟交换机(我这里是 Virtual Switch 5,对应物理 Adapter 1;千万别选成 169.254 网段那个)。
- 自动启动:测试阶段先关,跑稳了再改成跟 NAS 一起启动。
四、镜像怎么换
官方镜像:ImmortalWrt 24.10.6,x86-64 generic-ext4-combined.qcow2(不带 efi 的那个),下载后务必校验 sha256:
bb5762fb9fe990374e44c933764992b21f8c0e1002e463accafcfa848c6a6455
我实测 NAS 直连下载两次都断点续传拼坏了,改成在另一台机器上下载、校验通过后再传到 NAS,稳得多。
替换步骤:
- 先把虚拟机建盘时生成的空盘备份一份(我这里是
openwrt_00.img.orig)。 - 关机状态下把解压后的 qcow2(约 332.5MB)覆盖掉磁盘文件,检查文件头是 QFI 开头再开机。
- 第一次进控制台是 ImmortalWrt 的 root 命令行,先
passwd设 root 密码(密码只在控制台设,别写进文章、别发到聊天里),再改 LAN。
五、OpenWrt 初始网络:旁路由单臂模式
在虚拟机控制台里改 LAN,核心就四行意思:
- 地址:静态 192.168.123.3/24
- 网关:192.168.123.1(主路由)
- DNS:先填 192.168.123.1(后面 AdGuard 装好再变)
- DHCP:关掉(
dhcp.lan.ignore='1'),DHCP 继续留在主路由上
重启网络后,局域网访问 http://192.168.123.3 就能进 LuCI。能进 LuCI 才算这一步过关。
六、PassWall:安装、节点、分流模式
在 LuCI 的软件包里装 luci-app-passwall(我装的时候是 25.12.16-r1,组件 Xray 25.2.21、Sing-Box、ChinaDNS-NG、Geoview)。节点在 LuCI 的节点列表里自己粘贴导入,链接不要贴到公开文章和聊天记录里。
装完先别急着测,三个坑我都踩过:
坑 1:主开关开了,进程没起来
LuCI 状态页可能一直显示“未运行”,节点日志弹窗只写“未启用日志”。先别信状态页,去虚拟机里看进程列表:
ps w | grep -E "xray|chinadns"
如果 xray、chinadns-ng、passwall 的 dnsmasq、monitor.sh 都没在跑,手动重启一次:
/etc/init.d/passwall restart
再看进程,起来了就是起来了,状态页卡顿不用管。
坑 2:模式默认是“不代理”
PassWall 的 TCP/UDP 代理模式出厂默认是“不代理”,这时候国内能开、国外全打不开,特别容易误判成节点坏了。去模式设置里切到**“中国列表以外”**并保存应用,两项都变成 proxy 才算对。
坑 3:谷歌、YouTube 打不开,别的国外网站能开
这是 DNS 污染,不是节点问题。我实测过:节点 Socks 直接测谷歌、YouTube 都是 200,但手机 DNS 用主路由 192.168.123.1 时照样打不开。改成手机 DNS 192.168.123.3(走 PassWall 的 chinadns)立刻全通。后面全网 DHCP 也按这个思路改,见第八节。
七、节点自动切换:别用 haproxy,用 Xray 自带的均衡器
我有 3 个节点,之前只用其中一个,另外两个闲着。自动切换的做法是新建一个均衡器节点,不用 PassWall 里那个 haproxy 负载均衡(它的日志里出现过崩溃循环,绕开更稳):
- 新建节点,协议选
_balancing,名字就叫“自动切换”。 - 均衡器节点列表里勾上全部 3 个节点。
- 策略选
leastPing(每次走延迟最低的那个),探测间隔1m。 - 把全局 TCP 节点切到这个均衡器节点,UDP 选“与 TCP 节点相同”。
- 重启 PassWall,用它的 Socks(127.0.0.1:1070)测谷歌、YouTube,都是 200 才算过关。
效果:主节点挂了或者延迟炸了,Xray 会自动把它排除、切到下一个健康的节点,不用手动换。回滚也简单:TCP 节点切回原来的单节点就行,改之前的配置我备了一份在虚拟机 /tmp 里。
八、全网自动分流:只改主路由的 DHCP 一页
这是整套方案里最省事的一步,DHCP 不搬到旁路由,只改主路由 Padavan 的 DHCP 服务器页:
- 地址池:192.168.123.4–244(从 .4 开始,因为 .3 给了旁路由,从 .2 开始会把 .3 分出去撞 IP)
- 默认网关:192.168.123.3
- DNS 服务器 1:192.168.123.3
- 租约:86400 不变
手动设过 IP 的设备全部改回自动(DHCP),重连 WiFi 就自动拿到网关 .3 + DNS .3,新设备连上即生效。最终形态就是第一节那张表:国内直连、国外走节点。
回滚(只改这一页): 清空默认网关、DNS 改回 192.168.123.1、池子改回 .2 起始,设备重连就回到主路由直连。
九、备份:配置和磁盘分开备
两份备份,缺一不可,而且都只存 NAS 上:
- 配置备份:在虚拟机里用
sysupgrade -b打包,含 network、dhcp、passwall、dropbear 密钥。我打出来的包 12KB,放在 NAS 的备份目录里。这个包里有节点和密钥信息,别往外发、别存到别处。 - 磁盘备份:在 QKVM 里给虚拟机建快照,就等同于磁盘备份。注意快照和配置包都在 NAS 同一块盘上,只防虚拟机/配置损坏,不防 NAS 硬盘损坏。
十、磁盘扩容:分区扩了,文件系统不一定跟着扩
虚拟机建的时候盘是 2GB,但镜像本身的 rootfs 只有约 332MB,跑一阵子 PassWall、规则、AdGuard 装下来,可用空间就从 125MB 往下掉。扩容分三步,第三步最容易翻车:
- 关机,再动磁盘文件(不断网关就别动盘)。
- 用 QKVM 自带的 qemu-img 把盘撑到 2GB。这里有个细节:建了快照之后,虚拟机实际在用的盘已经不是原来那个文件了,而是快照文件(我这里是带时间戳后缀的那个),原盘变成了它的底包。扩容要扩当前在用的那个文件,扩原盘没用,还可能报权限不足。
- 开机进 OpenWrt,用 fdisk 把 rootfs 分区(我这里是 vda2)扩到 2GB。起始扇区必须和原来一模一样(我这里是 66560),错了就丢数据。扩完分区要重启一次让内核认新分区表,再扩文件系统。
我实测的结果要实话实说:qcow2 和分区都到了 2GB,但这个 ImmortalWrt 镜像不支持在线扩文件系统,resize2fs 直接报参数无效。重启后文件系统从 290MB 变成了 374MB,可用空间从 125MB 涨到 209MB,紧张局面缓解了,但离 2GB 还差一截。真要撑满 2GB,得关机后用外部工具离线扩,有快照兜底但风险比收益大,我先用着 209MB,等真紧张了再做。
十一、规则自动更新:每周日凌晨 4 点
PassWall 的规则(中国 IP 段、中国域名、GFW 列表、geoip/geosite)会慢慢过期,手动更新容易忘,设成定时:
- 自动更新开,每周日凌晨 4 点跑一次。
- geoip、geosite、国内 IP 段、中国域名、GFW 列表全开(我装机时 geoip/geosite 默认是关的,要手动打开)。
我第一次手动跑的结果:GFW 列表 4440 条、国内 IPv4 段 9131 条、IPv6 段 4967 条、中国域名 109673 条,geoip.dat 15.8MB、geosite.dat 10.8MB。顺带发现之前的规则文件还是镜像自带的 5 月份版本,一直没更新过,这次才算真正换新。
十二、AdGuard Home 全屋去广告:DNS 链才是关键
去广告的原理一句话:DNS 层面拦广告域名。浏览器问“广告服务器在哪”,DNS 直接不给答案,广告根本下不来,所以全屋设备(手机 App、电视都算)都受益;浏览器插件只能管浏览器,App 里的广告管不着。
装法
软件源里没有 AdGuard 的 LuCI 插件,我是直接装的官方程序 v0.107.79,装在虚拟机 /opt/AdGuardHome/ 里,管理页面 192.168.123.3:3000,DNS 占 53 端口。它不是 LuCI 插件,所以 LuCI 里看不到它,别去 LuCI 里找。
向导里的两个端口冲突
向导第一步就会报两个红字,都是正常的:
- 网页管理界面 80 端口被占:那是 LuCI 的端口,把 AdGuard 的管理页面端口改成 3000,以后 AdGuard 后台就是 :3000,LuCI 还是 :80,各走各的。
- DNS 53 端口被占:那是 OpenWrt 系统自带的 dnsmasq,先把它停掉,53 腾出来再继续向导。
向导里上游 DNS 那一步,只留 127.0.0.1:15353,那是 PassWall 的分流 DNS 端口。留了默认的 Quad9 之类,分流就乱了,国内域名也可能绕远路。
最关键的一步:关掉 PassWall 的 DNS 劫持
这一步不做,AdGuard 等于白装。PassWall 默认会把所有 53 端口的查询用防火墙规则重定向到它自己的 dnsmasq(11400 端口),直接绕开 AdGuard,仪表盘查询数永远是 0、广告域名照常解析。我当时的现象就是这样。
做法:把 PassWall 的 DNS 重定向(dns_redirect、dnsmasq_dns_redirect)关掉,重启 PassWall,链路就变成:
设备 ──> AdGuard :53(过滤广告)──> chinadns :15353(分流解析)
代价也要说清楚:关了劫持之后,硬编码 DNS 的 App(不走 DHCP 下发的 DNS、自己写死 8.8.8.8 那种)就不再被强制拉回分流了,但正常用 DHCP 的设备都不受影响。
验收标准
- 广告域名
pagead2.googlesyndication.com解析返回::,就是被拦住了。 - 谷歌、YouTube 照常解析、照常打开。
- AdGuard 开机自启开,系统 dnsmasq 的自启关,否则重启后 53 端口又被抢回去。
回滚:停 AdGuard、启动系统 dnsmasq、把 PassWall 的 DNS 重定向开回去、重启 PassWall,一分钟就能回原样。
十三、一个 iPhone 的坑:别在家里的 WiFi 上开“限制 IP 地址跟踪”
装完 AdGuard 那晚,我一度觉得抖音变慢了,查下来 DNS 解析、虚拟机负载都没问题,最后发现是 iPhone 家里 WiFi 上开了“限制 IP 地址跟踪”。这个设置一开,手机上网会先经过苹果的中转服务器藏真实 IP,抖音这种很吃 IP 定位的 App 就会被分到远的 CDN 节点,或者干脆加载不出来。
家里 WiFi 是自己的网络,没必要开这个。设置 → 无线局域网 → 家里 WiFi 后面的 ⓘ → 把“限制 IP 地址跟踪”关掉,抖音立刻恢复。这个设置是按每个 WiFi 单独记的,关了家里的,不影响外面连公共 WiFi 时还开着。
十四、最后的检查清单
跑完上面全部,拿着这张表过一遍再收工:
- 电脑、手机、电视都能上网,国内网站直连速度正常
- 谷歌、YouTube 能打开
- AdGuard 仪表盘查询数和拦截数在涨,广告域名返回
:: - 主节点挂了能自动切到备用节点(可以接受短暂波动,别拿生产环境赌)
- 配置备份 + 虚拟机快照都在 NAS 上
- 回滚步骤自己能复述一遍:主路由 DHCP 一页就能回直连
有问题先看进程列表和 AdGuard 查询日志,别只信 LuCI 和仪表盘的状态页,它们都可能滞后。
十五、后续:2026-11-05 国内网又卡,问题不在 IPv6
现象:11 月 4 日晚到 11 月 5 日,手机和电脑都慢,切流量就正常。微信文章里的图片一直转圈,点开放大能看;抖音精选页文字、点赞都出来了,视频缩略图全是空白,点进视频却能播;电脑浏览器打开微信文章,十几个 JS 全是 ERR_CONNECTION_CLOSED,每个都拖 19 秒才断,文章本身 16–31 秒才下完。
问题在哪:单臂旁路由不对称路由。出去经旁路由,回包主路由直发设备,不经过旁路由,主路由要对同一条连接处理两次,大流量 TCP 只剩约 80KB/s。旁路由上 masq 是开着的,但 WAN 区一个接口都没有,srcnat 链是空的,根本没生效。
怎么修复:旁路由加一条 SNAT,让经它转发的流量源地址改成旁路由自己(192.168.123.3),回包原路回来:
nft add rule inet fw4 srcnat ip saddr 192.168.123.0/24 ip daddr != 192.168.123.0/24 masquerade
规则写进 /etc/firewall.snat-fix,用 firewall include 固化(reload=1),防火墙重启后还在。改完微信文章、抖音、手机微信图片都恢复了,AdGuard 过滤重新打开也没问题。