旁路由这样搭才稳:QNAP 虚拟机 + OpenWrt + PassWall + AdGuard 全记录


这是我家里实际跑通的一套方案,写于 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,稳得多。

替换步骤:

  1. 先把虚拟机建盘时生成的空盘备份一份(我这里是 openwrt_00.img.orig)。
  2. 关机状态下把解压后的 qcow2(约 332.5MB)覆盖掉磁盘文件,检查文件头是 QFI 开头再开机。
  3. 第一次进控制台是 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 上:

  1. 配置备份:在虚拟机里用 sysupgrade -b 打包,含 network、dhcp、passwall、dropbear 密钥。我打出来的包 12KB,放在 NAS 的备份目录里。这个包里有节点和密钥信息,别往外发、别存到别处。
  2. 磁盘备份:在 QKVM 里给虚拟机建快照,就等同于磁盘备份。注意快照和配置包都在 NAS 同一块盘上,只防虚拟机/配置损坏,不防 NAS 硬盘损坏。

十、磁盘扩容:分区扩了,文件系统不一定跟着扩

虚拟机建的时候盘是 2GB,但镜像本身的 rootfs 只有约 332MB,跑一阵子 PassWall、规则、AdGuard 装下来,可用空间就从 125MB 往下掉。扩容分三步,第三步最容易翻车:

  1. 关机,再动磁盘文件(不断网关就别动盘)。
  2. 用 QKVM 自带的 qemu-img 把盘撑到 2GB。这里有个细节:建了快照之后,虚拟机实际在用的盘已经不是原来那个文件了,而是快照文件(我这里是带时间戳后缀的那个),原盘变成了它的底包。扩容要扩当前在用的那个文件,扩原盘没用,还可能报权限不足。
  3. 开机进 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 过滤重新打开也没问题。


文章作者: 小小胡
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小小胡 !
  目录