上一篇 下一篇 分享链接 返回 返回顶部

如何在香港服务器运行 Debian 时,用 FRR 配 BGP 路由策略,把跨境网络“稳”下来

发布人:Minchunlin 发布时间:2025-08-29 11:46 阅读量:844


半夜 2 点,我蹲在 42U 机柜前,盯着那台刚上架的香港节点——HK-EDGE-03。白天投诉的跨境丢包还在,我的微信监控群里,用户时不时冒出一句“又卡了”。那一刻我下了决心:把 BGP 策略重新梳理,用 FRR 把路选稳,把跨境这口气接顺。下面是一整晚到清晨的实操记录,也是后来多次复用的标准落地方案。

1. 目标与约束(说清楚我们要“稳”什么)

目标

  • 香港边缘节点通过 两家上游(Upstream-A / Upstream-B) 出口,稳定承载跨境(CN ↔ HK ↔ Global)业务。
  • 基于 BGP 路由策略(local-pref、AS-PATH prepend、MED、Community、RPKI、BFD、ECMP 等)实现 首选线路、自动降级 和 快速收敛。
  • 解决跨境链路常见的 MTU/PMTUD、对称性、路由泄露、会话抖动 等问题。

约束

  • 系统使用 Debian 12(bookworm),路由栈采用 FRRouting(FRR)。
  • 单机双口/四口 10G,和上游通过 eBGP 邻接。
  • 需要兼顾 新手可复制 与 老手可扩展:把“能跑通”与“跑稳、跑好”一次讲透。

2. 现场拓扑与硬件清单(真实货)

2.1 逻辑拓扑(简化)

拓扑:
         [用户/分支/IDC]
                 |
            (公网/专线)
                 |
        ┌─────────────────┐
        │   HK-EDGE-03    │ Debian + FRR
        │  AS 64512       │
        │  203.0.113.2    │ loopback(router-id)
        └───┬───────────┬─┘
            |           |
     eBGP #1|           |eBGP #2
  192.0.2.2 |           | 198.51.100.2
      AS64501           AS64502
     Upstream-A         Upstream-B
     (跨境优)            (全球覆盖更广)

2.2 硬件/链路参数(现场登记表)

型号/参数 说明
机型 1U 定制 前置双 NVMe,双电热插
CPU Intel Xeon Silver 4310 ×1 12C/24T
内存 64GB ECC FRR 占用不高,但留够缓存
系统盘 960GB NVMe FRR 配置与日志
网卡 Intel X710 10G ×2(bond 可选) 与两家上游直连
上游 A AS64501(标注:跨境质量更优) 物理 10G,延迟/丢包佳
上游 B AS64502(标注:全球 reach 更强) 物理 10G,带宽余量大
内网 VXLAN/传统三层 视现网而定
路由 ID 203.0.113.2 TEST-NET 样例地址

3. 系统与网络前置准备(把坑先填一半)

目的:让 FRR 与内核网络栈处于“可用于承载 BGP 的稳态”。

3.1 Debian 基础与时间同步

apt update && apt -y upgrade
apt -y install chrony ethtool tcpdump mtr iperf3 jq
systemctl enable --now chrony

生产上 NTP/Chrony 必开,BFD/RPKI 超时与 BGP 退避都跟时钟相关。

3.2 网卡与内核参数(减少非必要不稳定因素)

# 关闭会“抖”的 offload(按需,不是一刀切;X710 一般稳)
ethtool -K eth0 gso off tso off gro off
ethtool -K eth1 gso off tso off gro off

# 避免不对称路由被反射拒绝
cat >/etc/sysctl.d/99-edge.conf <<'EOF'
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0

# PMTUD/跨境链路 MTU 不一致时的自适应
net.ipv4.tcp_mtu_probing = 1

# 降低 ICMP 重定向/源路由等风险
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects    = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.default.send_redirects   = 0

# 提高邻居表与路由容量
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
EOF
sysctl --system

经验:跨境经常 MTU 不一致(GRE、IPSec、第三方网关),tcp_mtu_probing=1 和 MSS Clamp 能救急。

MSS Clamp(iptables 版):

apt -y install iptables-persistent
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
netfilter-persistent save

3.3 安装 FRR

Debian 12 的自带版本常够用;追新可加 FRR 官方仓库。以下演示通用装法:

apt -y install frr frr-pythontools
sed -i 's/bgpd=no/bgpd=yes/' /etc/frr/daemons
sed -i 's/bfdd=no/bfdd=yes/' /etc/frr/daemons
systemctl enable --now frr

4. 策略先行:BGP 设计蓝图

4.1 我们希望路由长这样

入站(学到的路):

  • 来自 Upstream-A 的前缀 → local-pref=200(更优先)
  • 来自 Upstream-B 的前缀 → local-pref=150
  • 对短时抖动做 轻量 damping(避免打死)
  • RPKI 验证 拒绝 invalid,记录未知/unknown

出站(我们通告的路):

  • 对 Upstream-A:不做 AS-PATH prepend(作为首选出口)
  • 对 Upstream-B:prepend 两次,并可设置较高 MED(作为备选/次优)
  • 支持 Blackhole 社区 与 地理偏好(上游是否支持以合同为准)

会话层:

  • BFD 加速失效检测(200ms×3 探测)
  • Graceful Restart 与 GTSM(TTL Security)
  • Maximum-Prefix 防路由泄露

ECMP 打开,但开启 multipath-relax,在路径相近时并行分担

4.2 社区与优先策略对照表(示例)

名称 社区/属性 用途
优先走 A local-pref=200(入站) 偏爱 A 的来路
次优走 B local-pref=150(入站) A 不可用时切 B
出站对 B 降优 as-path prepend 2次(出站) 让外界更倾向选 A
地区引流 64512:100/200(出站) 让上游在特定区域优选/降级(需上游支持)
黑洞 65535:666(出站) DDoS 黑洞(需上游启用)

5. FRR 基础配置(从 0 到能起 BGP)

我习惯用 集成配置(/etc/frr/frr.conf)+ vtysh。以下配置以 IPv4 单播 为主,IPv6 同理。

vtysh
configure terminal
!
frr defaults traditional
service integrated-vtysh-config
!
hostname HK-EDGE-03
username netop nopassword
!
log syslog informational
!
ip prefix-list PFX-ORIGIN seq 5 permit 203.0.113.0/24 le 24
!
# ---------- 入站策略 ----------
route-map IN-A permit 10
  set local-preference 200
  set weight 50
!
route-map IN-B permit 10
  set local-preference 150
  set weight 10
!
# ---------- 出站策略 ----------
route-map OUT-A permit 10
  match ip address prefix-list PFX-ORIGIN
  set community 64512:100 additive
  # 对 A 不做 prepend,保持“更好看”的 AS-PATH
!
route-map OUT-B permit 10
  match ip address prefix-list PFX-ORIGIN
  set community 64512:200 additive
  set as-path prepend 64512 64512
  set metric 50
!
# ---------- 轻量抑制(可选) ----------
bgp dampening half-life 15 reuse 750 suppress 2000 max-suppress-time 45
!
router bgp 64512
  bgp router-id 203.0.113.2
  bgp bestpath as-path multipath-relax
  maximum-paths 2
  bgp graceful-restart
  timers bgp 10 30
  no bgp default ipv4-unicast
!
  neighbor 192.0.2.1 remote-as 64501
  neighbor 192.0.2.1 description Upstream-A
  neighbor 192.0.2.1 timers 5 15
  neighbor 192.0.2.1 bfd
  neighbor 192.0.2.1 ttl-security hops 2
!
  neighbor 198.51.100.1 remote-as 64502
  neighbor 198.51.100.1 description Upstream-B
  neighbor 198.51.100.1 timers 5 15
  neighbor 198.51.100.1 bfd
  neighbor 198.51.100.1 ttl-security hops 2
!
 address-family ipv4 unicast
  network 203.0.113.0/24
  neighbor 192.0.2.1 activate
  neighbor 192.0.2.1 route-map IN-A in
  neighbor 192.0.2.1 route-map OUT-A out
  neighbor 192.0.2.1 maximum-prefix 200000 90 restart 5
  neighbor 198.51.100.1 activate
  neighbor 198.51.100.1 route-map IN-B in
  neighbor 198.51.100.1 route-map OUT-B out
  neighbor 198.51.100.1 maximum-prefix 200000 90 restart 5
 exit-address-family
!
# ---------- BFD ----------
bfd
 peer 192.0.2.1
  detect-multiplier 3
  required-min-rx 200
  desired-min-tx 200
 !
 peer 198.51.100.1
  detect-multiplier 3
  required-min-rx 200
  desired-min-tx 200
!
end
write memory

解释要点

  • 入站用 local-pref/weight 影响我们“学到的”路由优先级;出站再用 AS-PATH prepend/MED/Community 影响“别人如何走向我们”。
  • maximum-prefix 是防误操作的保险丝。
  • multipath-relax + maximum-paths 2:当两条 eBGP 路的 AS-PATH 代价相近时并行转发,减震。
  • bfd:百毫秒级失效检测,比纯 BGP Keepalive 快。

6. RPKI 验证(防“脏路由”)

生产建议部署本地 RTR Cache(如 Routinator、rpki-client)后让 FRR 进行实时验证。下面给出常见写法(注意按你的 cache 服务实际 IP/端口调整)。

configure terminal
router bgp 64512
  bgp rpki server tcp 127.0.0.1 3323
  bgp rpki retry 60
  bgp rpki timeout 600
  bgp rpki cache-time 900
  bgp rpki allow-invalid off
end
write memory

验证:

vtysh -c "show bgp rpki"
vtysh -c "show bgp ipv4 uni 203.0.113.0/24 json" | jq .

经验:把 allow-invalid off 打开,invalid 的路 不要学,unknown 记录并持续观察(有些小网段还没 ROA)。

7. 跨境稳定性“必修课”

  • GTSM(TTL Security):上面已启用 ttl-security hops 2,减少会话被远端伪造探测的风险。
  • Graceful Restart:路由器/进程短时重启时,转发表可暂存,不至于黑一片。
  • BFD:强烈推荐 对跨境 eBGP 邻居打开。
  • 对称性:rp_filter=0 + 合理的 入站 local-pref 与 出站 prepend,尽可能让去来一致,至少业务关键段一致。
  • MTU/MSS:tcp_mtu_probing + MSS Clamp,大多数“海外看视频时不时卡一下”的玄学问题都能被这俩解决一半。
  • 黑洞社区:当单点遭受 DDoS,先导向上游黑洞,恢复后再解除,避免牵连整体。
  • 最大前缀:防止内部路由泄露到上游(你不想凌晨背锅)。

8. 监控与自愈(“看得见”才算稳)

8.1 快速观测命令

vtysh -c "show ip bgp summary"
vtysh -c "show ip bgp neighbors 192.0.2.1"
vtysh -c "show ip route 203.0.113.0/24"
vtysh -c "show bfd peers"

8.2 指标采集(Telegraf exec 简单抓)

/etc/telegraf/telegraf.d/frr.conf:

[[inputs.exec]]
  commands = ["vtysh -c 'show ip bgp summary json'"]
  data_format = "json"
  name_override = "frr_bgp"
  interval = "10s"

可在监控面板里做以下 SLO 看板:

指标 期望 告警线
eBGP 邻居会话数 2 <2
BFD 状态 Up 非 Up
路由收敛耗时 < 1s(BFD 触发) > 3s
丢包(mtr 到关键地域) < 0.5% > 2%
RTT 95 分位(CN 节点) < 40ms(HK↔南方) > 80ms

9. 验证与对比(把“稳”量化)

我在现场用了 iperf3 + mtr 做前后对比,摘录关键数据如下(样例):

场景 调整前 调整后
CN ↔ HK(高峰 RTT) 54ms / 抖动 12ms 39ms / 抖动 5ms
CN ↔ HK 丢包(10 分钟) 1.8% 0.3%
BGP 收敛(上游 A 短断 1s) 3.5s <1s(BFD 触发)
出口对称性(会话采样) 62% 91%

10. 常见坑与现场解法(都是泪)

邻居起不来

ttl-security 开了但跳数不对 → 与上游确认直连还是跨交换设备,合理设置 hops。

ACL/防火墙挡住 179/TCP 或 BFD → 机房边界检查 mangle/filter 表。

学到奇怪的“全球全表”,路爆了

你本来只想默认路,但上游给了全表 → maximum-prefix 触发 + 沟通只要 default-originate。

或者加 route-map 限制入站前缀数量/长度。

跨境特定 APP 卡顿

大多是 PMTUD 被墙/丢弃:开启 MSS Clamp、tcp_mtu_probing。

也可能是 回程绕路:分析 traceroute -T 与流日志,调整 出站 prepend 或跟上游协商 社区策略。

RPKI 配好后业务断

部分自有/合作前缀没有及时注册 ROA → unknown 先不拦,invalid 才拦,并在变更窗口逐步收紧。

ECMP 开了但没生效

需要 bgp bestpath as-path multipath-relax + 两路代价接近;还要注意内核 fib_multipath_hash_policy(Debian 默认 flow 哈希基本够用)。

11. 变更与回滚(要写在手边的小纸条)

上线顺序:

先 IN 策略(不影响外界) → 2) 开 BFD → 3) 开 RPKI(allow-invalid on,观察) → 4) 开 OUT 策略(小流量时段) → 5) 逐步收紧 RPKI。

回滚最小化:

  • 只对 OUT 做了 prepend/社区?先 no neighbor X route-map OUT-* out。
  • 入站 local-pref 导致异常?no route-map IN-* in 先回默认。
  • BFD 误报?no neighbor X bfd 暂时关掉,用 BGP keepalive 顶住。

12. 附:一份最小可用清单(Checklist)

  •  Debian 升级、时间同步 OK
  •  rp_filter=0、tcp_mtu_probing=1、MSS Clamp 就位
  •  FRR 安装,bgpd、bfdd 已启用
  •  eBGP 邻居建立,show ip bgp summary 为 Establ
  •  入站 local-pref:A=200、B=150
  •  出站 prepend:B 两次,A 不加
  •  BFD Up,收敛 < 1s
  •  RPKI 连接正常,invalid 已拒
  •  ECMP 生效,关键流量对称
  •  监控面板、告警规则上线

天色亮起来时,机房的玻璃已经有了微微的灰。show ip bgp summary 里两个邻居都稳稳地 Estab,BFD peer 一片绿色。我刷了眼监控,CN→HK 的 95 分位 RTT 比昨晚好了近 20ms。
台风天、节假日、直播秒杀……这些日子我都见过。跨境网络从来不是“配一次就万无一失”,而是用 正确的策略 和 适当的冗余,在不确定里找确定。
如果你也在香港的机房里熬过一个夜班,希望这篇手记能帮你少踩几个坑。我们不追玄学,只追“可复现的稳定”

目录结构
全文