从零开始配置旁路由,again
2026 年 07 月 24 日
大半个月前,在家里的 NAS 上跑 QWRT 做旁路由,基本上还可以,总算是减轻了主路由的压力。
没想到,昨天一次意外停电之后,QWRT 彻底起不来了,各种卸载重装都无解。
暂时把 DHCP 配置屏蔽掉,让设备走主路由后。我想了一下,还是得换个系统再跑一个旁路由。跟各路 AI 聊了一下之后,决定换成 immortalwrt。
背景知识
旁路由的本质,就是让这 “第二台路由” 在局域网中作为主路由后面的 “可选的网关”。这样就可以指定部分机器走旁路由,剩下的走主路由,互不干扰。
架构参考下图,在后续用例里统一使用以下 IP:主路由=192.168.1.1,NAS=192.168.1.2,旁路由=192.168.1.3,NAS访问旁路由的虚拟网卡=192.168.1.4。
graph TD
%% 定义设备
Internet["广域网 (Internet)"]
MainRouter["主路由 (光猫/主路由)<br>IP: 192.168.1.1<br>DHCP服务开启"]
SubRouter["旁路由 (immortalwrt)<br>IP: 192.168.1.3<br>网关/DNS:192.168.1.1<br>DHCP服务关闭"]
Client1["局域网终端 (PC/手机等)<br>IP: 192.168.1.x<br>网关/DNS: 192.168.1.1"]
Client2["局域网终端 (PC/手机等)<br>IP: 192.168.1.x<br>网关/DNS: 192.168.1.3"]
%% 连接关系
Internet <--> |光纤/拨号| MainRouter
MainRouter <==>|LAN口-LAN口| SubRouter
MainRouter <-.->|局域网| Client1
SubRouter <-.->|局域网| Client2
%% 样式调整
style Internet fill:#f9f,stroke:#333,stroke-width:2px
style MainRouter fill:#bbf,stroke:#333,stroke-width:2px
style SubRouter fill:#bfb,stroke:#333,stroke-width:2px
style Client1 fill:#ff9,stroke:#333,stroke-width:2px
style Client2 fill:#ff9,stroke:#333,stroke-width:2px
immortalwrt 本身就不介绍了,只提一件事,某 AI 评价稳定性的时候,说的是 immortalwrt > iStoreOS >> QWRT,当然,可信度未知。
对于这类系统,在 docker 里跑有个问题,就是系统运行时影响到的变化点太多了,因此没办法把可变的部分放到 volume 中来持久化。
但系统运行的时候,要装软件,要改配置,这些改动还是要固化下来,否则一不小心 docker compose down 了就丢了。所以就要记住,经常用 docker commit 命令,把配置好的系统固化成本地镜像,方便以后使用。
配置 Docker 工程
作为参考的 docker-compose.yaml 如下:
version: '3.8'
services:
immortalwrt:
image: immortalwrt/rootfs:openwrt-25.12.1 # 原始镜像
#注:后续 commit 后,可以改成自己的镜像名,例如 immortalwrt-custom:25.12.1-20260724
container_name: immortalwrt # 固定容器名
restart: always
privileged: true # 特权模式
command: /sbin/init
networks:
immortal-macvlan:
ipv4_address: 192.168.1.3 # 指定 IP
networks:
immortal-macvlan:
driver: macvlan
driver_opts:
parent: bond1 # 物理网卡名
macvlan_mode: bridge
enable_ipv6: true # 开启 ipv6,个人喜好,不需要的可以关闭
ipam:
config:
- subnet: 192.168.1.0/24 # 子网网段
gateway: 192.168.1.1 # 主路由
常见 docker 配置项就不说了,只记录以下几点:
- 必须要特权模式。
- 作为旁路由系统,需要虚拟的局域网独立 IP,当前配置指定了 macvlan 驱动,理论上也可以用 ipvlan。
- 物理网卡名通过
ip link查询。 - ipv6 并非必须启动,可能会带来麻烦。我自己的用例需要 ipv6 地址,所以必须启动。
子网网段/网关(主路由)必须指定,IP强烈建议指定(实际上 v6 地址也可以指定)。
关于 macvlan 和 ipvlan,这两个都是获得 IP 的方式,区别在于:
- macvlan 能虚拟 mac 地址,因此更接近真实网卡。
- ipvlan 只虚拟 IP,跟主机用同一个 mac,所以可能会有边缘 case 存在问题,但性能比 macvlan 更好。
如果要用 ipvlan,那么只需要这样修改上面的例子:
macvlan_mode: bridge需要改成ipvlan_mode: l2- 其它所有的 macvlan 字符串改成 ipvlan。
另外 macvlan 和 ipvlan 存在同样的主机无法直接访问容器的虚拟 IP 的问题,解决方法也类似,即在主机上创建一个虚拟网卡并指定路由,这里只写 macvlan 的例子(在主机操作):
# 创建虚拟网卡
ip link add macvlan-shim link bond1 type macvlan mode bridge
# 指定虚拟网卡 IP
ip addr add 192.168.1.4/24 dev macvlan-shim
# 启动虚拟网卡
ip link set macvlan-shim up
# 指定通往容器 IP 的路由
ip route add 192.168.1.3/32 dev macvlan-shim
配置 immortalwrt
配置网络
按照上面的配置,启动 immortalwrt 之后,是没法看到图形界面的。因为在这个时间点,immortalwrt 自己配置的网络是错的。所以需要先在主机直接 attach 到容器并修改配置文件。这里建议最好先了解 vi 的基本用法。
先执行 docker exec -it immortalwrt /bin/sh 连上容器。这部分操作都是容器内部操作。
用 vi 修改 /etc/config/network,添加一个接口:
config interface 'lan'
option proto 'static'
option ipaddr '192.168.1.3'
option netmask '255.255.255.0'
option gateway '192.168.1.1'
option ip6proto 'dhcp'
option sourcefilter '0'
option device 'eth0'
list dns '192.168.1.1'
option multipath 'off'
然后执行 /etc/init.d/network restart 重启网络。
有一种理论上跟上面等价的做法,用 uci 命令,但我自己没这么试过。
# 1. 创建名为 lan 的 interface 节点
uci set network.lan=interface
# 2. 设置各个配置项 (option)
uci set network.lan.proto='static'
uci set network.lan.ipaddr='192.168.1.3'
uci set network.lan.netmask='255.255.255.0'
uci set network.lan.gateway='192.168.1.1'
uci set network.lan.ip6proto='dhcp'
uci set network.lan.sourcefilter='0'
uci set network.lan.device='eth0'
uci set network.lan.multipath='off'
# 3. 添加列表项 (list)
uci add_list network.lan.dns='192.168.1.1'
# 4. 提交更改写回文件,并重启网络生效
uci commit network
/etc/init.d/network restart
这时候可以用 ip addr 命令看网络是否正常了。
如果像我一样需要 ipv6 地址,那么还得改 /etc/sysctl.conf,添加这句:net.ipv6.conf.eth0.accept_ra=2,再重启网络。
安装软件
按照上面的做法做完后,虽然容器网络正常了,但仍然无法用浏览器访问,原因是没有 luci 界面。
所以最基础的安装方式仍然是容器命令行:
apk add luci luci-i18n-base-zh-cn
这句命令成功以后,就可以通过 http://192.168.1.3 访问 immortalwrt 了。
接下来其他软件可以通过浏览器安装,也可以通过命令行,自行选择即可。
通过浏览器调整配置
由于现在可以使用浏览器调整,接下来的处理就方便多了。
- 关闭 DHCP:网络 - 接口 - lan - 编辑 - DHCP 服务器 - 常规 - 忽略此接口。
- 删除不必要接口:网络 - 接口 - wan - 删除,网络 - 接口 - wan6 - 删除。
- 配置防火墙:网络 - 防火墙 - 常规设置。可以删除下面区域中所有条目,再添加并保存:
- 名称=lan
- 输入+出站数据+区域内转发=接受
- IP 动态伪装+TCP MSS 钳制=yes
- 涵盖的网络=lan
- 配置密码及 SSH:系统 - 管理权
其他配置就自由发挥吧。
配置主路由 DHCP 通知
其实上次的文章里有写,不过为了方便开关,改了一点点做法。就是把 dhcp 配置的部分放到 /etc/dnsmasq.d 目录下的 *.conf 文件去。这样要开关这部分功能的话,只需要将配置文件改名然后 /etc/init.d/dnsmasq restart 即可。
还可以加个自动化思路,比如定时执行脚本,ping 旁路由地址,如果 ping 的状态发生变化,则自动将文件改名即可。这种问题找 AI 处理就好了。
结论
旁路由的最大好处,就是随便怎么折腾,哪怕是崩溃了,都不影响其他人上网。
接下来用一段时间看看 immortalwrt 会不会比 QWRT 好一些。