BGP Flowspec 允许你通过 BGP 分发数据流的控制规则,它通过 BGP NLRI 将规则(如源地址,协议号,端口等)分发给激活了 flow address-family 的设备,使网络设备能快速部署针对数据包的防火墙流控规则。正因为 Flowspec 支持该特性,使得调用 BGP Flowspec 来减轻 DDoS 带来的影响成为了可能。
今天我们使用 BGP Flowspec 来实现控制上游的过滤列表来阻止外界访问我们服务器的功能。
拓扑整图:

VFP3 模拟外界访问的用户,VFP4 为我们的上游路由器,VFP9 为我们的边界路由器,Client-B 模拟我们的服务器。
需求:
- 当 DDoS 攻击来临时,边界路由器 ( VFP9 ) 需要通过发送 BGP NLRI 通知上游路由器( VFP4 ) ,上游路由器要根据 BGP NLRI 自动生成过滤列表,并对数据包做丢弃动作。
下面开始对路由器的配置( 基础 IP 配置,OSPF 配置已经配好,生产环境中与eBGP的连接不需要配置 OSPF,实验环境为了之后实验方便预先配置了 OSPF )
由于 BGP Flowspec 是典型的 控制端-被控端 模式,ISP 路由器作为被控端,我方路由器作为控制端,所以 ISP 路由器只需要激活 Flowspec(当然,实际生产环境中要考虑接受路由白名单的问题),剩余的事情如规则下发都需要在我方路由器(CE)上做。
vMX-VFP9(我方CE路由器):
root@CE-B# show
routing-options {
flow {
term-order standard; // 激活 BGP Flowspec,模式为 RFC Standard
}
router-id 10.0.0.3;
}
protocols {
bgp {
group inet-4 {
type internal;
local-address 10.0.0.3;
family inet {
unicast; // 激活 IPv4-Unicast SAFI,传递 IPv4 路由
flow; // 激活 IPv4-Flowspec SAFI,传递 Flowspec 路由
}
local-as 100;
neighbor 10.0.0.2 {
import import;
export export;
peer-as 100;
}
}
}
}
policy-options {
policy-statement export {
term inet-flow-export {
from rib inetflow.0; // 允许 Flowspec 路由出网,路由表为 inetflow.0
then accept;
}
term inet-unicast-export {
from {
rib inet.0;
route-filter 100.64.1.0/24 exact; // 宣告 IPv4 路由
}
then accept;
}
term last {
then reject;
}
}
policy-statement import {
then accept;
}
}
[edit]
vMX-VFP4(ISP PE 上游路由器):
root@R2# show
routing-options {
flow {
term-order standard; // 激活 BGP Flowspec,模式为 RFC Standard
}
router-id 10.0.0.2;
}
protocols {
bgp {
group inet-4 {
type internal;
local-address 10.0.0.2;
cluster 10.0.0.2;
local-as 100;
neighbor 10.0.0.1 {
import all;
export all;
peer-as 100;
}
neighbor 10.0.0.3 {
import all;
family inet {
unicast; // 激活 IPv4-Unicast SAFI,传递/接受 IPv4 路由
flow; // 激活 IPv4-Flowspec SAFI,接受 Flowspec 路由(也可以传递)
}
export all;
peer-as 100;
}
}
}
policy-options {
policy-statement all {
then accept;
}
}
基本的配置已完成,我们来检查下 BGP 邻居的建立情况:
root@CE-B# run show bgp summary
Groups: 1 Peers: 1 Down peers: 0
Table Tot Paths Act Paths Suppressed History Damp State Pending
inet.0
6 1 0 0 0 0
inetflow.0
0 0 0 0 0 0
Peer AS InPkt OutPkt OutQ Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...
10.0.0.2 100 81 77 0 0 33:09 Establ
inet.0: 1/6/5/0
inetflow.0: 0/0/0/0
inet.0 以及 inetflow.0 邻居已经建立起来了,我们首先来模拟从公网服务器访问我们服务器的情况:
root@R1> ping 100.64.1.2 count 3 source 100.64.0.1 PING 100.64.1.2 (100.64.1.2): 56 data bytes 64 bytes from 100.64.1.2: icmp_seq=0 ttl=62 time=563.488 ms 64 bytes from 100.64.1.2: icmp_seq=1 ttl=62 time=173.453 ms 64 bytes from 100.64.1.2: icmp_seq=2 ttl=62 time=370.806 ms --- 100.64.1.2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 173.453/369.249/563.488/159.235 ms root@R1> ssh 100.64.1.2 source 100.64.0.1 The authenticity of host '100.64.1.2 (100.64.1.2)' can't be established. ECDSA key fingerprint is SHA256:UGgeGwcaz0+JMrvB1Sh/DEtay3sc3mTrjJYztLLTtHs. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '100.64.1.2' (ECDSA) to the list of known hosts. root@100.64.1.2's password:
看起来没什么问题,IPv4 路由已经连通了,Ping 以及 SSH 均可成功连通。
现在我们来模拟一种情况:当我们的服务器遭受了大量的针对 SSH 端口的攻击,我们需要发 BGP NLRI 给上游服务器,让上游服务器根据 BGP NLRI 生成对应的防火墙规则来丢弃数据包。这样可以维持原来的链路路径,而且我们还能减少 DDoS 对我们带来的影响。
这种情况,我们需要这样配置:
vMX-VFP9(我方CE路由器)
root@CE-B# show routing-options
flow {
route deny-ssh { // 聚合一条规则,名字定义为 deny-ssh
match { // 匹配协议类型
protocol tcp; // TCP 协议
destination-port 22; // 端口 22 ( SSH 标准端口 )
destination 100.64.1.2/32; // 目标地址 100.64.1.2 (受攻击服务器)
}
then discard; // 动作配置为拒绝
}
term-order standard;
}
配置完成后,我们查看 ISP 的路由表以及防火墙规则:
root@R2> show route table inetflow.0 extensive
inetflow.0: 1 destinations, 1 routes (1 active, 0 holddown, 0 hidden)
100.64.1.2,*,proto=6,dstport=22/term:1 (1 entry, 1 announced)
TSI:
KRT in dfwd;
Action(s): discard,count
*BGP Preference: 170/-101
Next hop type: Fictitious, Next hop index: 0
Address: 0xa1d9dbc
Next-hop reference count: 1
Next hop:
State: <Active Int Ext>
Peer AS: 100
Age: 2:28
Validation State: unverified
Task: BGP_100_100.10.0.0.3+179
Announcement bits (1): 0-Flow
AS path: I
Communities: traffic-rate:0:0
Accepted
Localpref: 100
Router ID: 10.0.0.3
root@R2> show firewall filter __flowspec_default_inet__
Filter: __flowspec_default_inet__
Counters:
Name Bytes Packets
100.64.1.2,*,proto=6,dstport=22 0 0
可见 ISP 的路由表已经收到了 BGP 发过来的 Flowspec 规则,且已经将其安装至防火墙中。我们再来模拟测试一下从公网访问我们服务器的 SSH 端口:
root@R1> ping 100.64.1.2 count 3 source 100.64.0.1 PING 100.64.1.2 (100.64.1.2): 56 data bytes 64 bytes from 100.64.1.2: icmp_seq=0 ttl=62 time=11.102 ms 64 bytes from 100.64.1.2: icmp_seq=1 ttl=62 time=7.364 ms 64 bytes from 100.64.1.2: icmp_seq=2 ttl=62 time=332.472 ms --- 100.64.1.2 ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max/stddev = 7.364/116.979/332.472/152.384 ms root@R1> ssh 100.64.1.2 source 100.64.0.1 ssh: connect to host 100.64.1.2 port 22: Operation timed out
再来检查 ISP 路由器的防火墙规则:
root@R2> show firewall filter __flowspec_default_inet__ Filter: __flowspec_default_inet__ Counters: Name Bytes Packets 100.64.1.2,*,proto=6,dstport=22 432 8
我们可以很清楚的看到针对服务器 100.64.1.2 的 TCP 22 端口包被丢弃,且产生了记录,并且 ICMP 报文未受影响。
我们再来测试,模拟受到 ICMP flood 攻击而屏蔽 ICMP 的现象(放行 TCP,阻止 ICMP ):
vMX-VFP9(我方CE路由器)
root@CE-B# show
inactive: route deny-ssh {
match {
protocol tcp;
destination-port 22;
destination 100.64.1.2/32;
}
then discard;
}
route deny-icmp {
match {
protocol icmp;
icmp-type [ 0 8 ];
}
then discard;
}
term-order standard;
再模拟从公网服务器进行访问测试:
root@R1> ping 100.64.1.2 count 3 source 100.64.0.1 PING 100.64.1.2 (100.64.1.2): 56 data bytes --- 100.64.1.2 ping statistics --- 3 packets transmitted, 0 packets received, 100% packet loss root@R1> ssh 100.64.1.2 source 100.64.0.1 root@100.64.1.2's password: Permission denied, please try again. root@100.64.1.2's password:
再来检查 ISP 的防火墙规则:
root@R2> show firewall filter __flowspec_default_inet__ Filter: __flowspec_default_inet__ Counters: Name Bytes Packets *,*,proto=1,icmp-type=0,=8 252 3
可以清楚的观察到测试用的3个 ICMP 报文均被丢弃,实验成功。
总结:
- 由于 BGP Flowspec 是典型的 控制端-被控端 模式,所以所有被控端都要激活 Flowspec 功能,并与控制端建立 BGP 连接( 通过 RR 也可以,但是 RR 不要安装收到的规则 ),所有规则下发操作全部在控制端上做。
- 生产环境中给客户提供该服务,要注意接受路由白名单的编写,不要影响到其他客户。