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 不要安装收到的规则 ),所有规则下发操作全部在控制端上做。
- 生产环境中给客户提供该服务,要注意接受路由白名单的编写,不要影响到其他客户。