MENU

RouterOS+Fastnetmon 全自动BGP路由黑洞

June 12, 2020 • Read: 4784 • BGP阅读设置

继BGP速成班后...已经有好几个月想不出新教程...因为本菜鸡的水平实在提升的太慢 ...
总算经过一番大脑升级之后, 达成了大神们3年前就已经实现的全自动黑洞路由系统...
那么3年前的东西, 现在难道没淘汰 ? 完全木有 , Working like a charm !

主要参考文章:
1 https://zhu.vn/archives/1966
2 https://blog.remontti.com.br/3981


前言 :

自己起BGP , 有什么好处 ?
有小伙伴肯定会说 , 把路由拉直 , 乱写WHOIS看Netflix用...你们啊 NAIVE !
安全生产在各行各业都是最重要的一环 !
本文将重走大神们的老路. 针对萌新转化为"EASY"版 , 并用实战案例更方便理解 .

如上一篇 BGP PLAYER 1小时速成班所说 : https://ccav.me/bgplayer-in-1hour.html
大型实战试验场 , 肯定是 VULTR , 没有比他更新手 Friendly了 .


本次爆炸实验所需材料 :

VPS1 RouterOS CHR 6.45.8-6.45.9
VPS2 Ubuntu 16.04 安装 Fastnetmon + Exabgp , 选装 Grafana + Influxdb 提升B格 .

Vultr 请用相同 Region, 2台同时开启 Private IP , 放在同一个段内 , 根据说明书手工配置网卡 , 打通内网.
https://www.vultr.com/docs/configuring-private-network

实验流程图 :
idlzbe2g0or9.png

新手最想不通的一点 :
ROS如何把流量数据传给 Fastnetmon , 接着如何发送黑洞路由给 ROS .
Pig God 写的文章本菜鸡2019年就看了 , 然而以上问题我是恶补了1年的基础知识才想通 ...
ROS下 : /ip traffic-flow 这个就是输出流量数据的工具
1sqvgvqa0ucl.png
然后Setting建议无脑根据本图设定 , 这样输出数据最精准.
接下来是 Traffic Flow Targets : Src 填ROS内网IP , Dst 显然就是你另一台VPS的内网IP . 其它照填 .

接下来我们在 ubuntu的VPS上首先安装Fastnetmon

apt-get install build-essential tcptraceroute socat python-pip traceroute curl -y
wget https://raw.githubusercontent.com/pavel-odintsov/fastnetmon/master/src/fastnetmon_install.pl -Ofastnetmon_install.pl 
perl fastnetmon_install.pl

后编辑 /etc/fastnetmon.conf

# Netflow capture method with v5, v9 and IPFIX support
netflow = on
# it's possible to specify multiple ports here, using commas as delimiter
netflow_port = 2055
netflow_host = 0.0.0.0

编辑 /etc/networks_list
把你BGP广播的 IP段写进去 比如 103.114.0.0/24

运行 service fastnetmon start , 再运行 /opt/fastnetmon/fastnetmon_client
看的到有每个IP的流量,说明第一步完成无误 .
0zkatz4bygeq.png

接下来安装exabgp :
pip install exabgp==3.4.20

使用巴西大神写的简易systemctl控制脚本 :

vim /etc/init.d/exabgp

#!/bin/bash
### BEGIN INIT INFO
# Provides:          exabgp
# Required-Start:    $all
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:
### END INIT INFO

VERMELHO='\033[1;31m'
VERDE='\033[1;32m'
NC='\033[0m'

PROCESSO=$(ps -x |grep -v "grep" |grep -v "/bin/bash" |grep exabgp |wc -l); 

function startExaBGP(){
    if [  $PROCESSO -eq 0 ]
    then
        echo "Iniciandos...";
        env exabgp.daemon.user=root \
          exabgp.daemon.daemonize=true \
          exabgp.daemon.pid=/var/run/exabgp.pid \
          exabgp.log.destination=/var/log/exabgp.log \
          exabgp /etc/exabgp.conf
        sleep 0.3
        echo -e "ExaBGP [${VERDE} Iniciado ${NC}] ";
    else
        echo -e "ExaBGP já exstá em execuxão. [${VERDE} Ativo ${NC}] ";
    fi
}

function stopExaBGP(){
    if [  $PROCESSO -eq 0 ]
    then
        echo -e "ExaBGP não está sendo executado. [${VERMELHO} Parado ${NC}]";

    else 
        echo "Parando...";
        kill -9 `cat /var/run/exabgp.pid` &>/dev/null
        echo -e "ExaBGP [${VERMELHO} Parado ${NC}] ";
    fi
}

function statusExaBGP(){
    if [  $PROCESSO -eq 0 ]
    then
        echo -e "ExaBGP está [${VERMELHO} Parado ${NC}]";
    else 
        echo -e "ExaBGP está [${VERDE} Ativo ${NC}]";
    fi
    echo 
    echo "Logs:"
    tail /var/log/exabgp.log
}

case "$1" in
    start )
        startExaBGP
        ;;

    stop )
        stopExaBGP
        ;;

    restart )
        stopExaBGP
        sleep 1
        startExaBGP
        ;;

    status )
        statusExaBGP      
        ;;

    * )
        echo "Opção inválida, use start | stop | restart | status"
        ;;
esac

chmod a+x /etc/init.d/exabgp

vim /lib/systemd/system/exabgp.service

[Unit]
Description=ExaBGP
After=network.target remote-fs.target

[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/etc/init.d/exabgp start
ExecStop=/etc/init.d/exabgp stop
ExecReload=/etc/init.d/exabgp restart

[Install]
WantedBy=multi-user.target

systemctl daemon-reload
systemctl enable exabgp

vim /etc/exabgp.conf

group fastnetmon {
local-as YOUR-AS-NUMBER;
peer-as YOUR-AS-NUMBER;

neighbor ROS内网IP { 
local-address 本地内网IP;
family {
            ipv4 unicast;
            ipv6 unicast;
        }
}
process service-dynamic {
run /usr/bin/socat stdout pipe:/var/run/exabgp.cmd;
}
}

到了这一步最好重启一下VPS , 然后开始配ROS的 BGP.


本文大大降低难度, 不起私有AS号 . 直接2台VPS用现有的AS号起IBGP.

首先新建两条 Filter Rules:

/routing filter
add action=accept chain=FastNetMon-IN set-type=blackhole
add action=discard chain=FastNetMon-OUT

之后利用你现有的 BGP instance 两端用相同的AS号起 IBGP ~
那么 IBGP 的多跳这里别忘记打勾 !
FILTER 选刚才建好的那2个 :
4ma1j81o5bmy.png

BGP State 显示 established 之后我们进入 Fastnetmon 详细参数配置 .
又要编辑 /etc/fastnetmon.conf 了 , 之后你还有得好编辑他了 , 每做一步编辑一次 , 不要浪 !

# Enable/Disable any actions in case of attack
enable_ban = on
# How long (in seconds) we should keep an IP in blocked state
# If you set 0 here it completely disables unban capability
ban_time = 1900
# Different approaches to attack detection
ban_for_pps = off
ban_for_bandwidth = on
ban_for_flows = off
# Limits for Dos/DDoS attacks
threshold_mbps = 900
# announce blocked IPs with BGP protocol with ExaBGP
exabgp = on
# specify different communities for host and subnet announces
#  next_hop 填你内网网卡的IP
exabgp_next_hop = 10.25.96.3
# Announce /32 host itself with BGP
exabgp_announce_host = on
# Announce origin subnet of IP address instead IP itself
exabgp_announce_whole_subnet = off

解释一下部分参数 : ban_time 按照秒来算 , 时间到了 IP解封 , 这个看你心情设定 .
通过哪种计量单位来ban , 我们只开启 ban_for_bandwidth , 这就足够了.
threshold_mbps = 900 以上 , 通常被出问题来的必然被打满 . 10G口的建议调的更高 .
注意 : 这是单个/32 IP得到的量 ,不是所有IP的总量 ...

那么我们先用 ROS 自带的 bandwidth test 来测一发速模拟一下DDOS流量
threshold_mbps = 300 即可
配完之后service fastnetmon restart 进行暴力测速(超过设定的300)

打开你的 ROS /ip route
然后你会发现你的路由表里多了一条从 IBGP 传过来的 /32路由
meo4t93xgw52.png
自带 BGP Local Pref. 100 属性 , 我们接下来利用这个特点把他转化为黑洞路由发往公网 .

来到了当初速成班提到的防止路由泄露 Filter要做好的地方 , 新建一条, 编辑完成后放在0号位最优先.
Chain : 自己起BGP 允许拨出去的IP 相同的 Chain 即可
Prefix Length 输入 32 , 黑洞路由都是 一个一个IP发的 .
2da3cl2vcqt3.png
那么这个IP还有什么特点呢 ?
是从 IBGP 发过来的 , 以及 Local Pref. 100 .
93qxsyor5tez.png
之后 Actions 选项果断 accept 就不截图了 .
BGP Actions 我们要给他打上 Vultr 的黑洞社区标签 .
q8z4nbfphhnp.png

最后当然要验证一下路由到底有没有发出去 .
看到 BGP Advertisements 里有这条 /32路由 ,且附带了 黑洞社区标签那么基本OK了.
当然自己最好本地 traceroute一发确保路由空了 .
ew7ku9kcz4k5.png


补充知识要点 :

我们仔细看一下 fastnetmon.conf 之后可以发现它控制 exabgp 发路由实际上通过的是/var/run/exabgp.cmd这个脚本.
那么有的情况下 , fastnetmon 被重启了 , 之前被BAN的 IP的就永远不会被解封了 - -...这是一个缺点.
解决方法有两种 , 重启 exabgp , 那么所有被封的IP全部解封.
人工运行一下 exabgp.cmd 单独解封IP :

echo "withdraw route 被封IP next-hop 内网IP"  > /var/run/exabgp.cmd


最后一步我们要通知自己被D爆以及在群里分享爆炸的喜悦 ~

利用这个脚本即可:
https://github.com/halbebruno/fastnetmon-telegram/blob/master/telegram_notify_about_attack.sh
把他保存在 /usr/local/bin/notify_about_attack.sh
修改完成后别忘记添加权限 chmod a+x /usr/local/bin/notify_about_attack.sh

Telegram Bot使用教程 :
https://www.91yunbbs.com/discussion/633
注意一下 userid 之前有一个 "-" 千万别忘记填上 .
作者的变量写的是 : bot$KEY , 那么记得别多写一个bot上去.

于是效果如下 :
w3rct4z9qxyw.png


要点已经木有了 , 接下来是提升B格的部分 ~ 纯属SHOW 给小伙伴们看 .

请全程参考以下文章 :
https://ccav.me/fastnetmon-grafana-monitoring-network-traffic-and-ddos-early-warning.html
https://forum.mikrotik.com/viewtopic.php?t=124958

根据文章安装配置 Grafana 和 Influxdb 后 ,
这里的要点就是编辑 /etc/fastnetmon.conf 中如下字段

graphite = on
graphite_host = 127.0.0.1
graphite_port = 2003
graphite_prefix = fastnetmon

作用是把 Fastnetmon 的数据能写入 InfluxDB 数据库 ...
最后通过 Grafana 来读取 InfluxDB中的数据 ...

Grafana添加DB :
在Configuration - Data sources选项里 ,添加一个 InfluxDB接口,基本上都是默认参数即可.
8n4k38vkfnj1.png

导入控制台模板 :
选择 Create - Import 选项卡 输入 7378 , 即可导入下面这个控制台
https://grafana.com/grafana/dashboards/7378

导入之后会发现最底下的 Top incoming / Out Going By Subnet 都没办法用.
经查这些面板默认查询数据库中 "networks"表 , 然而我们这个是 ROS导入的数据 , 所以要改成 "total"这个表.
截图里的位置,修改一下 , 这个功能就复活了 .
8l2gxmnz7zac.png

成品效果图 :
pexdjmhphmak.jpg
y0gfwcxcynlw.jpg

于是整个实验按照流程图全部完成了 ~
新一轮的爆炸实验正在酝酿中 - -!

2020/6/11

本文经作者 @Drcai 授权转载
转载自 https://www.91yunbbs.com/discussion/641

Archives QR Code
QR Code for this page
Tipping QR Code