自助牵引是攻击打满上联、清洗来不及调度时的最后手段。本文讲清 RTBH 与 Flowspec 的原理差别、community 怎么标、规则怎么发、误封怎么防,以及它和高防牵引到底哪里不同。
Q:RTBH 和 Flowspec 分别是什么?
- RTBH(Remotely Triggered Black Hole,远端触发黑洞):你通过 BGP 把一个前缀的下一跳改成黑洞,运营商在自己网内直接把去往该前缀的流量丢掉。粒度是整个 IP,一旦生效这个 IP 就完全不可达。
- Flowspec(RFC 8955):用 BGP 下发一条带匹配条件的规则,可以按源/目的 IP、端口、协议、包长、TCP 标志匹配,动作可以是丢弃、限速或重定向到指定 VRF。
- 一句话区分:RTBH 是整颗 IP 全丢,Flowspec 是只丢你指定的那部分。
- 两者都属于「运营商侧动作」,跟高防清洗不是一回事。
Q:它和高防牵引有什么区别?
- 高防牵引是把流量引到清洗中心,洗完了再回注给你。站点继续可用,代价是延迟增加、要走商务流程、按规格计费。
- RTBH 是在你的上游直接丢弃。保住的是机房上联和同网段邻居,牺牲的是这个 IP 本身。
- Flowspec 介于两者之间:可以只丢 UDP 洪水,保住 443 上的正常业务,但清洗能力有限,挡不住混合型攻击。
- 顺序上应该是:CDN/WAF 挡七层 → 高防清洗挡四层 → Flowspec 削峰 → RTBH 保命。越往后越粗暴,也越快生效。
Q:什么情况下才需要自助牵引?
- 攻击流量超过清洗规格,清洗中心自己先被打满。这种时候再怎么调阈值都没用,只能在上游先丢。
- 机房按 IP 段整体封禁,同网段其他客户被牵连,服务商要求你自己先处理。
- 纯 UDP 反射放大,占了你 90% 的入向带宽,但业务本身只用 TCP 443。这时候精准丢弃 UDP 就能救回业务,不必整站黑洞。
- 攻击刚开始、清洗调度还要几分钟,先用 Flowspec 顶一下。
- 小站要注意:没有自有 AS 和 IP 段,就发不了 BGP 路由。多数机房和云厂商后台的「黑洞」「封堵」「DDoS 封禁」按钮,本质就是替你做了 RTBH,不需要自己配。
Q:RTBH 的 community 怎么标?
- 通用约定是 65535:666(RFC 7999 定义的 BLACKHOLE community),大部分运营商和机房认这个值。
- 也有大量运营商用自己的私有值,比如 65001:666、65000:9999 这种,必须问服务商要准确值,猜是猜不出来的。
- 部分运营商还支持「掩码长度」community:宣告 /32 表示只黑洞这一颗,宣告大段会被拒。这条限制很重要,它防的就是客户误操作把整个 /24 甚至 /16 打进黑洞。
- 宣告时通常还要加 no-export,别让黑洞路由扩散到你自己的其他上游去。
# 本地验证:先把黑洞路由指向 null0,确认路由表写对了
ip route add blackhole 203.0.113.45/32
# 撤销
ip route del blackhole 203.0.113.45/32
Q:Flowspec 规则怎么发?ExaBGP 配置示例
- ExaBGP 是最常见的开源实现,用文本描述 NLRI 就能发出去,不用自己拼二进制。
neighbor 192.0.2.1 {
router-id 203.0.113.1;
local-address 203.0.113.1;
peer-as 65001;
local-as 65002;
family {
ipv4 flow;
}
flow {
route ddos-udp {
match {
destination 203.0.113.0/24;
protocol =udp;
destination-port =53;
}
then {
discard;
}
}
}
}
- 只丢 DNS 反射、保留 TCP,是实战里性价比最高的一条规则。同理可以只丢 123(NTP)、11211(memcached)、1900(SSDP)。
- 限速动作比丢弃更温和,适合「打的是正常协议,只是量太大」的场景:
flow {
route dns-flood {
match {
destination 203.0.113.45/32;
protocol =udp;
destination-port =53;
}
then {
rate-limit 2000; # 单位按厂商实现,多为 kbps
}
}
}
- 规则要写成模板从外部注入,别硬编码在配置里。攻击发生时改一行配置再 reload,比现场手写快得多。
- 发之前确认对端
family ipv4 flow已经协商成功,没协商上规则会被静默丢弃,而你在自己这边看不出任何报错。
Q:怎么防止误封自己的业务?
- 只对 /32 主机路由操作。哪怕服务商允许你宣告 /24,也别那么干,一次误操作能把整个机柜打下线。
- 规则必须带自动撤销。人一慌就会忘,忘了就是通宵故障:
# 30 分钟后自动撤销,别指望自己记得
at now + 30 minutes <<'EOF'
exabgp_cli announce flow ... withdraw
EOF
# 或者用脚本加时间戳管理,到期统一 withdraw
- 宣告前先核对资产清单:这个 IP 上跑的是什么业务、有没有支付回调、有没有备案、有没有客户白名单在用。回调 IP 被打进黑洞,等于把订单全丢了。
- Flowspec 优先于 RTBH。能精准丢 UDP 就别整站黑洞。
- 加 no-export,不要泄露默认路由。最经典的事故是把 0.0.0.0/0 指到 null0,全公司断网。
- 变更前通知业务方一句话,别让客服在群里问「网站怎么打不开了」而你还在改配置。
Q:牵引生效了怎么验证?
- 三个方向同时看,只看一个容易误判:
- 流量曲线:入向带宽掉到接近零,出向正常,说明入向被上游丢了。如果入向还在,说明规则没生效。
- 连通性:
ping不通、traceroute到某一跳后就没响应,且那一跳在运营商网内。 - 对端确认:让服务商在边界路由器上
show ip bgp 203.0.113.45或show route看一眼,截图给你。这是唯一能证明「规则真的落到设备上」的材料。
# 从异地探针看效果
mtr -rwzbc 20 203.0.113.45
curl -sv --max-time 5 https://203.0.113.45/ -o /dev/null
# 本机看入向流量对比(有黑洞时应归零)
sar -n DEV 1 5 | grep -E 'IFACE|eth0'
- 注意一个假象:CDN 回源也可能让你看到「入向归零」,实际是缓存挡住了,不是黑洞生效。验证时要同时看源站是否还能被公网直连。
Q:Flowspec 和清洗怎么配合最省钱?
- 先在 Flowspec 层做「粗筛」:把 UDP、非常用端口、超大包、碎片包这些明显不是业务流量的先丢掉。这一步不花钱,能削掉一半以上。
- 剩下的引流到清洗中心做精细过滤。清洗设备按规格计费,前面少进去一半,规格就能买小一档。
- 顺序反了就不划算:先清洗再丢,等于让清洗设备替你处理垃圾流量,钱花在最没价值的地方。
- 两种动作要分场景:纯反射放大用 discard;业务协议被洪水淹没(比如你的 DNS 服务真被打)用 rate-limit,保住可用性。
Q:国内小站能用到这些吗?
- 坦率说,多数用不到。Flowspec 要运营商在 PE 上开启并给你授权,普通 IDC 客户拿不到;RTBH 也通常只对自有 AS 的客户开放。
- 但「自助封堵」这个功能几乎所有云厂商和机房都有,页面上的按钮就是 RTBH 的封装。你要做的是提前问清三件事:封堵是整 IP 还是按端口、多久自动解封、一天能操作几次。
- 没有自有 AS 的站,正确路线还是 CDN 挡七层 + 高防挡四层 + 源站 IP 不泄露,把牵引当成对方机房的动作,不指望自己操作。
- 真要上 Flowspec,先跟机房商务确认支持情况,别在攻击当天才发现对端根本没开这个 family。
Q:还有什么补充建议?
- 把「黑洞」当预案里的一个明确按钮,写清谁能按、按之前通知谁、多久撤销。没写进预案的操作,凌晨三点一定做错。
- 演练一次:在测试 IP 上宣告黑洞,验证自动撤销脚本、监控告警、业务通知三条链路是否都通。
- 黑洞不是防护,是止血。它保证的是机房不被拖垮,不保证你的站可用,所以事后一定要回到清洗和架构层面解决。
- 所有牵引操作留记录:时间、操作人、前缀、community、撤销时间。这份记录在跟机房扯皮和算损失时非常有用。