告别 ALLinBOOM,用 VRRP 为折腾旁路由保驾护航 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
metalvest

告别 ALLinBOOM,用 VRRP 为折腾旁路由保驾护航

  •  
  •   metalvest 9 天前 via Android 2258 次点击
    爱折腾的大伙都知道,ALLinONE 软路由一旦发生崩溃,便会造成全家断网(ALLinBOOM)。

    解决这一问题的思路在于,把路由功能与扩展功能进行解耦处理,也就是采用“主路由 + 旁路由”这一架构。在常见的旁路由方案当中,要么需要客户端手动把网关指向旁路由(一旦旁路由故障,每个设备都要手动改回主路由),要么在旁路由上开启强制 DHCP 功能(旁路由宕机之后,DHCP 服务随之失效,新设备将无法获取 IP 地址)。这两种方式在自动化方面均有所欠缺,一旦遇到断网,全家人就要给你上压力了。

    更为省心的做法是,引入 VRRP (虚拟路由冗余协议),让主路由与旁路由共同使用一个虚拟网关 IP 地址。在正常状态下,旁路由会作为 MASTER 角色来接管流量;一旦旁路由发生故障,主路由会在数秒内自动接替其工作,整个切换过程对客户端而言完全无感。
    下面给出基于 VRRP 协议的具体配置方法。整个方案需要借助两台设备来完成:其中一台作为主路由,负责拨号、NAT 以及 DHCP 服务,其 VRRP 角色为 BACKUP ;另一台作为旁路由,负责处理特殊流量(例如去广告、科学上网等),其 VRRP 角色为 MASTER 。同时,还需要设置一个虚拟网关 IP ( VIP ),以此作为客户端统一的网关地址,并由 VRRP 协议动态地对其进行接管。

    以下配置以具体的硬件设备为例(可以将其任意更换为手头其他支持 OpenWrt 系统的设备):
    主路由:H3C NX30 Pro ( LAN 口 IP 地址为 10.0.0.1 ,默认网关指向运营商侧)
    旁路由:斐讯 N1 ( IP 地址为 10.0.0.3 ,默认网关为 10.0.0.1 ,并关闭 DHCP 服务)
    VIP 虚拟网关地址:10.0.0.254/24

    配置步骤基础准备:两台设备均已刷入 OpenWrt 系统,并且主路由的 WAN 口能够正常上网。
    对旁路由进行静态 IP 地址的设置:IP 地址为 10.0.0.3 ,网关为 10.0.0.1 ,同时关闭其 DHCP 服务。

    安装 keepalived 软件包
    opkg update && opkg install keepalived
    编写配置文件
    旁路由( MASTER )的配置文件路径为 /etc/keepalived/keepalived.conf ,其内容如下:
    global_defs {
    router_id N1_MASTER
    }
    vrrp_instance VI_1 { state MASTER interface br-lan virtual_router_id 51 priority 150 advert_int 1 virtual_ipaddress { 10.0.0.254/24 }}
    主路由( BACKUP )的配置文件路径同样为 /etc/keepalived/keepalived.conf ,其内容如下:
    global_defs { router_id NX30Pro_BACKUP }vrrp_instance VI_1 { state BACKUP interface br-lan virtual_router_id 51 priority 100 advert_int 1 virtual_ipaddress { 10.0.0.254/24 }}

    解决 OpenWrt 系统中 UCI 配置覆盖的问题
    在两台设备上分别创建 /etc/config/keepalived 文件,并写入以下内容:
    config globals 'globals'
    option alt_config_file '/etc/keepalived/keepalived.conf'
    启动 keepalived 服务并设置开机自启动
    /etc/init.d/keepalived
    enable/etc/init.d/keepalived start

    通过 DHCP 向客户端下发虚拟网关地址
    在主路由的 LuCI 管理界面中,依次进入:网络 → 接口 → LAN → DHCP 服务器 → 高级设置 → DHCP-选项,然后填入 3,10.0.0.254 。

    验证方案效果
    正常状态下的验证:在旁路由上执行 ip addr show br-lan 命令,可以看到 10.0.0.254/24 地址存在,而主路由上则没有该 IP 地址。
    客户端自动获取网关地址的验证:客户端能够自动获得网关地址 10.0.0.254 。
    模拟旁路由故障的验证:执行 keepalived stop 命令停止旁路由的 keepalived 服务,3 秒之内主路由便会接管 VIP 地址。
    恢复旁路由的验证:执行 keepalived start 命令重新启动旁路由的 keepalived 服务,VIP 地址会自动切换回旁路由。
    重启测试的验证:将两台设备分别重启,重启之后 VIP 地址仍然位于旁路由上,客户端的网关地址也保持正确。

    完成上述配置之后,一旦旁路由发生故障,系统会自动切换至主路由,用户几乎感觉不到断网的发生。这样一来,既能够放心地折腾各种插件功能,又不会影响到全家人的正常上网。虽然该配置过程相比手动修改网关的方式要稍微复杂一些,但是配置完成之后便可以实现一劳永逸的效果。
    15 条回复    2026-04-21 19:41:29 +08:00
    mooyo
        1
    mooyo  
       9 天前
    排版有点问题。。。
    cloudsong
        2
    cloudsong  
       9 天前 via iPhone   1
    写得非常棒。给您锦上添花两点:1. 在 keepalived 中添加 ping 外网地址的功能,防止科学上网插件挂了但是 openwrt 还活着,PREROUTING 链依然存在,但客户端发出的数据包到达旁路由后,防火墙规则会将包扔给指定的端口,此时端口对应的监听进程已经没了,系统内核收到包后发现没有进程认领,通常会直接 DROP 或返回 RST 。2. 如果你所有设备只连接一个交换机就没问题。如果主从之间有交换机,然后下游还有交换机接设备,那么主从之间的交换机一旦坏了,主从都认为自己还活着是主机,就开始竞争给下游发包。这一点可以通过更改网络拓扑解决,大部分人遇不到的
    cloudsong
        3
    cloudsong  
       9 天前 via iPhone
    另外还要考虑 dns 用 fakeip ,以及避免 vrrp 震荡的问题。这些我都遇见过。比如出海线路很差,那么有可能系统会在两个线路之间来回切换,表现是游戏断线,视频通话断线。因此线路检测还需要加入一个延时机制,比如连续 ping 失败 3-5 次就切换。以及在你的 Keepalived 配置 fall 3 rise 2 这种,避免网关反复横跳
    metalvest
        4
    metalvest  
    OP
       9 天前
    @cloudsong #2 你说得非常对。基础 VRRP 配置只检测 keepalived 进程是否存活,无法感知业务层面的故障(如科学上网插件进程假死、dnsmasq 异常、内核转发失效等)。这种“半死”状态会导致 VIP 不切换,客户端流量依然指向已失效的旁路由,造成断网。

    这部分需要根据各人自己使用的具体业务自定义需要检查的内容,就不单独写在文章里了,可以自行描述自己的需求让 AI 帮写合适的脚本逻辑
    djw123
        5
    djw123  
       9 天前
    其实安装 keepalived-i18n 就可以了,web 里面 gui 设置更方便一点
    qwvy2g
        6
    qwvy2g  
       9 天前 via Android
    记得还有一种方式是网关虚拟实体机的 ip ,实体机 vrrp 是最高的。
    Kinnice
        7
    Kinnice  
       9 天前
    还有一个思路是用路由来做,ospf 这种
    cloudsong
        8
    cloudsong  
       9 天前 via iPhone
    @Kinnice 我见过 ospf 做双线分流,但是那是多运营商分流。你如果要分流科学,那回流要单独处理,确保都去主路由。ip 分流通过路由宣告做掉,这是 l3 ,但是请教一下,l7 这层分流怎么做呢?还是用 singbox 吗?还是用 mosdns ?最后科学挂了之后,tun 是否会自动消失呀? tun 如果还在的话,岂不是依然绕不开业务层监控?
    Kinnice
        9
    Kinnice  
       8 天前 via Android
    @cloudsong 所有流量去主路由,
    1 主路由路由分流的路由到旁路设备
    2 主路由设置旁路的设备 srcip 直连

    对于下层设备
    直连: 设备-主路由-互联网
    科学: 设备-主路由-旁路-主路由-互联网

    旁路可随便断开,ospf 会直接建立不了路由通路走直连或其他,dns 最好无污染,有污染就得依靠旁路的嗅探功能,
    Kinnice
        10
    Kinnice  
       8 天前 via Android
    @Kinnice 你也可以理解为就是双 wan ,其中一个 wan 是接到旁路设备的 lan ,这个设备的 wan 又接回主路由的 lan ,只不过做了一个路由配置让他不要环下去
    Kinnice
        11
    Kinnice  
       8 天前 via Android
    @cloudsong 旁路你可以选择直接跑一个 mihomo 或者 singbox ,tun 还是 tproxy 就看你机器性能选择了


    主路由( openwrt )跑 bird 和 adguardhome (国内走运营商,其他走旁路的科学工具的 dns )

    旁路( alpine )跑 bird 和科学工具 7 层分流什么的都没问题

    旁路挂了,本来没法访问的还是没法访问,直连无任何影响

    我现在在两地跑了 2 个方案 vrrp 和 ospf ,发现稳定性几乎一致,节点没全故障过( amy+cn2gia 自建+cnix 自建),以至于都快忘了它们的存在了
    cloudsong
        12
    cloudsong  
       8 天前 via iPhone
    @Kinnice 谢谢。受教了。你这个防环路结构很棒。后面 l7 我打算前面 mosdns 先 dns 分流一次,后面 singbox sniff inbound 兜底。tun 这边还是业务层判断联网来做掉。
    om2mo
        13
    om2mo  
       8 天前 via Android
    你的方案里都是假设出现故障是旁路由,而且故障来源仅仅是 IP 下线

    如果是代理程序意外退出、套接字过高 CPU100%
    ...?

    实际上你的方法完全可以在主路由用脚本替代。
    metalvest
        14
    metalvest  
    OP
       7 天前
    @om2mo 假设出现故障是旁路由是因为这样就只折腾旁路由啊
    LOVOQ
        15
    LOVOQ  
       4 天前
    我个人一点浅见,父母长辈这个需要高可靠网络的群体,建议不要进行多余设置,所有操作建议强制在硬路由上进行。去广告什么的让他在本地设备上进行,不要经过软漏油。如果实在需要软路由功能,建议为他们手动设置网关和 dns 服务器。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2149 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 68ms UTC 16:12 PVG 00:12 LAX 09:12 JFK 12:12
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86