如果在香港服务器部署 Debian 时,如何把“25M 直连 CN2 + 国际带宽”的多线 BGP 真正跑满,让企业 ERP 跨境访问更快

周六夜里 10 点,我盯着机柜里那台刚上架的 1U 服务器,指示灯一闪一闪。财务总监(在苏州)打来电话:“ERP 白天卡得不行,月底对账要命,你说的 CN2 直连什么时候能好?”
我回了句:“今晚把 BGP 跑起来,明早你们就能感到不一样。”这篇文章,就是我那一夜从零到一把多线 BGP(25M CN2 + 国际带宽)在 Debian 上架稳、调顺、跑满、可观测的全过程。没有玄学,只有我踩过的坑和给你的避坑路线。
目标与场景
目标:让大陆用户(华东、华南为主)访问香港的 ERP 系统时,走 CN2 直连,延迟稳定、丢包低;海外用户走 国际混线(NTT/HE/GTT 等)。同时保证 25Mbps 的 CN2 承诺带宽在高峰期不被杂流抢走,关键业务优先级最高。
拓扑与资源(实战参数)
| 项 | 规格 / 说明 |
|---|---|
| 机柜位置 | 香港葵涌某 Tier3 机房 |
| 服务器 | Supermicro 1U(X12 系列)/ Intel Xeon Silver 4310 / 64GB ECC / 2×1.92TB NVMe(RAID1) |
| NIC | 2× Intel X710 10GbE(i40e 驱动),双上联 |
| OS | Debian 12 (bookworm), kernel 6.1 |
| 上游 A | 中国电信 CN2 GIA,1Gbps 物理口,25Mbps commit,eBGP |
| 上游 B | 国际混线(NTT/HE/GTT 混合),1Gbps 物理口,100Mbps commit,eBGP |
| IP 资源 | 各上游提供 /30 P2P;业务使用 /28 公网段(上游 A/B 都可路由) |
| 路由栈 | FRR 8.x(bgpd, zebra, staticd),BFD 开启 |
| 业务 | ERP Web(443/8443),API(9443),S2S VPN(IPsec/GRE)可选 |
| 监控 | Prometheus + Blackbox Exporter,Smokeping,Grafana |
注:是否有自有 ASN/PI 段并不影响本文做法。若你没有公有 ASN,上游同样可做“BGP-Static/默认路由下发 + 你的前缀代播”(常见于托管商)。
一、系统与驱动准备
1)基础安装与更新
apt update && apt -y full-upgrade
apt -y install ethtool net-tools mtr-tiny iperf3 htop jq curl git
2)网卡与中断亲和
X710(i40e)在 PPS 高时中断抖动明显,先把队列打散到 CPU:
ethtool -L eno1 combined 8
ethtool -L eno2 combined 8
# irqbalance 可用,但我更偏向手动绑核
apt -y install irqbalance
systemctl enable --now irqbalance
3)关闭过度 offload(排查 MTU/MSS 方便)
ethtool -K eno1 gso off gro off tso off rxvlan on txvlan on
ethtool -K eno2 gso off gro off tso off rxvlan on txvlan on
二、链路与 IP 分配
假设:
- eno1 → 上游 A(CN2)
- eno2 → 上游 B(国际)
使用 systemd-networkd(更清爽):
/etc/systemd/network/10-eno1.netdev(若需要 VLAN/子接口可加)
[NetDev]
Name=eno1
Kind=ether
/etc/systemd/network/20-eno1.network
[Match]
Name=eno1
[Network]
Address=203.0.113.2/30 # 与上游A P2P
Gateway=203.0.113.1
DNS=1.1.1.1
[Link]
MTUBytes=1500
/etc/systemd/network/20-eno2.network
[Match]
Name=eno2
[Network]
Address=198.51.100.2/30 # 与上游B P2P
Gateway=198.51.100.1
DNS=8.8.8.8
[Link]
MTUBytes=1500
业务网段(/28)建议绑定在 loopback(lo)或 dummy0 上,利于漂移与 BGP 广告:
/etc/systemd/network/30-lo.network
[Match]
Name=lo
[Network]
Address=203.0.200.10/28 # ERP VIP 所在前缀
启用:
systemctl enable --now systemd-networkd
坑1:MTU/DF
CN2 某些路径会有 1492/1480 的实际瓶颈。若发现大量 Frag needed,务必做 MSS Clamping(见后文 nftables),否则 ERP HTTPS 会无故卡住。
三、安装 FRR 并启用 BGP/BFD
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
/etc/frr/frr.conf(示范精简片段,按需扩展):
frr version 8.4
service integrated-vtysh-config
!
hostname hk-core01
!
# BFD
bfd
profile fast
transmit-interval 50
receive-interval 50
echo-mode
detect-multiplier 5
profile fast
!
# 路由策略:本地优先级
route-map PREFER-CN2 permit 10
set local-preference 200
!
route-map PREFER-INTL permit 10
set local-preference 150
!
ip prefix-list DEFAULT_ONLY seq 5 permit 0.0.0.0/0
!
# eBGP to 上游A(CN2)
router bgp 65001
bgp router-id 203.0.200.10
no bgp ebgp-requires-policy
timers bgp 10 30
neighbor 203.0.113.1 remote-as 4809 # 示例 AS
neighbor 203.0.113.1 description CN2
neighbor 203.0.113.1 bfd profile fast
neighbor 203.0.113.1 timers 5 15
address-family ipv4 unicast
neighbor 203.0.113.1 route-map PREFER-CN2 in
neighbor 203.0.113.1 prefix-list DEFAULT_ONLY in
network 203.0.200.0/28
exit-address-family
!
# eBGP to 上游B(国际)
router bgp 65001
neighbor 198.51.100.1 remote-as 2914 # 示例 AS
neighbor 198.51.100.1 description INTL
neighbor 198.51.100.1 bfd profile fast
neighbor 198.51.100.1 timers 5 15
address-family ipv4 unicast
neighbor 198.51.100.1 route-map PREFER-INTL in
neighbor 198.51.100.1 prefix-list DEFAULT_ONLY in
network 203.0.200.0/28
exit-address-family
!
line vty
!
要点
- 只收 默认路由(省内存且干净),把入向 local-pref分开,CN2 高于国际。
- BFD 秒级感知链路失效。
- 用 network 203.0.200.0/28 对外发布业务前缀,让上游 A/B 都能打到你。
- 若上游支持 BGP Community 控制入向(如优先走 CN2),询问其社区值并在出向加标签(本文不赘述厂商值,和对方确认为准)。
四、把大陆流量“固定走 CN2”,其他走国际
1)生成中国大陆前缀表 → ipset
获取 APNIC 中国前缀并写入 ipset:
mkdir -p /opt/china-route && cd /opt/china-route
curl -s https://ispip.clang.cn/all_cn.txt -o cn_prefix.txt # 也可用 apnic/17mon 源
ipset create CHINA hash:net -exist
while read pfx; do ipset add CHINA $pfx -exist; done < cn_prefix.txt
生产环境请做 每日定时更新,更新后重建路由策略(systemd timer + 脚本)。
2)基于 nftables 打标 → ip rule 分流
/etc/nftables.conf(关键片段):
table inet filter {
chains ...
}
table inet mangle {
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
# ERP 业务优先打标(即便不是中国来源)
tcp dport {443,8443,9443} meta mark set 0x10
# 中国大陆目的地分流(出方向)
ip daddr @china dst mark set 0x20
}
set china {
type ipv4_addr; flags interval;
}
}
# MSS Clamping(防 MTU 陷阱)
table ip mangle {
chain forward {
type filter hook forward priority mangle; policy accept;
tcp flags syn / syn tcp option maxseg size set rt mtu
}
}
把 cn_prefix.txt 内容载入 nft set(可借助 nft -f 或脚本转换),随后创建 两个路由表:
/etc/iproute2/rt_tables 增加:
100 cn2
200 intl
给两张表各设默认出路:
ip route add default via 203.0.113.1 dev eno1 table cn2
ip route add default via 198.51.100.1 dev eno2 table intl
# 打了 0x20 的包走 cn2 表;没打标的默认走 intl
ip rule add fwmark 0x20 table cn2
ip rule add priority 1000 table intl
效果
- 大陆目的地 → 走 eno1(CN2)。
- 其他 → 走 eno2(国际)。
- ERP 端口被打了更高优先级标记,后续 QoS 会保证它不被抢带宽。
五、把 25M CN2 用对:带宽整形 + 业务优先
CN2 只有 25M commit,白天一拥而上就会拥塞。我们用 HTB + fq_codel 做类 CBQ 策略:
# CN2 出口整形在 eno1,汇聚带宽 25M
tc qdisc add dev eno1 root handle 1: htb default 30
tc class add dev eno1 parent 1: classid 1:1 htb rate 25mbit ceil 25mbit
# 业务优先(ERP)
tc class add dev eno1 parent 1:1 classid 1:10 htb rate 8mbit ceil 25mbit prio 0
tc qdisc add dev eno1 parent 1:10 fq_codel
# 常规(中国方向的其他)
tc class add dev eno1 parent 1:1 classid 1:30 htb rate 5mbit ceil 17mbit prio 1
tc qdisc add dev eno1 parent 1:30 fq_codel
# 把标记为 0x10(ERP)的流量打到高优先级队列
tc filter add dev eno1 protocol ip parent 1:0 prio 1 handle 0x10 fw flowid 1:10
经验:先给 ERP 保底 6–10M,峰值可吃满 25M;普通中国流量做“有上限的弹性”。这样月底对账、白天审批最有感知。
六、TCP 栈与内核优化(务实可控)
/etc/sysctl.d/99-net-tune.conf
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_window_scaling = 1
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.ip_forward = 1
net.ipv4.conf.all.rp_filter = 2 # loose uRPF
net.ipv4.conf.default.rp_filter = 2
sysctl --system
七、健康检查与“自我修复”
1)黑盒探针(跨省)+ 动态本地优先级
用 Blackbox Exporter 对 华东/华南/华北 的探针点定时 https://erp.example.com/healthz,若某区域 CN2 抖动/丢包上升,脚本自动把 CN2 的 local-pref 暂降,临时让国际线接盘。脚本示例(思路):
#!/usr/bin/env bash
set -euo pipefail
LOSS=$(curl -s http://blackbox.local/api/v1/query?query=probe_success{target="erp-cn2-suzhou"} | jq '.data.result[0].value[1]' | tr -d '"')
if [ "$LOSS" != "1" ]; then
echo "CN2 Suz loss, lower pref"
vtysh -c 'configure terminal' \
-c 'route-map PREFER-CN2 permit 10' \
-c 'set local-preference 120' \
-c 'end' \
-c 'write mem'
else
# 恢复
vtysh -c 'configure terminal' \
-c 'route-map PREFER-CN2 permit 10' \
-c 'set local-preference 200' \
-c 'end' \
-c 'write mem'
fi
2)BFD + FRR 日志告警
BFD 掉线 5×50ms 即感知,Prometheus 抓 syslog,Grafana 告警飞书/Slack 直达。
八、观测:我如何确认“真的更快了”
1)基线与对比(实测值)
| 地区 | 优化前(ms) | 优化后(ms) | 备注 |
|---|---|---|---|
| 苏州(电信) | 85–120 | 35–45 | 走 CN2 |
| 广州(电信) | 70–95 | 28–38 | 走 CN2 |
| 上海(联通) | 60–80 | 32–45 | 多数仍优选 CN2 路径 |
| 新加坡 | 45–55 | 48–58 | 走国际混线,几乎无变化 |
| 洛杉矶 | 130–160 | 120–140 | 走国际混线,略优 |
工具:smokeping 连 ERP VIP;mtr -rwzc 200 erp.example.com;curl -w 统计 TTFB。
2)带宽使用(白天 10:00–12:00)
| 类目 | 平均 | 峰值 | 策略 |
|---|---|---|---|
| CN2 总出 | 18 Mbps | 25 Mbps | 受 HTB 限顶 |
| 其中 ERP | 9–12 Mbps | 18 Mbps | 高优先级 |
| 其他大陆 | 4–7 Mbps | 10 Mbps | 弹性 |
| 国际出 | 35–60 Mbps | 90 Mbps | 混线承压 |
九、安全防护(入向干净,出向不背锅)
- nftables 过滤:只开放 80/443/9443、VPN 端口(必要时段),限制管理段来源。
- 反射/源地址校验:rp_filter=2 + 上游入向 ACL,拒绝 RFC1918、bogon。
- 速率限制:API 登录/导出接口做 limit_req 或 WAF。
- uRPF loose:配合双宿主避免误杀回程。
- 日志:nft log + rsyslog -> Loki,审计溯源。
十、我踩过的坑 & 你别再踩
- MSS/MTU 不配:CN2 某段实际 MTU < 1500,HTTPS 大文件卡死,抓包看到 Fragmentation needed。解决:nftables 做 MSS clamp,tcp_mtu_probing=1;必要时把上联 MTU 调小到 1492。
- 策略路由不命中:conntrack 的回流走了另一条表。解决:在 prerouting 打标;同时确保 forward/output 场景都有覆盖。
- BFD 被防火墙挡了:上游侧屏蔽 echo。解决:统一双方 profile 与端口开放;不通就降级靠 BGP keepalive。
- FRR 版本差异:7.x 与 8.x 在 route-map 行为、no bgp ebgp-requires-policy 默认不同。解决:固定版本、将差异纳入配置模版。
- CN2 被杂流挤占:白天同事跑备份。解决:HTB 把 ERP 队列优先级拉满,普通流量降权;备份改到凌晨。
- 入向不稳:只做了出向分流,入向仍绕路。解决:与上游确认 Community/MED 策略,必要时做 DNS 分省解析(华东/华南优先 CN2 的 VIP),渐进优化。
十一、关键配置清单(可抄可改)
sysctl(节选)
| Key | Value | 说明 |
|---|---|---|
| net.core.default_qdisc | fq | 配合 BBR |
| net.ipv4.tcp_congestion_control | bbr | 长肥管道友好 |
| net.ipv4.tcp_mtu_probing | 1 | 自探测 PMTU |
| net.ipv4.ip_forward | 1 | 转发必开 |
| net.ipv4.conf.*.rp_filter | 2 | loose uRPF |
FRR(节选)
| 项 | 值 |
|---|---|
| BGP keepalive/hold | 5s / 15s |
| BFD | 50ms × 5 |
| CN2 local-pref | 200(降级时 120) |
| 国际 local-pref | 150 |
十二、验证动作(上线 Checklist)
- show bgp summary 两邻居 Established,show bfd peer Up。
- ip rule/ip route show table cn2|intl 正确。
- nft list ruleset 打标命中(计数器递增)。
- tc -s qdisc/class 可见 ERP 队列在跑。
- smokeping 三省延迟/抖动明显下降。
- 高峰期 ERP TTFB < 200ms(华东/华南),导出报表< 3s。
- 故障演练:拉下 CN2 物理口,BFD < 1s 收敛,国际兜底。
十三、扩展玩法(有余力再做)
- 双机热备:两台服务器跑 FRR + VRRP(keepalived),ERP VIP 漂移,配合 loopback 发布 BGP。
- S2S 加速:对接内地分支的防火墙用 IPsec/GRE 直接入 CN2,绕开复杂 NAT。
- 分省 DNS:华东/华南智能解析到 “偏 CN2 的 VIP”,北方/海外走国际 VIP。
- Netflow/pmacct:精确看到 CN2 被谁打满,优化准星更准。
结尾:第二天的电话
周日早上 8 点,苏州那边的财务总监又来了电话。这次她笑着说:“今天点开单据几乎秒开,导出也快了。你们昨晚做了什么?”
我把 Smokeping 的曲线截图给她看:一夜之间,华东的延迟从 90ms 掉到 35ms 左右,抖动几乎贴地。
我说:“没什么玄学,就是把路由让该走的人走该走的路,把 25M 的 CN2 留给真正该走的人,再给 ERP 多一点尊重。”
机房里风依旧吹着,只是我可以安心把保温杯里的茶喝完了。
附:一键化脚本思路(纲要)
- setup_nic.sh:ethtool/队列/MTU 初始化
- setup_networkd.sh:systemd-networkd 配置模板渲染
- setup_frr.sh:FRR + 路由策略模板(jinja)
- china_ipset_update.sh:每日更新中国前缀 → nft set/ipset
- qos_apply.sh:HTB + fq_codel 应用
- health_pref_adjust.sh:探针联动 local-pref
- validate.sh:BGP/BFD/nft/tc/smokeping 快速体检
如果你也在把 ERP 放在香港、要兼顾大陆与海外,这套“Debian + FRR + 多线 BGP + 策略路由 + 精准 QoS”的组合拳,落地快、可观测、易回滚。按上面的配置一步步做,周一的你,大概率也会接到一个好消息的电话。