CentOS Stream 9 使用 FRR 与华为 USG 建立 BGP 动态同步 ZeroTier 路由

摘要:本文介绍如何在 CentOS Stream 9 部署 FRRouting,通过 eBGP 将 ZeroTier 动态路由自动同步至华为 USG,替代传统静态路由维护。
大家好,我是云核筑梦家。
在使用 ZeroTier 做异地组网时,我们通常会在 ZeroTier Controller 中配置 Managed Routes,让 Linux 自动获得不同远端节点的业务路由。
如果 Linux 上层还有华为 USG 防火墙,传统方式一般需要在防火墙上手工添加静态路由。节点和业务网段越来越多后,每次新增、删除或调整路由都需要重复修改防火墙配置,维护成本会逐渐增加。
本文通过 FRRouting(FRR)+ BGP 实现自动同步:
ZeroTier 路由变化 → Linux Kernel 路由变化 → FRR 自动读取 → BGP 发布/撤销 → 华为 USG 自动更新路由
这样以后只需要管理 ZeroTier 路由,华为侧无需再逐条维护对应的静态路由。
本文所有 IP、AS 号、接口名称和业务网段均为实验示例,请根据实际网络环境修改。
一、实验环境
本文使用以下实验参数:
Linux 与华为通过 10.88.200.0/24 建立 eBGP。
ZeroTier 虚拟网络使用 10.66.0.0/24。
实验中的业务路由示例:
10.20.0.0/21下一跳10.66.0.4172.20.11.0/24下一跳10.66.0.3172.20.12.0/24下一跳10.66.0.3172.20.13.0/24下一跳10.66.0.3172.20.14.0/24下一跳10.66.0.3
二、安装 FRRouting
先确认系统版本:
cat /etc/os-release本文使用 CentOS Stream 9。
安装 FRR:
dnf install -y frr查看软件包信息:
dnf info frr三、启用 BGP 服务
FRR 安装完成后,默认可能没有启用 BGP Daemon。
查看当前配置:
grep -E '^(bgpd|bfdd|vtysh_enable)=' /etc/frr/daemons如果看到:
bgpd=no执行:
sed -i 's/^bgpd=no/bgpd=yes/' /etc/frr/daemons启动 FRR,并设置为开机启动:
systemctl enable frr
systemctl restart frr检查进程:
ps -ef | grep -E 'bgpd|zebra' | grep -v grep正常情况下应该能够看到 zebra 和 bgpd 进程。
四、确认 ZeroTier 路由
查看 Linux 当前路由:
ip route实验环境可能类似:
default via 10.88.200.1 dev eth1 proto static metric 100
10.20.0.0/21 via 10.66.0.4 dev ztxxxxxxxx proto static metric 5000
10.88.200.0/24 dev eth1 proto kernel scope link
10.66.0.0/24 dev ztxxxxxxxx proto kernel scope link
172.20.11.0/24 via 10.66.0.3 dev ztxxxxxxxx proto static metric 5000
172.20.12.0/24 via 10.66.0.3 dev ztxxxxxxxx proto static metric 5000
172.20.13.0/24 via 10.66.0.3 dev ztxxxxxxxx proto static metric 5000
172.20.14.0/24 via 10.66.0.3 dev ztxxxxxxxx proto static metric 5000这里的重点是:不要在 FRR 中把所有业务网段一个一个写死。
例如不建议采用:
network 10.20.0.0/21
network 172.20.11.0/24
network 172.20.12.0/24否则以后 ZeroTier 新增一个业务网段,还要再次登录 Linux 修改 FRR。
本文希望实现的效果是:
只要 Linux Kernel 中出现“下一跳属于 ZeroTier 地址池”的路由,就自动通过 BGP 发布给华为。
五、配置 ZeroTier 下一跳过滤
进入 FRR:
vtysh假设 ZeroTier 虚拟地址池为:
10.66.0.0/24
创建 Prefix List:
configure terminal
ip prefix-list ZT-NEXTHOP seq 10 permit 10.66.0.0/24 le 32这条规则用来匹配下一跳属于 10.66.0.0/24 的路由。
例如:
10.66.0.3可以匹配10.66.0.4可以匹配10.88.200.1不匹配
因此 Linux 默认路由不会被错误发布出去。
六、创建 Kernel 路由重分发策略
创建 Route-Map:
route-map ZT-REDIST permit 10
match ip next-hop prefix-list ZT-NEXTHOP
set community 65101:100 additive
exit它的工作逻辑如下:
FRR 获取 Linux Kernel 路由。
检查该路由的下一跳。
如果下一跳属于 ZeroTier 地址池,则允许进入 BGP。
给路由增加
65101:100Community。
例如:
172.20.11.0/24 via 10.66.0.3
能够通过过滤。
而:
0.0.0.0/0 via 10.88.200.1
不会通过。
七、增加第二层出口过滤
为了进一步降低误发布路由的风险,可以增加一层 Community 过滤。
创建 Community List:
bgp community-list standard ZT-COMMUNITY permit 65101:100创建出口 Route-Map:
route-map ZT-OUT permit 10
match community ZT-COMMUNITY
exit这样只有经过 ZT-REDIST 正确处理,并带有 65101:100 Community 的路由,才能最终发送给华为。
完整逻辑为:
Kernel 路由 → 检查 ZeroTier 下一跳 → 打 Community → 出口再次检查 → 发布给 USG
这种做法可以降低以后误配置其他 BGP 路由时被意外发布给防火墙的风险。
八、禁止华为反向向 Linux 注入路由
本文主要需求是:
Linux → Huawei USG
不需要:
Huawei USG → Linux
因此创建入口拒绝策略:
route-map BLOCK-IN deny 10
exit这样即使以后华为侧误配置了“引入静态路由”“引入直连路由”或其他 BGP 路由,Linux 也不会接收。
九、配置 Linux BGP
实验参数:
配置:
router bgp 65101
bgp router-id 10.88.200.2
bgp log-neighbor-changes
neighbor 10.88.200.1 remote-as 65100
neighbor 10.88.200.1 description Huawei-USG
address-family ipv4 unicast
redistribute kernel route-map ZT-REDIST
neighbor 10.88.200.1 route-map BLOCK-IN in
neighbor 10.88.200.1 route-map ZT-OUT out
exit-address-family
exit保存配置:
end
write memoryFRR 配置默认保存到:
/etc/frr/frr.conf建议做一次备份:
cp /etc/frr/frr.conf /root/frr.conf.production-$(date +%Y%m%d-%H%M%S)十、Linux 最终核心配置
最终核心配置如下:
ip prefix-list ZT-NEXTHOP seq 10 permit 10.66.0.0/24 le 32
bgp community-list standard ZT-COMMUNITY permit 65101:100
route-map ZT-REDIST permit 10
match ip next-hop prefix-list ZT-NEXTHOP
set community 65101:100 additive
exit
route-map ZT-OUT permit 10
match community ZT-COMMUNITY
exit
route-map BLOCK-IN deny 10
exit
router bgp 65101
bgp router-id 10.88.200.2
bgp log-neighbor-changes
neighbor 10.88.200.1 remote-as 65100
neighbor 10.88.200.1 description Huawei-USG
address-family ipv4 unicast
redistribute kernel route-map ZT-REDIST
neighbor 10.88.200.1 route-map BLOCK-IN in
neighbor 10.88.200.1 route-map ZT-OUT out
exit-address-family
exit这里没有写死任何业务网段。
需要固定的只有:
华为和 Linux 的 BGP 邻居地址
ZeroTier 虚拟地址池
两端 BGP AS
以后业务网段增加或删除,不需要修改这段配置。
十一、配置华为 USG BGP
华为侧开启 BGP,实验参数如下:
本地 AS:
65100Router ID:
10.88.200.1邻居 IP:
10.88.200.2邻居 AS:
65101
因为华为和 Linux 位于同一个三层网段,所以属于直连 eBGP。
EBGP 最大跳数保持 1 即可。
BFD 前期可以暂时关闭,先确保普通 BGP 稳定运行。
CLI 配置逻辑类似:
bgp 65100
router-id 10.88.200.1
peer 10.88.200.2 as-number 65101
ipv4-family unicast
peer 10.88.200.2 enable不同 USG 软件版本的 CLI 命令可能略有差异,也可以直接通过 Web 页面配置。
十二、检查 BGP 邻居
Linux 执行:
vtysh -c "show bgp ipv4 unicast summary"正常情况下可以看到类似:
Neighbor V AS State/PfxRcd PfxSnt
10.88.200.1 4 65100 0 5如果 State/PfxRcd 显示数字,而不是 Idle、Active 或 Connect,说明 BGP 已经进入 Established 状态。
这里显示 0 是正常的。
因为本文通过 BLOCK-IN 禁止 Linux 接收华为发布的路由,所以 Linux 收到的 Prefix 数量为 0。
PfxSnt 5 表示 Linux 正在向华为发送 5 条路由。
十三、查看 FRR 获取到的 Linux 路由
执行:
vtysh -c "show ip route"示例:
K>* 10.20.0.0/21 [0/5000] via 10.66.0.4
K>* 172.20.11.0/24 [0/5000] via 10.66.0.3
K>* 172.20.12.0/24 [0/5000] via 10.66.0.3
K>* 172.20.13.0/24 [0/5000] via 10.66.0.3
K>* 172.20.14.0/24 [0/5000] via 10.66.0.3其中:
K = Kernel Route
这也是本文最终使用:
redistribute kernel route-map ZT-REDIST而不是 redistribute static 的原因。
十四、检查 Linux 实际发布了哪些路由
执行:
vtysh -c "show bgp ipv4 unicast neighbors 10.88.200.1 advertised-routes"正常应该只看到业务路由,例如:
10.20.0.0/21
172.20.11.0/24
172.20.12.0/24
172.20.13.0/24
172.20.14.0/24不应该看到:
0.0.0.0/0
10.88.200.0/24
10.66.0.0/24如果只发布预期业务网段,就说明 Route-Map 已经正常工作。
十五、华为查看学习到的路由
查看 BGP 邻居:
display bgp peer邻居状态应该为:
Established
查看 BGP 路由:
display bgp routing-table查看已经进入主路由表的 BGP 路由:
display ip routing-table protocol bgp实验环境示例:
Destination/Mask Proto Cost NextHop Interface
10.20.0.0/21 EBGP 5000 10.88.200.2 Vlanif200
172.20.11.0/24 EBGP 5000 10.88.200.2 Vlanif200
172.20.12.0/24 EBGP 5000 10.88.200.2 Vlanif200
172.20.13.0/24 EBGP 5000 10.88.200.2 Vlanif200
172.20.14.0/24 EBGP 5000 10.88.200.2 Vlanif200如果路由 Flags 中带有 D,表示该路由已经 Download to FIB,可以参与实际转发。
十六、原有静态路由不要一次性删除
生产环境建议采用渐进式切换。
推荐顺序:
建立 BGP。
确认邻居状态为 Established。
确认所有业务路由已经通过 BGP 学习。
选择一个测试网段。
删除该网段原有静态路由。
查看该路由是否自动切换为 EBGP。
测试实际业务访问。
确认无问题后,再删除剩余静态路由。
例如:
display ip routing-table 172.20.14.0确认协议已经变成 EBGP,下一跳正确指向 Linux 后,再继续清理其他静态路由。
十七、新增 ZeroTier 路由测试
假设以后在 ZeroTier Controller 中新增:
192.168.88.0/24 via 10.66.0.8
Linux 自动获得:
192.168.88.0/24 via 10.66.0.8 dev ztxxxxxxxx因为 10.66.0.8 属于 10.66.0.0/24,所以会自动被 ZT-REDIST 匹配。
随后流程为:
ZeroTier → Linux Kernel → FRR → BGP → Huawei USG
华为最终会自动获得:
192.168.88.0/24 → 10.88.200.2
整个过程中不需要再次登录华为新增静态路由。
十八、删除 ZeroTier 路由
如果在 ZeroTier Controller 中删除:
192.168.88.0/24 via 10.66.0.8
Linux Kernel 中对应路由消失后,FRR 会自动向华为发送 BGP Withdraw。
华为随后自动删除对应 BGP 路由。
因此可以实现:
添加 Managed Route 自动发布,删除 Managed Route 自动撤销。
十九、常用排查命令
Linux 查看 BGP 邻居:
vtysh -c "show bgp ipv4 unicast summary"查看 FRR 路由:
vtysh -c "show ip route"查看 BGP 路由:
vtysh -c "show bgp ipv4 unicast"查看实际向华为发布的路由:
vtysh -c "show bgp ipv4 unicast neighbors 10.88.200.1 advertised-routes"查看 FRR 服务:
systemctl status frr查看 BGP 进程:
ps -ef | grep bgpd查看 TCP 179:
ss -lntp | grep ':179'华为查看邻居:
display bgp peer华为查看 BGP 路由:
display bgp routing-table华为查看已经安装的 BGP 路由:
display ip routing-table protocol bgp二十、目前方案仍存在的一个问题
这套方案解决的是:
Linux Kernel 路由发生变化后,华为能够自动同步。
但仍有一种特殊情况需要注意。
假设 Linux 中存在:
172.20.11.0/24 via 10.66.0.3
如果 ZeroTier 节点 10.66.0.3 已经掉线,但是 ZeroTier Managed Route 暂时仍保留在 Linux Kernel 中,那么 FRR 依然会认为这条路由存在。
此时可能出现:
ZeroTier 节点失联 → Kernel 路由仍存在 → FRR 继续发布 → 华为继续转发 → 流量黑洞
对于要求更高的生产环境,可以进一步增加:
ZeroTier 节点健康检测
自动路由撤销
BFD
脚本联动
双 Linux FRR 冗余
BGP MED 主备控制
这些可以作为后续进一步优化的方向。
总结
本文通过 CentOS Stream 9 + FRRouting + ZeroTier + Huawei USG 实现了 ZeroTier 业务路由自动同步。
传统方式需要:
新增业务网段 → 登录防火墙 → 添加静态路由
改造以后变成:
ZeroTier 添加 Managed Route → 自动同步至 Huawei USG
FRR 使用 redistribute kernel 获取 Linux Kernel 路由,再通过 Route-Map 只选择下一跳属于 ZeroTier 网段的路由。
同时使用 Community 和出口 Route-Map 做第二层过滤,降低默认路由、管理网段或其他非预期路由被错误发布的风险。
对于 ZeroTier 节点较多、业务网段经常增加或调整的环境,这种方案可以明显减少静态路由维护工作量,也让路由增加和撤销更加自动化。
评论