Como se proteger de ataques DDoS com FastNetMon de graça – Integração FRR vs NE-Huawei – Bonus Gráficos Grafana

Existe um tutorial mais atualizado acesse:

Fortalecendo a Resiliência da Rede: Detecção de Ataques DDoS com FastNetMon, FRRouting, Grafana e Implementação em Debian 12 com Huawei & RouterOS
👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆

#
#
#
#
#
#
#
#

Neste tutorial vamos aprender como identificar os ataques Dos/DDoS e anunciar os prefixo atacados (ou atacantes) de seu AS em envia-los para uma blackhole, e repassar os mesmo para sua operadora. (Acordo)

Vamos utilizar o FastNetMon (Community Edition) que é um analisador de carga DoS/DDoS de alto desempenho, construído sobre vários mecanismos de captura de pacotes (NetFlow, IPFIX, sFlow, AF_PACKET, SnabbSwitch, netmap, PF_RING, PCAP).

Farei a instalação no Debian 11 (Instalação Limpa). O hardware utilizado por ser bem generoso, 1CPU e 1GB de memoria.


Nesse gráfico podemos ver um servidor analisando 10GB via Netflow e quase nada sendo usado de recursos. Mais ao final irei configurar o Graphith para termos gráficos qual irá abusar mais do hardware, porém para muitos gráficos não são necessários, e sim algo que o proteja.

Cenário fictício de exemplo:
Seu AS: 260072 (Madruga Telecom)
Operadora AS: 71 (BrUxa71 Telecom)
10.100.0.1/30 – Huawei NE
10.100.0.2/30 – Servidor

Configurando a interface de Rede

Antes de iniciar a instalação do seu do seu servidor em meu exemplo estou usando o IP 10.100.0.2/30, porém eu NUNCA faria um NAT no roteador de borda então porque utilizar o IP privado? Simples por que ele não é acessível logo não pode ser atacado, mas por outro lado se ele não tiver internet você não poderá fazer a instalação e ele não poderá te notificar pelo telegram. Solução que eu gosto muito de aplicar em servidores é a seguinte (falo muito de como configurar interface de redes nesse tutorial, recomendo uma leitura).

Vamos supor que seu prefixo seja 72.72.72.0/22 e você vai alocar o ip 72.72.72.255/32 para ser o IP de “loopback”. Dica que esse IP não seja próximo a do prefixo público que utiliza em seus servidores.

# vim /etc/network/interfaces
allow-hotplug eno1
iface eno1 inet static
    address 72.72.72.255/32

iface enp0s3 inet static
    address 10.100.0.2/30
    post-up /usr/sbin/ip route add default via 10.100.0.1 src 72.72.72.255

Perceba que nós estaremos conversando com nosso roteador de borda pelo prefixo privado 10.100.0.0/30 porém todo o pacote de origem do servidor sai pelo o IP público. Caso este ip seja atacado o mesmo poderá cair em blackhole que o nosso servidor ainda terá comunicação com a borda.

Mas para que seu IP publico tenha rota será necessário criar um rota em seu roteador de borda apontando o IP público para o privado.

<NE-SEUMADRUGA> system-view
Enter system view, return user view with return command.
[~NE-SEUMADRUGA] ip route-static 72.72.72.255 255.255.255.255 10.100.0.2 description FASTNETMON
[*NE-SEUMADRUGA] commit

É claro que neste caso ficará sem internet, mas podemos aplicar um firewall para enviar que ele fique respondendo, apenas para deixar ele “escondidinho”. E para isso vamos usar o nftables (Que já vem instalado por padrão no Debian 11 substituindo o iptables)
Habilite o mesmo para iniciar com o sistema:

# systemctl enable nftables

Vamos montar nosso firewall de forma que apenas conexoes que forem abertas pelo servidor seja respondidas.

# vim /etc/nftables.conf
#!/usr/sbin/nft -f

flush ruleset

table inet filter {

        chain input {
                type filter hook input priority 0;

                # Permite que apenas conexoes que foram aberta pelo servidor seja respondidas
                ip daddr 72.72.72.255 ct state related,established counter accept
                ip daddr 72.72.72.255 counter drop

        }
        chain forward {
                type filter hook forward priority 0;
        }
        chain output {
                type filter hook output priority 0;
        }
}

Inicie o nftables

# systemctl start nftables

Você pode simplesmente rodar um scanner de porta no seu IP público bem como um ping, o mesmo não deve responde.

Instalação FastNetMon (Edição da comunidade)

Para ver o comparativo da versão gratuita acesse aqui. Já antemão o que não teremos suporte é ao IPv6 e alguns recursos extras.
Conversando com Pavel Odintsov entendeu que no Brasil os planos da versão paga ficam muito pesada para a grande maioria devido a alto do dólar, então ele criou um cupom com 50% de desconto para os brasileiros. 🙂
Segue os lins com o desconto:
Licença 10Gb
Licença 40GB
Licença 100GB

Vamos a instalação [Doc Oficial]

# apt install wget tcpdump net-tools zip curl
# cd /tmp/
# wget https://install.fastnetmon.com/installer -Oinstaller
# chmod +x installer
# ./installer -install_community_edition

É necessário que vc informe seu e-mail durante a instalação. (Para usar a Comunidade FastNetMon você deve fornecer seu e-mail corporativo válido e aceitar receber informações sobre nossa edição comercial e atualizações de segurança)

18:13:33 Will log all installation process details into file: /tmp/fastnetmon_install_1170.log
18:13:33 Installer build git version is: b21331ee349eaf0bc2abc71a466802cd26ee2347 build time is: 2022-01-17T16:17:51
18:13:33 Install FastNetMon Community edition

We offer significantly improved FastNetMon Advanced edition: 
<blockquote class="wp-embedded-content" data-secret="ghCHMDUZME"><a href="https://fastnetmon.com/fastnetmon-advanced/">FastNetMon Advanced</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“FastNetMon Advanced” — FastNetMon DDoS Detection Tool" src="https://fastnetmon.com/fastnetmon-advanced/embed/#?secret=9HRlASbAu2#?secret=ghCHMDUZME" data-secret="ghCHMDUZME" width="500" height="282" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
You could order free one-month trial for Advanced edition here: 
<blockquote class="wp-embedded-content" data-secret="zdVTqp3qpj"><a href="https://fastnetmon.com/trial/">Order trial</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Order trial” — FastNetMon DDoS Detection Tool" src="https://fastnetmon.com/trial/embed/#?secret=kKLHfdm2fM#?secret=zdVTqp3qpj" data-secret="zdVTqp3qpj" width="500" height="282" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

To use FastNetMon Community you must provide your valid corporate email and accept 
to receive information about our commercial edition and security updates.
You can find our privacy policy here https://fastnetmon.com/privacy-policy/

Provide your corporate email here, personal emails are not allowed: seu@email.com.br
18:13:41 Apply sysctl configuration changes
18:13:41 Disable rp_filter for all interfaces
18:13:41 Installing on Debian 11.2 platform
18:13:41 Download binary package
18:15:27 Successfully installed FastNetMon Community edition

Adicione todos os prefixos do seu AS, são esses os IPs serão feito analise.

# vim /etc/networks_list

Exemplo:

72.72.72.0/22

Ajustando as configurações do /etc/fastnetmon.conf.
Habilitamos o serviço de netflow: `netflow = off` para `netflow = on`

# sed -i 's/netflow = off/netflow = on/' /etc/fastnetmon.conf

Ajustes de tempo

# sed -i 's/average_calculation_time = 5/average_calculation_time = 15/' /etc/fastnetmon.conf
# sed -i 's/average_calculation_time_for_subnets = 5/average_calculation_time_for_subnets = 15/' /etc/fastnetmon.conf
# sed -i 's/netflow_sampling_ratio = 1/netflow_sampling_ratio = 1024/' /etc/fastnetmon.conf

Defina por quanto tempo em segundos um IP ficará em blackhole o padrão é 1900 seg. No comando estou alterando para 10min:

# sed -i 's/ban_time = 1900/ban_time = 600/' /etc/fastnetmon.conf

Ative medidores de velocidade por sub-rede, para listar a velocidade da faixa em bps e pps para ambas as direções. (Parece que removeram na última versão)

# sed -i 's/enable_subnet_counters = off/enable_subnet_counters = on/' /etc/fastnetmon.conf

Altera o top 7 para o top 10 ao usar o comando fastnetmon_client

# sed -i 's/max_ips_in_list = 7/max_ips_in_list = 10/' /etc/fastnetmon.conf

Temos diferentes abordagens para detecção dos ataques: Pacotes por segundos, largura de banda e por fluxo (flows).

ban_for_pps = on
ban_for_bandwidth = on
ban_for_flows = off

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

Vamos ativar todos os filtros:

# sed -i 's/ban_for_flows = off/ban_for_flows = on/' /etc/fastnetmon.conf
# sed -i 's/ban_for_tcp_bandwidth = off/ban_for_tcp_bandwidth = on/' /etc/fastnetmon.conf
# sed -i 's/ban_for_udp_bandwidth = off/ban_for_udp_bandwidth = on/' /etc/fastnetmon.conf
# sed -i 's/ban_for_icmp_bandwidth = off/ban_for_icmp_bandwidth = on/' /etc/fastnetmon.conf
# sed -i 's/ban_for_tcp_pps = off/ban_for_tcp_pps = on/' /etc/fastnetmon.conf
# sed -i 's/ban_for_udp_pps = off/ban_for_udp_pps = on/' /etc/fastnetmon.conf
# sed -i 's/ban_for_icmp_pps = off/ban_for_icmp_pps = on/' /etc/fastnetmon.conf

Como temos todas as detecções ativas, precisamos ajustar cada situação para sua realidade. Você precisa ter em mente qual é o maior tráfego que pode atingir por um IP da sua rede (seu maior plano) com base nisso tenha em mente que a cada 100MB gera em torno de 10.000 pps por segundo, isso não é regra mas pode ser uma base inicial. Vamos imaginar então que meu maior plano seja 900MB, farei uma ajuste no threshold_pps para 90.000 pps.

# sed -i 's/threshold_pps = 20000/threshold_pps = 90000/' /etc/fastnetmon.conf

Agora em threshold_mbps seria o maior tráfego que você irá permitir, eu normalmente não altero e deixo no padrão 1gb. E em threshold_flows o fluxos de limite qual também mantenho o mesmo valor 3500.

threshold_mbps = 1050
threshold_flows = 3500

O netflow ouve a porta padrão 2055 se desejar alterar basta alterar o valor de netflow_port. Irei alterar para 52055.

# sed -i 's/netflow_port = 2055/netflow_port = 52055/' /etc/fastnetmon.conf

Por o serviço ira ficar ouvindo em todos os endereços IPs do seu servidor (netflow_host = 0.0.0.0), logo o mais correto seria deixa-lo apenas para o IP privado.

# sed -i 's/netflow_host = 0.0.0.0/netflow_host = 10.100.0.2/' /etc/fastnetmon.conf

Ainda em /etc/fastnetmon.conf temos notify_script_path que sempre que o fastnetmon identificar um ataque irá executar o script /usr/local/bin/notify_about_attack.sh, identificando o IP da sua rede que está sofrendo (incoming) o ataque ou que está atacando (outgoing) alguém. Ele NÃO irá identificar os IPs de origem, pois em um ataque quase sempre as origens são alteradas por milhares de IPs aleatórios.

Habilite e reinicie o fastnetmon para carregar as novas configurações.

# systemctl enable fastnetmon
# systemctl restart fastnetmon

Verifique se a porta 52055/udp esta ouvindo:

# netstat -putan  | grep 52055
udp        0      0 10.100.0.2:52055           0.0.0.0:*                           1599/fastnetmon 

Bom mas antes de criarmos nosso script notify_about_attack.sh, precisamos preparar algumas coisas, e antes de mais nada vamos configurar nosso Huawei para enviar os dados.

Acesse seu roteador Huawei:

<NE-SEUMADRUGA> system-view
[~NE-SEUMADRUGA] ip netstream export version ipfix peer-as bgp-nexthop ttl
[*NE-SEUMADRUGA] ip netstream export template sequence-number fixed
[*NE-SEUMADRUGA] ip netstream export index-switch 32
[*NE-SEUMADRUGA] ip netstream as-mode 32
[*NE-SEUMADRUGA] ip netstream timeout active 1
[*NE-SEUMADRUGA] ip netstream timeout inactive 15
[*NE-SEUMADRUGA] ip netstream export template timeout-rate 1
[*NE-SEUMADRUGA] ip netstream export template option sampler
[*NE-SEUMADRUGA] ip netstream export template option application-label
[*NE-SEUMADRUGA] ip netstream sampler fix-packets 1024 inbound
[*NE-SEUMADRUGA] ip netstream sampler fix-packets 1024 outbound
[*NE-SEUMADRUGA] ip netstream export source 10.100.0.1
[*NE-SEUMADRUGA] ip netstream export host 10.100.0.2 52055

slot 0 NE8000F1A / slot 10 ou 9 NE8000 M8 / slot 3 NE40

[*NE-SEUMADRUGA] slot <0-10>
[*NE-SEUMADRUGA] ip netstream sampler to slot self
[*NE-SEUMADRUGA]  ipv6 netstream sampler to slot self

Será necessário adicionar em todas suas interfaces de Uplink:

 ip netstream inbound
 ip netstream outbound

Exemplo:

interface 40GE0/1/49.71
 vlan-type dot1q 71
 description BruxaDo71Telecom
 ip address 71.71.71.2 255.255.255.252
 statistic enable
 ip netstream inbound
 ip netstream outbound

Com o tcpdump vamos monitorar a interface para ver o que esta chegando na porta.

# tcpdump -i ens192 -n udp port 52055 -T cnfp -c 10

Se seu NE estiver mandado os pacotes você terá um resultado como:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens192, link-type EN10MB (Ethernet), capture size 262144 bytes
14:25:19.601113 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.608068 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.668054 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.691123 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.768055 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.781129 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.831133 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.858054 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.941124 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
14:25:19.958060 IP 10.100.0.1.40000 > 10.100.0.2.52055: NetFlow v9
10 packets captured
10 packets received by filter
0 packets dropped by kernel

Agora com o comando:

# fastnetmon_client

Iremos visualizar os TOP IPs

FastNetMon 1.1.3 master git- Pavel Odintsov: stableit.ru
IPs ordered by: packets
Incoming traffic       724347 pps   6998 mbps    161 flows
72.72.72.238            51973 pps    569 mbps      0 flows  *banned*
72.72.72.112            14390 pps    154 mbps      0 flows
72.72.72.93             14000 pps    150 mbps      0 flows
72.72.72.161            11705 pps    129 mbps      0 flows
72.72.72.118             8797 pps     86 mbps      0 flows
72.72.72.43              7602 pps     84 mbps      0 flows
72.72.72.111             6669 pps     64 mbps      0 flows

Outgoing traffic       291008 pps    705 mbps    101 flows
72.72.72.238            18009 pps     14 mbps      0 flows  *banned*
72.72.72.112             7929 pps      5 mbps      0 flows
72.72.72.93              7110 pps     10 mbps      0 flows
72.72.72.14              4910 pps     40 mbps      0 flows
72.72.72.43              4887 pps      2 mbps      0 flows
72.72.72.161             4537 pps      2 mbps      0 flows
72.72.72.111             3933 pps     14 mbps      0 flows

Internal traffic             0 pps      0 mbps

Other traffic              420 pps      0 mbps

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

Subnet load:
72.72.72.0/22      pps in: 256000   out: 52000    mbps in: 9630  out: 1077
100.100.0.6/32     pps in: 0        out: 0        mbps in: 0     out: 0

Perceba que o IP 72.72.72.238 foi banido, pois o mesmo excedeu os pps de 50.000, no entanto este é um dos IPs que então em meu CGNAT, e vai ser natural este ter um comportamento diferente. Para que o fastnetmon ignore o mesmo você pode cria uma lista branca. Não se preocupe se isso acontecer com você o fastnetmon não ira fazer nenhuma ação, pois não configuramos nada ainda.
Para criar a lista branca networks_whitelist com os IPs ou prefixo que deseja ignorar.

# > /etc/networks_whitelist
# vim /etc/networks_whitelist

Exemplo

72.72.72.224/28
72.72.73.224/28

Reinicie para carregar as novas configurações.

# systemctl restart fastnetmon

Bot Telegram

Para receber notificações pelo Telegram juntamente com o arquivo de log, vai ser necessário criar um bot do telegram para o uso do mesmo. Se você não sabe como criar um Bot para telegram basta você falar com o @BotFather e enviar para ele /newbot, ele irá pedir qual nome você gostaria de dar a seu bot, e em seguida ira gera um token que vamos precisar a seguir.

Para o Telegram vamos usar um scriptzinho que criei.

# cd /tmp/
# wget https://github.com/remontti/TelegramCMD/archive/master.zip
# unzip /tmp/master.zip
# chmod a+x /tmp/TelegramCMD-master/telegram
# mv /tmp/TelegramCMD-master/telegram* /usr/local/bin/
# ln -s /usr/local/bin/telegram /bin/telegram

Edite o token.conf e altere para o seu TOKEN.

# vim /usr/local/bin/telegram.conf/token.conf
######################################
# Telegram bot                       #
# Create a new bot with @BotFather   #
# get TOKEN                          #
######################################

TOKEN="123456789:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"

Esse script você pode usar para diversas coisas, ele será capaz de zipar um diretorio e lhe enviar o arquivo bem como enviar apenas uma mensagem. Como usar? É importante você saber que o IDs de grupos tem um “-” no inicio do ID, já usuários não. Para descobrir o ID do seu usuário fale com o bot @myidbot e envie para ele /getid, para saber de um grupo adicione @myidbot ao seu grupo e envie /getgroupid@myidbot. Realize um teste com um dos comandos: (Não esqueça de alterar pelo seu ID)

Uso: telegram [Opções]
  -m: Para enviar uma mensagem
     ex: telegram -m "ID Chat" "Meu assunto" "Minha mensagem..."
     ex: telegram -m "-123456789" "Notificação" "Mensagem para um grupo ID"
     ex: telegram -m "123456789" "Notificação" "Mensagem para direta/privado"

  -f: Para enviar um arquivo
     ex: telegram -f "ID Chat" "/diretorio/arquivo" "nome do arquivo zip" "Comentário"
     ex: telegram -f "12345689" /var/log/syslog syslog "Logs do sistema para user privado"
     ex: telegram -f "-12345689" /var/log/syslog syslog "Logs do sistema para um grupo"

FRR

Vamos realizar a instalação do FRRouting (FRR) para fechar sessão BGP entre o roteador de borda e servidor.

# apt install curl apt-transport-https gnupg2 tree net-tools
# curl -s https://deb.frrouting.org/frr/keys.asc | apt-key add -
# echo deb https://deb.frrouting.org/frr bullseye frr-8 | tee -a /etc/apt/sources.list.d/frr.list
# apt update
# apt install frr frr-doc

Parâmetros kernel

# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
# echo "net.ipv4.conf.all.rp_filter = 0" >> /etc/sysctl.conf
# echo "net.ipv4.conf.default.rp_filter = 0" >> /etc/sysctl.conf
# echo "net.ipv4.conf.lo.rp_filter = 0" >> /etc/sysctl.conf
# echo "net.ipv4.conf.`ip -br link |awk '{print $1}' |grep -v lo`.rp_filter = 0" >> /etc/sysctl.conf
# sysctl -p

Ative o modulo BGP

# sed -i 's/bgpd=no/bgpd=yes/' /etc/frr/daemons

Reinicie o FRR

# systemctl restart frr

Entre no shell VTY do FRR.

# vtysh

Rode o comando: `show running-config`

deb11# show running-config 
Building configuration...

Current configuration:
!
frr version 8.3.1
frr defaults traditional
hostname deb11
log syslog informational
no ip forwarding
no ipv6 forwarding
service integrated-vtysh-config
!
line vty
!
end

Agora entre no modo de configuração, e vamos preparar nosso peer com o router de borda. No exemplo está praticamente auto explicativo, vamos fechar o peer e deixar ser anunciado apenas nossos prefixos e aplicaremos a community 65001:666

configure terminal
!
ip prefix-list FASTNETMON_EXPORT seq 5 permit 72.72.72.0/23 le 32
ip prefix-list FASTNETMON_EXPORT seq 10 permit 72.72.74.0/23 le 32
!
!
route-map MARK_FASTNETMON_IMPORT deny 10
!
route-map MARK_FASTNETMON_EXPORT permit 10
 match ip address prefix-list FASTNETMON_EXPORT
 set community 65001:666
!
router bgp 65001
 bgp router-id 10.100.0.2
 neighbor 10.100.0.1 remote-as 260072
 neighbor 10.100.0.1 description "NE8K_BORDA"
# neighbor 10.100.0.1 ebgp-multihop 255 # (Caso seja multihop)
 !
 address-family ipv4 unicast
  neighbor 10.100.0.1 route-map MARK_FASTNETMON_IMPORT in
  neighbor 10.100.0.1 route-map MARK_FASTNETMON_EXPORT out
 exit-address-family
!
line vty
!
end
write memory
exit

Vamos ao Huawei

<NE-SEUMADRUGA> system-view
Enter system view, return user view with return command.

Crie uma rota estática de Blackhole

[~NE-SEUMADRUGA] ip route-static 192.0.2.1 255.255.255.255 NULL0 description BLACKHOLE

Crie um filtro que irá aceitar qualquer rota /32

[*NE-SEUMADRUGA] ip ip-prefix  ACCEP_PREFIX_MASK32_FASTNETMON_IPV4 index 10 permit 0.0.0.0 0 greater-equal 32

Crie os prefixos publico para rejeitar e não cair em blackhole mesmo quando atacado, caso você deixar o fastnetmon anúnciar seu NE pode rejeitar (Ex IP Servidores ou CGNAT)

[*NE-SEUMADRUGA] ip ip-prefix  IGNORE_PREFIX_FASTNETMON_IPV4 index 10 permit 72.72.72.224 28 greater-equal 28 less-equal 32
[*NE-SEUMADRUGA] ip ip-prefix  IGNORE_PREFIX_FASTNETMON_IPV4 index 20 permit 72.72.73.224 28 greater-equal 28 less-equal 32

Crie um filtro para a community 65001:666

[*NE-SEUMADRUGA] ip community-filter basic COMM_FASTNETMON_BLACKHOLE index 10 permit 65001:666

Vamos montar agora nosso route policy de import (rotas que iremos receber). A 1ª é ignorar os prefixos IGNORE_PREFIX_FASTNETMON_IPV4

[*NE-SEUMADRUGA] route-policy FASTNETMON_IMPORT_IPV4 deny node 1000
[*NE-SEUMADRUGA]  if-match ip-prefix IGNORE_PREFIX_FASTNETMON_IPV4

A 2º é o que vir marcado do fastnetmon com 65001:666 (COMM_FASTNETMON_BLACKHOLE) jogar para blackhole e aplicar uma community nova 65444:666, como no exemplo aqui meu AS é de 32bits vou usar um AS privado, mas onde seu AS é de 16bits o mais comum de se encontrar é AS:666. Assim se você for trânsito de outro AS você pode montar em suas route policy para aceitar prefixos do AS dele com /32 marcados com AS:666 e jogar para blackhole também fica dica!

[*NE-SEUMADRUGA] route-policy FASTNETMON_IMPORT_IPV4 permit node 1010
[*NE-SEUMADRUGA]  if-match community-filter COMM_FASTNETMON_BLACKHOLE 
[*NE-SEUMADRUGA]  apply local-preference 999
[*NE-SEUMADRUGA]  apply ip-address next-hop 192.0.2.1
[*NE-SEUMADRUGA]  apply community 65444:666
[*NE-SEUMADRUGA]  if-match ip-prefix ACCEP_PREFIX_MASK32_FASTNETMON_IPV4

E a 3ª ignoramos o resto como boas praticas.

[*NE-SEUMADRUGA] route-policy FASTNETMON_IMPORT_IPV4 deny node 9999

Para as route policy de export (Rotas que o NE irá ensinar) colocarei apenas um Deny pois ele não precisa ensinar nada.

[*NE-SEUMADRUGA] route-policy FASTNETMON_EXPORT_IPV4 deny node 9999
[*NE-SEUMADRUGA] commit

Vamos ao peer

[*NE-SEUMADRUGA] bgp 260072
[~NE-SEUMADRUGA] undo peer 10.100.0.2
[*NE-SEUMADRUGA]  peer 10.100.0.2 as-number 65001
[*NE-SEUMADRUGA]  peer 10.100.0.2 description BORDA_VS_FASTNETMON_IPV4
[*NE-SEUMADRUGA]  peer 10.100.0.2 timer connect-retry 1
[*NE-SEUMADRUGA]  peer 10.100.0.2 connect-interface 10.100.0.1
[*NE-SEUMADRUGA]  peer 10.100.0.2 timer keepalive 10 hold 30 
[*NE-SEUMADRUGA]  ipv4-family unicast
[*NE-SEUMADRUGA]   peer 10.100.0.2 enable
[*NE-SEUMADRUGA]   peer 10.100.0.2 public-as-only
[*NE-SEUMADRUGA]   peer 10.100.0.2 route-policy FASTNETMON_IMPORT_IPV4 import
[*NE-SEUMADRUGA]   peer 10.100.0.2 route-policy FASTNETMON_EXPORT_IPV4 export
[*NE-SEUMADRUGA]   peer 10.100.0.2 next-hop-local
[*NE-SEUMADRUGA]   peer 10.100.0.2 advertise-community
[*NE-SEUMADRUGA]   peer 10.100.0.2 advertise-ext-community
[*NE-SEUMADRUGA] commit
[~NE-SEUMADRUGA] run save 

Em caso de alguma emergência, para baixar a sessão use:

[~NE-SEUMADRUGA] bgp 260072
[*NE-SEUMADRUGA] peer 10.100.0.2 ignore
[*NE-SEUMADRUGA] commit

Para subir novamente:

[~NE-SEUMADRUGA] bgp 260072
[*NE-SEUMADRUGA] undo peer 10.100.0.2 ignore
[*NE-SEUMADRUGA] commit

Verifique se sua sessão subiu:

[*NE-SEUMADRUGA] display bgp peer | include 10.100.0.2
 BGP local router ID : x.x.x.x
 Local AS number : 260072
 Total number of peers : 13                 Peers in established state : 13

  Peer                             V          AS  MsgRcvd  MsgSent  OutQ  Up/Down       State  PrefRcv
  10.100.0.2                       4       65001   897801  1088107     0 2496h26m Established        0

No FRR use `show bgp summary`

# vtysh
# show bgp summary
IPv4 Unicast Summary:
BGP router identifier 10.100.0.2, local AS number 65001 vrf-id 0
BGP table version 0
RIB entries 0, using 0 bytes of memory
Peers 1, using 21 KiB of memory

Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt
10.100.0.1      4     260072         5         5        0    0    0 00:02:52            0        0

Total number of neighbors 1
# exit

Para repassar os prefixos marcados como blackhole para sua operadora você precisará saber qual é a community que a mesma utiliza e se ela lhe oferece esse recurso, em seguida você irá adiciar a route policy da sua operadora uma nova regra:

No exemplo tudo que recebemos do fastnetmon passamos a aplicar a community 65444:666, logo tudo que for marcado com a mesma irei repassar para operadora com a commnunity da operadora. Para isso crie então primeiro a community-filter de Blackhole sua.

[~NE-SEUMADRUGA] ip community-filter basic COMM_BLACKHOLE index 10 permit 65444:666

Agora na route policy da operadora crie algo semelhante ao exemplo, sendo que a community de blackhole que sua operadora passou fosse “71:666”:

[~NE-SEUMADRUGA] route-policy UPSTREAM_OP_BRUXADO71_EXPORT_IPV4 permit node 2070
[~NE-SEUMADRUGA]  if-match community-filter COMM_BLACKHOLE
[~NE-SEUMADRUGA]  apply community 71:666

Pronto agora que ja temos nosso peer Up entre router e servidor, nosso Bot mandando mensagem, iremos criar o script que será executado sempre que um ataque for identificado BAN ou UNBAN. Irei criar um diretório /var/log/fastnetmon_attacks/ataques qual irá ficar os ataques finalizados.

# mkdir /var/log/fastnetmon_attacks/ataques -p
# vim /usr/local/bin/notify_about_attack.sh

Altere ID_CHAT=’-1000000000000′ pelo ID do seu usuário ou grupo.

#!/usr/bin/env bash
  
# Este script receberá os seguintes parâmetros:
#  $1 IP do cliente
#  $2 INCOMING -> Vindo de fora da rede | OUTGOING -> Saindo da sua rede
#  $3 Pacotes por seguncoes
#  $4 Ação (ban ou unban)

# Defina o ID do Chat ou Grupo (Grupos sempre começam com "-" )
ID_CHAT='-1000000000000'

if [ "$2" = "incoming" ]; then
  TIPO="Sendo atacado"
else 
  TIPO="Realizando um ataque"
fi

# Desbanindo um IP
if [ "$4" = "unban" ]; then
  /usr/local/bin/telegram -m "$ID_CHAT" "UNBAN IP: <code>$1</code>" "<code>->></code> Removido da blackhole"
  # Remove IP do anuncio para o FRR
  vtysh --command "configure terminal
  no ip route $1/32 lo
  router bgp 65001
   address-family ipv4 unicast
    no network $1/32
  "
  # Movemos os logs para pasta ataques pois não queremos mais receber elas.
  mv /var/log/fastnetmon_attacks/\* /var/log/fastnetmon_attacks/ataques
  exit 0
fi

# Banindo um IP
if [ "$4" = "ban" ]; then
  /usr/local/bin/telegram -m "$ID_CHAT" "BAN IP: <code>$1</code> $TIPO <b>[$3 pps]</b>" "<code>->></code> Anunciado em blackhole"
  /usr/local/bin/telegram -f "$ID_CHAT" /var/log/fastnetmon_attacks/\* $1 "Logs do ataque ao IP $1"
  # Anuncia IP ao FRR
  vtysh --command "configure terminal
  ip route $1/32 lo
  router bgp 65001
   address-family ipv4 unicast
    network $1/32
  "
    exit 0
fi

if [ "$4" == "attack_details" ]; then
  #/usr/local/bin/telegram -m "$ID_CHAT" "BAN" "<code>FastNetMon: IP $1 blocked because $2 attack with power $3 pps</code>"
  exit 0
fi

De permissão para execução

# chmod a+x /usr/local/bin/notify_about_attack.sh

Restarte o fastnetmon

# systemctl restart fastnetmon

Se quiser fazer um teste manual anunciando um IP (um que não esteja em uso né!!! rsrsrs) exemplo: 72.72.73.255/32
Adicionando:

# vtysh --command "configure terminal
  ip route 72.72.73.255/32 lo
  router bgp 65001
   address-family ipv4 unicast
    network 72.72.73.255/32"

Verificando se esta enviando:

# vtysh --command " show ip bgp neighbors 10.100.0.1 advertised-routes"
BGP table version is 3, local router ID is 10.100.0.2, vrf id 0
Default local pref 100, local AS 65001
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
               i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

   Network          Next Hop            Metric LocPrf Weight Path
*> 72.72.73.255/32  0.0.0.0                  0         32768 i

Total number of prefixes 1

Removendo:

# vtysh --command "configure terminal
  no ip route 72.72.73.255/32 lo
  router bgp 65001
   address-family ipv4 unicast
    no network 72.72.73.255/32"

Finalizamos a primeira parte sem fazer nenhum estrago ao servidor (CPU) 🙂

Seria interessante fazer alguns testes de ataques (coisa pequena) mas com características reais de dentro da sua rede e de fora, escolha uma IP que não esteja em uso para tal! Para realizar esse ataque user o a ferramenta criada pelo ekovegeance: https://github.com/ekovegeance/DDOS

Em um servidor/desktop linux vai precisar ter instalado os pacotes bash sudo curl netcat hping3 openssl stunnel nmap whois dnsutils.
Baixe os arquivos, extraia entre em sua pasta e execute o arquivo ddos.

$ wget https://github.com/ekovegeance/DDOS/archive/v1.2.4.zip
$ unzip v1.2.4.zip 
$ cd DDOS-1.2.4/
$ ./ddos

Gráficos Grafana

Habilite o graphite no fastnetmon

# sed -i 's/graphite = off/graphite = on/' /etc/fastnetmon.conf

Vamos instalar o influxdb para ser a base de dados

# apt install lsb-release gnupg2 curl wget
# wget -q https://repos.influxdata.com/influxdata-archive_compat.key
# echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' \
  | sha256sum -c && cat influxdata-archive_compat.key \
  | gpg --dearmor \
  | tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
# echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main'\
  | tee /etc/apt/sources.list.d/influxdata.list
# apt update
# apt install influxdb

Edite o influxdb.conf

# vim /etc/influxdb/influxdb.conf

Localize [[graphite]] e abaixo adicione:

[[graphite]]
  enabled = true
  bind-address = ":2003"
  protocol = "tcp"
  consistency-level = "one"
  separator = "."
  batch-size = 5000 # will flush if this many points get buffered
  batch-timeout = "1s" # will flush at least this often even if we haven't hit buffer limit
  templates = [
    "fastnetmon.hosts.* app.measurement.cidr.direction.function.resource",
    "fastnetmon.networks.* app.measurement.cidr.direction.resource",
    "fastnetmon.total.* app.measurement.direction.resource"
  ]

Reinicie o influxdb

# systemctl restart influxdb

Em seguida o fastnetmon

# systemctl restart fastnetmon

Agora vamos acessar o o influxdb para ver se o banco graphite foi criado.

# influx
Connected to http://localhost:8086 version 1.8.10
InfluxDB shell version: 1.8.10
> use graphite
Using database graphite
> show measurements
name: measurements
name
----
hosts
networks
total
> exit

Grafana

Adicione o repositório do grafana e instale-o

# wget -q -O - https://packages.grafana.com/gpg.key | apt-key add -
# echo "deb https://packages.grafana.com/oss/deb stable main" | tee -a /etc/apt/sources.list.d/grafana.list
# apt update; apt install grafana

Habilite serviço para inicialização e inicie o mesmo

# systemctl enable grafana-server
# systemctl start grafana-server

Acesse em seu navegador http://ip_privado:3000 e entre com usuário e senha admin em seguida defina uma nova senha.

No menu Configuration e vá em Data sources, clique em Add data source

Localize influxDB e selecione

Preencha apenas:
URL: http://localhost:8086
Database: graphite
E clique em Save & test, você deve ter a resposta Data source is working.

Faça download aqui das Dashs e importe.

Não esqueça de definir o banco InfluxDB

Você pode pesquisar por mais dashs em: https://grafana.com/grafana/dashboards/?search=fastnetmon

Fastnetmon

Fastnetmon PAINEL GERAL

Fastnetmon TOP HOSTS (+100MB)

Fastnetmon TOP HOSTS (+300MB)

Fastnetmon TOP NETWORKS

Fastnetmon TOP TRÁFEGO DE SAÍDA

Fastnetmon TRÁFEGO REDE ESPECIFICADA

Fastnetmon TRÁFEGO POR IP ESPECIFICO

E como ficou o hardware agora?

Gostou? Se sentindo mais seguro agora? É consultor e ganha $ com isso!?

Se quiser fazer uma doação para o café ficarei muito feliz pelo seu reconhecimento!

Se não puder doar pode deixar seu agradecimento nos comentário também ficarei feliz em saber que ajudei. Se tiver qualquer pergunta deixe-a também. Se preferir entrar em Contato clique aqui.

Abraço!

Fontes:
https://fastnetmon.com/install/
https://docs.frrouting.org/en/latest/bgp.html
https://deb.frrouting.org/
https://fastnetmon.com/docs/influxdb_integration/
https://grafana.com/docs/grafana/latest/installation/debian/

BÔNUS PEGANDO PREFIXO /24 DO IP ATACADO E ANUNCIANDO COM OUTRA COMMUNITY PARA MITIGAR

#####################
# SCRIPT FASTNETMON
#####################

#!/usr/bin/env bash
  
# Este script receberá os seguintes parâmetros:
#  $1 IP do cliente
#  $2 INCOMING -> Vindo de fora da rede | OUTGOING -> Saindo da sua rede
#  $3 Pacotes por seguncoes
#  $4 Ação (ban ou unban)

# Pegando prefixo 24
ip32=$1
prefixo24="${ip32%.*}.0/24"

# Defina o ID do Chat ou Grupo (Grupos sempre começam com "-" )
ID_CHAT='-1000000000000'
 
if [ "$2" = "incoming" ]; then
  TIPO="Sendo atacado"
else 
  TIPO="Realizando um ataque"
fi
 
# Desbanindo um IP
if [ "$4" = "unban" ]; then
  /usr/local/bin/telegram -m "$ID_CHAT" "UNBAN IP: <code>$1</code>" "<code>->></code> Removido da blackhole"
  # Remove IP do anuncio para o FRR
  vtysh --command "configure terminal
  no ip route $1/32 lo
  no ip route $prefixo24 lo
  router bgp 65001
   address-family ipv4 unicast
    no network $1/32
    no network $prefixo24
  "
  # Movemos os logs para pasta ataques pois não queremos mais receber elas.
  mv /var/log/fastnetmon_attacks/\* /var/log/fastnetmon_attacks/ataques
  exit 0
fi
 
# Banindo um IP
if [ "$4" = "ban" ]; then
  /usr/local/bin/telegram -m "$ID_CHAT" "BAN IP: <code>$1</code> $TIPO <b>[$3 pps]</b>" "<code>->></code> Anunciado em blackhole"
  /usr/local/bin/telegram -f "$ID_CHAT" /var/log/fastnetmon_attacks/\* $1 "Logs do ataque ao IP $1"
  # Anuncia IP ao FRR
  vtysh --command "configure terminal
  ip route $1/32 lo
  ip route $prefixo24 lo
  router bgp 65001
   address-family ipv4 unicast
    network $1/32
    network $prefixo24
  "
    exit 0
fi
 
if [ "$4" == "attack_details" ]; then
  #/usr/local/bin/telegram -m "$ID_CHAT" "BAN" "<code>FastNetMon: IP $1 blocked because $2 attack with power $3 pps</code>"
  exit 0
fi


#####################
# FRR
#####################


!
frr version 8.5.1
frr defaults traditional
hostname fnm
log syslog informational
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 65001
 bgp router-id 172.16.1.2
 neighbor 172.16.1.1 remote-as 12345
 neighbor 172.16.1.1 description "BORDA"
 !
 address-family ipv4 unicast
  neighbor 172.16.1.1 route-map MARK_FASTNETMON_IMPORT in
  neighbor 172.16.1.1 route-map MARK_FASTNETMON_EXPORT out
 exit-address-family
exit
!
ip prefix-list FASTNETMON_EXPORT_32 seq 5 permit 200.0.0.0/22 le 32
!
ip prefix-list FASTNETMON_EXPORT_24 seq 5 permit 200.0.0.0/22 le 24
!
route-map MARK_FASTNETMON_IMPORT deny 10
exit
!
route-map MARK_FASTNETMON_EXPORT permit 10
 match ip address prefix-list FASTNETMON_EXPORT_24
 set community 65001:777
exit
! 
route-map MARK_FASTNETMON_EXPORT permit 20
 match ip address prefix-list FASTNETMON_EXPORT_32
 set community 65001:666
exit
!
end
write memory


#####################
# HUAWEI
#####################


#Configurando filtros e sessão BGP
ip route-static 192.0.2.1 255.255.255.255 NULL0 description BLACKHOLE

# Aceitas os prefixos 32 do AS para blackhole
ip ip-prefix  ACCEP_PREFIX_MASK32_FASTNETMON_IPV4 index 10 permit 200.0.0.0 22 greater-equal 32

# Aceitas os prefixos 24 do AS para mitigar
ip ip-prefix  ACCEP_PREFIX_MASK24_FASTNETMON_IPV4 index 10 permit 200.0.0.0 22 greater-equal 24

#Iginora Prefixos do CGNAT/Servidores
ip ip-prefix  IGNORE_PREFIX_FASTNETMON_IPV4 index 10 permit 200.0.1.0 28 greater-equal 28 less-equal 32
ip ip-prefix  IGNORE_PREFIX_FASTNETMON_IPV4 index 20 permit 200.0.2.0 26 greater-equal 26 less-equal 32

# community que o FRR ira enviar
ip community-filter basic COMM_FASTNETMON_BLACKHOLE_32 index 10 permit 65001:666
ip community-filter basic COMM_FASTNETMON_BLACKHOLE_24 index 10 permit 65001:777

# Define comm para usar nos RP das operadoras
ip community-filter basic COMM_BLACKHOLE_32 index 10 permit 65444:666
ip community-filter basic COMM_BLACKHOLE_24 index 10 permit 65444:777

# RP
route-policy FASTNETMON_IMPORT_IPV4 deny node 1000
 if-match ip-prefix IGNORE_PREFIX_FASTNETMON_IPV4

route-policy FASTNETMON_IMPORT_IPV4 permit node 1010
 if-match community-filter COMM_FASTNETMON_BLACKHOLE_32 
 apply local-preference 999
 apply ip-address next-hop 192.0.2.1
 apply community 65444:666
 if-match ip-prefix ACCEP_PREFIX_MASK32_FASTNETMON_IPV4
 
route-policy FASTNETMON_IMPORT_IPV4 permit node 1020
 if-match community-filter COMM_FASTNETMON_BLACKHOLE_24
 apply local-preference 999
 apply ip-address next-hop 192.0.2.1
 apply community 65444:777
 if-match ip-prefix ACCEP_PREFIX_MASK24_FASTNETMON_IPV4
 
route-policy FASTNETMON_IMPORT_IPV4 deny node 9999
route-policy FASTNETMON_EXPORT_IPV4 deny node 9999

# FILTRO OPERADORA

# Envia para community de blackhole da operadora 
route-policy UPSTREAM_OP_BRUXADO71_EXPORT_IPV4 permit node 2070
 if-match community-filter COMM_BLACKHOLE_32
 apply community 71:666

# Envia para community de blackhole de mitigraçação
route-policy UPSTREAM_OP_BRUXADO71_EXPORT_IPV4 permit node 2070
 if-match community-filter COMM_BLACKHOLE_24
 apply community 71:999

Rudimar Remontti

Trabalho atualmente como Gerente de Redes em um Provedor de Internet no Rio Grande do Sul.

Você pode gostar...

12 Resultados

  1. Excelente artigo, parabens por compartilhar um contudo tão rico

  2. Denilson Limoeiro disse:

    Parabéns pelo tutorial. Irei tentar implementar. Estou tendo alguns problemas com ataques.

  3. Frederico disse:

    Obrigado pelo post! Me ajudou bastante…
    Surgiu uma dúvida, gostaria de uma ajuda por gentileza se estiver a seu alcance..
    Adaptei esse post ao mikrotik. Funcionou 100%.
    Porém, quando repasso o ip para minha operadora, meu mikrotik está repassando tambem o atributo AS-PATH com valor 65001 e minha operadora não aceita.
    A pergunta é se existe alguma maneira de não repassar isso para operadora e repassar somente o Ip e a communitie?
    Desde já agradeço!

  4. Cleiton disse:

    Excelente tutorial.
    Hoje meu asn está sob a proteção de uma ferramenta parecida com essa, está sob a gerencia do Meu fornecedor de Link. Estou sofrendo um pouco com falso positivo, seria possível utilizar isso dentro de um concentrador pppoe ? setando limites menores dos que estão no meu fornecedor e enviando para blackhole apenas o ip inválido /32 do cliente ?

  5. Rafael Velloso disse:

    Boa tarde, alguem sabe porque no meu não apareceu o Networks?
    Conferi o template la no influxdb.conf, refiz e não apareceu…

    > show measurements
    name: measurements
    name
    —-
    hosts
    total
    > exit

  6. Alessandro Rocha disse:

    Muito bom como sempre! Vou testar!

  7. Vinicius Dorneles disse:

    É possível personalizar as regras baseado no prefixo? Por exemplo:
    o prefixo 72.72.72.0/24 possui uma regra de pps/mbps/flow;
    o prefixo 72.72.73.0/24 possui outra regra de pps/mbps/flow.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *