FastNetMon与MikroTik集成(DDoS检测系統)

By hack520 on

背景
從事IDC行業經常會遇到DDoS攻擊,一般用以下解決辦法處理,即:

  • NULL路由
  • 一堆金盾用帶寬硬撐
  • 切路由到國外清洗(Voxility&incapsula)
  • 等死

不過沒關係,只要有自己的AS和IP,還有線路,完全可以避免這些事情發生。(前提自己得有一些底蘊,只有10把20M這些只有死路一條。)

首先,先準備一只VPS,配置大概如下:

雙核,2G 內存,40G 硬盤,帶寬無所謂,最好和你的路由在同機房,否則因為延遲大的原因可能會產生一些奇怪的事情。

1.-安装组件和配置基础知识
1.1.- FastNetMon

wget https://raw.githubusercontent.com/pavel-odintsov/fastnetmon/master/src/fastnetmon_install.pl -Ofastnetmon_install.pl 
sudo perl fastnetmon_install.pl

慢慢等它就完成了…傳送門點這裡看完整安裝教學。

安裝完畢之後,首先要進行一些操作.

/etc/networks_list

/etc/networks_whitelist

這2個文件,一個是需要監測的prefix列表,一個是白名單列表.沒有就自己創建個。例如我們的prefix 是1.1.1.0/24 和2.2.2.0/24,直接vi /etc/networks_list

1.1.1.0/24
2.2.2.0/24

加白名單的話,操作一樣,IP後面要按照CIDR的格式寫,例如1.1.1.1/32。

2.- 配置路由

首先要確定一下,路由的哪個接口是主要流量通過的,

/ip traffic-flow
set active-flow-timeout=1m cache-entries=1k enabled=yes interfaces=bonding1
/ip traffic-flow target
add dst-address=10.110.100.114(FastNetMon IP) port=1234

然後就是設置fastnetmon的配置文件,以下是我的配置:

###
### Main configuration params
###

### Logging configuration

# enable this option if you want to send logs to local syslog facility
logging:local_syslog_logging = off

# enable this option if you want to send logs to a remote syslog server via UDP
logging:remote_syslog_logging = off

# specify a custom server and port for remote logging
logging:remote_syslog_server = 10.10.10.10
logging:remote_syslog_port = 514

# Enable/Disable any actions in case of attack
enable_ban = on

# disable processing for certain direction of traffic
process_incoming_traffic = on
process_outgoing_traffic = off

# How many packets will be collected from attack traffic
ban_details_records_count = 500

# How long (in seconds) we should keep an IP in blocked state
# If you set 0 here it completely disables unban capability
ban_time = 3600

# Check if the attack is still active, before triggering an unban callback with this option
# If the attack is still active, check each run of the unban watchdog
unban_only_if_attack_finished = on

# enable per subnet speed meters
# For each subnet, list track speed in bps and pps for both directions
enable_subnet_counters = off

# list of all your networks in CIDR format
networks_list_path = /etc/networks_list

# list networks in CIDR format which will be not monitored for attacks
white_list_path = /etc/networks_whitelist

# redraw period for client's screen
check_period = 1

# Connection tracking is very useful for attack detection because it provides huge amounts of information,
# but it's very CPU intensive and not recommended in big networks
enable_connection_tracking = off

# Different approaches to attack detection
ban_for_pps = off
ban_for_bandwidth = on
ban_for_flows = off

# Limits for Dos/DDoS attacks
threshold_pps = 20000
threshold_mbps = 350
threshold_flows = 3500

# Per protocol attack thresholds
# We don't implement per protocol flow limits, sorry 🙁
# These limits should be smaller than global pps/mbps limits

threshold_tcp_mbps = 100000
threshold_udp_mbps = 100000
threshold_icmp_mbps = 100000

threshold_tcp_pps = 100000
threshold_udp_pps = 100000
threshold_icmp_pps = 100000

ban_for_tcp_bandwidth = off
ban_for_udp_bandwidth = off
ban_for_icmp_bandwidth = off

ban_for_tcp_pps = off 
ban_for_udp_pps = off
ban_for_icmp_pps = off

###
### Traffic capture methods
###

# PF_RING traffic capture, fast enough but the wirespeed version needs a paid license
mirror = off

# Port mirroring sample rate
pfring_sampling_ratio = 1

# Netmap traffic capture (very fast but needs patched drivers)
mirror_netmap = off

# SnabbSwitch traffic capture
mirror_snabbswitch = off

# AF_PACKET capture engine
# Please use it only with modern Linux kernels (3.6 and more)
# And please install birq for irq ditribution over cores
mirror_afpacket = off

# use PCI-e addresses here instead of OS device names. You can find them in "lspci" output
interfaces = eth0,eth1

# Port mirroring sampling ratio
netmap_sampling_ratio = 1

# This option should be enabled if you are using Juniper with mirroring of the first X bytes of packet: maximum-packet-length 110;
netmap_read_packet_length_from_ip_header = off

# Pcap mode, very slow and thus not suitable for production
pcap = off
# Netflow capture method with v5, v9 and IPFIX support
netflow = on
# sFLOW capture suitable for switches
sflow = off

# PF_RING configuration
# If you have a license for PF_RING ZC, enable this mode and it might achieve wire speed for 10GE
enable_pf_ring_zc_mode = off

# Configuration for netmap, mirror, pcap modes
# For pcap and PF_RING we could specify "any"
# For netmap and PF_RING we could specify multiple interfaces = eth0,eth1
interfaces = eth0,eth1

# We use average values for traffic speed to certain IP and we calculate average over this time slice
average_calculation_time = 1

# We use average values for traffic speed for subnet and we calculate average over this time slice
average_calculation_time_for_subnets = 20

# Netflow configuration

# it's possible to specify multiple ports here, using commas as delimiter
netflow_port = 1234
netflow_host = 0.0.0.0

# To bind to all interfaces = eth0,eth1
# To bind to all interfaces = eth0,eth1
# To bind to localhost for a specific protocol:      ::1 or 127.0.0.1

# Netflow v9 and IPFIX agents use different and very complex approaches for notifying about sample ratio
# Here you could specify a sampling ratio for all this agents
# For NetFLOW v5 we extract sampling ratio from packets directely and this option not used
netflow_sampling_ratio = 1

# In some cases with NetFlow we could get huge bursts related to aggregated data nature
# We could try to get smoother data with this option, i.e. we will divide counters on collection interval time
netflow_divide_counters_on_interval_length = off

# Process each netflow packet with LUA
# This option is not default and you need build it additionally
# netflow_lua_hooks_path = /usr/src/fastnetmon/src/netflow_hooks.lua

# sFLOW configuration

# It's possible to specify multiple ports here, using commas as delimiter
sflow_port = 6343
# sflow_port = 6343,6344
sflow_host = 0.0.0.0

# process each sFLOW packet with LUA
# This option is not default and you need build it additionally
# sflow_lua_hooks_path = /usr/src/fastnetmon/src/sflow_hooks.lua

###
### Actions when attack detected
###

# This script executed for ban, unban and attack detail collection
notify_script_path = /usr/local/bin/notify_about_attack.py

# pass attack details to notify_script via stdin
# Pass details only in case of "ban" call
# No details will be passed for "unban" call
notify_script_pass_details = on

# collect a full dump of the attack with full payload in pcap compatible format
collect_attack_pcap_dumps = off

# Execute Deep Packet Inspection on captured PCAP packets
process_pcap_attack_dumps_with_dpi = off

# Save attack details to Redis
redis_enabled = off

# Redis configuration
redis_port = 6379
redis_host = 127.0.0.1

# specify a custom prefix here
redis_prefix = mydc1

# We could store attack information to MongoDB
mongodb_enabled = off
mongodb_host = localhost
mongodb_port = 27017
mongodb_database_name = fastnetmon

# If you are using PF_RING non ZC version you could block traffic on host with hardware filters
# Please be aware! We can not remove blocks with this action plugin
pfring_hardware_filters_enabled = off

# announce blocked IPs with BGP protocol with ExaBGP
exabgp = off
exabgp_command_pipe = /var/run/exabgp.cmd
exabgp_community = xxxx:666 #上游的黑洞社區,其實不寫也行的。只要路由設置好/32 發到上游黑洞即可。

# specify multiple communities with this syntax:
# exabgp_community = [65001:666 65001:777]

# specify different communities for host and subnet announces
# exabgp_community_subnet = 65001:667
# exabgp_community_host = 65001:668

exabgp_next_hop = 192.0.2.1

# In complex cases you could have both options enabled and announce host and subnet simultaneously

# Announce /32 host itself with BGP
exabgp_announce_host = on

# Announce origin subnet of IP address instead IP itself
exabgp_announce_whole_subnet = off

# Announce Flow Spec rules when we could detect certain attack type
# Please we aware! Flow Spec announce triggered when we collect some details about attack,
# i.e. when we call attack_details script
# Please disable exabgp_announce_host and exabgp_announce_whole_subnet if you want to use this feature
# Please use ExaBGP v4 only (Git version), for more details: https://github.com/FastVPSEestiOu/fastnetmon/blob/master/docs/BGP_FLOW_SPEC.md
exabgp_flow_spec_announces = off

# GoBGP intergation
gobgp = off
gobgp_next_hop = 0.0.0.0
gobgp_announce_host = on
gobgp_announce_whole_subnet = off

# Graphite monitoring
# InfluxDB is also supported, please check our reference:
# https://github.com/FastVPSEestiOu/fastnetmon/blob/master/docs/INFLUXDB_INTEGRATION.md
graphite = off
graphite_host = 127.0.0.1
graphite_port = 2003

# Default namespace for Graphite data
graphite_prefix = fastnetmon

# Add local IP addresses and aliases to monitoring list
# Works only for Linux
monitor_local_ip_addresses = on

# Create group of hosts with non-standard thresholds
# You should create this group before (in configuration file) specifying any limits
hostgroup = my_hosts:10.10.10.221/32,10.10.10.222/32

# Configure this group
my_hosts_enable_ban = off

my_hosts_ban_for_pps = off
my_hosts_ban_for_bandwidth = off
my_hosts_ban_for_flows = off

my_hosts_threshold_pps = 20000
my_hosts_threshold_mbps = 1000
my_hosts_threshold_flows = 3500

# Path to pid file for checking "if another copy of tool is running", it's useful when you run multiple instances of tool
pid_path = /var/run/fastnetmon.pid

# Path to file where we store information for fastnetmon_client
cli_stats_file_path = /tmp/fastnetmon.dat

# Enable gRPC api (required for fastnetmon_api_client tool)
enable_api = off

###
### Client configuration
###

# Field used for sorting in client, valid values are: packets, bytes or flows
sort_parameter = packets
# How much IPs will be listed for incoming and outgoing channel eaters
max_ips_in_list = 7

主要的參數講解下,

ban_for_bandwidth = on #只監測帶寬,不監測pps 和flows,因為這個閾值很不好調節,有些幷發高的服務器就...
process_incoming_traffic = on
process_outgoing_traffic = off #對於DDoS攻擊,我們更關心的是入向流量.
average_calculation_time = 1 #設置1秒可以在3秒內監測到DDoS并往上游發黑洞.

設置好之後,啟動FastNetMon 服務

service fastnetmon start
并把/opt/fastnetmon/fastnetmon --daemonize 添加到/etc/rc.local

此時你會看到路由的filow有數據正在流動…

[admin@HKG_BGP] /ip traffic-flow> monitor      
     finished-flows: 3563877950
       active-flows: 1023
  unmanaged-packets: 0
    unmanaged-bytes: 0
-- [Q quit|D dump|C-z pause]

在fastnetmon VPS 上執行

/opt/fastnetmon/fastnetmon_client

如果之前的配置無誤的話,你會看到這樣的顯示…

FastNetMon 1.1.3 master git-94f4947e87753b8be193ca54d17dac24cac599fb Pavel Odintsov: stableit.ru
IPs ordered by: packets
Incoming traffic         34023 pps     22 mbps      0 flows
1.1.1.1            30118 pps     16 mbps      0 flows
1.1.1.2              547 pps      0 mbps      0 flows
1.1.1.3             307 pps      1 mbps      0 flows


Outgoing traffic             0 pps      0 mbps      0 flows
Internal traffic             1 pps      0 mbps

Other traffic             1907 pps      9 mbps

Screen updated in:              0 sec 188 microseconds
Traffic calculated in:          0 sec 283 microseconds
Total amount of IPv6 packets related to our own network: 0
Not processed packets: 0 pps

此時,fastnetmon 的工作已經完成.

3.-對接黑洞路由

3.1.- FastNetMon部分

FastNetMon VPS 機器執行以下操作安裝Bird.

yum install bird -y

安裝好后設定一下,我直接貼出我的配置

router id 10.110.100.114; 

protocol kernel {
  scan time 60;
  import all;
}

protocol device {
  scan time 60;
}

function isnt_blackhole () {
  if proto != "static_blackhole" then return true;
  if net.len != 32 then return true;

  return false;
}

protocol static static_blackhole {
  include "/etc/bird/blackhole4/*.blackhole";
}


protocol bgp bgp_pig_hk {
  local as 你的AS號;

  neighbor 10.111.113.89(路由IP) as 你的AS號;
  source address 10.110.100.114;

  export filter {
    if isnt_blackhole() then reject;
    accept;
  };
  import none;

  multihop 2;
  graceful restart on;
};

3.2.-Mikrotik 部分

#設置黑洞BGP過濾器
/routing filter 
add action=accept chain=BGP-BH-IN prefix-length=32 #只收FNM機發來的/32,也就是單個IP..
add action=discard chain=BGP-BH-OUT
#設置上游黑洞過濾器
/routing filter
add action=accept append-bgp-communities=xxxx:666(黑洞社區自己找上游拿) chain=BGP-Pig-OUT  prefix-length=32 set-type=blackhole
#建立黑洞BGP Peer
/routing bgp peer
add in-filter=BGP-BH-IN multihop=yes name=BGP-BH out-filter=BGP-BH-OUT remote-address=10.110.100.114 remote-as=你的AS route-reflect=yes ttl=default

操作完全正確的話,你會看到黑洞BGP 已經UP.
[admin@HKG_BGP] /routing bgp peer> /routing bgp peer print detail status where name=BGP-BH
Flags: X - disabled, E - established 
 0 E name="BGP-BH" instance=default remote-address=10.110.100.114 remote-as=xxoxx tcp-md5-key="" nexthop-choice=default multihop=yes route-reflect=yes hold-time=3m ttl=default 
     in-filter=BGP-BH-IN out-filter=BGP-BH-OUT address-families=ip default-originate=never remove-private-as=no as-override=no passive=no use-bfd=no remote-id=10.110.100.114 
     local-address=10.111.113.89 uptime=21h33m50s prefix-count=0 updates-sent=0 updates-received=3 withdrawn-sent=0 withdrawn-received=3 remote-hold-time=4m used-hold-time=3m 
     used-keepalive-time=1m refresh-capability=yes as4-capability=yes state=established

4.-後記

/usr/local/bin/notify_about_attack.py 這個東西可以做很多有意思的東西,例如telegram 通知,郵件通知等等..自助解封,主動封鎖等等…….

還有flow并不是最佳的監測辦法,最好的辦法是用端口鏡像..或者分光,條件有限只能這樣搞了.

全文終。

作者:hack520

文章链接:FastNetMon与MikroTik集成(DDoS检测系統)

短连接:https://zhu.vn/?p=1966

发表评论