Como bloquear um (país) range de IP no Linux usando iptables.
Iptables é a aplicação nativa de firewall do linux. Através dele, você pode realizar bloqueio de IPs, controle de tráfego de entrada, bloqueios de saida de tráfego.
Nesta semana, um de nossos parceiros estava recebendo um flood (ataque) em seu servidor de e-mails (IMAP).
Primeiramente ele foi alertado pela sua hospedagem que o tráfego de saida na porta 25 estava extremamente alto.
Isso estava acontecendo por que o ataque consiste em enviar uma massa extremamente grande de tentativas de conexão, onde as mesmas falham e enviam essa informação de falha na saida da porta 25.
Segue o log:
2023-10-25 23:18:54 dovecot_login authenticator failed for (localhost) [46...44]:30670: 535 Incorrect authentication data (set_id=zarzadca) 2023-10-25 23:18:55 SMTP connection from [46...44]:5150 (TCP/IP connection count = 4)
Ao verificar que os ips são de paises onde o nosso parceiro não faz negócios a primeira coisa que me veio a mete seria bloquear todo o país atacante.
Iniciei a confecção do script quando me veio a seguinte questão a mente:
Será que alguem já fez esse script? 🤔
Bingo, achei um script na internet que estava precisando dar uma ajustada, pois acredito que ele seja antigo, fiz os ajustes e vou deixar o link do github e o script logo abaixo caso você não queria olhar no github e nem me seguir por lá. 😢
https://github.com/Leonardo-Ferreira-costa/block-iptables.sh
#!/bin/bash
# O script tem a intenção de bloquear um range de ip de um determinado país, para saber o códio do páis verificar na url informada abaixo.
# See url for more info - http://www.cyberciti.biz/faq/?p=3402
# Author: nixCraft <www.cyberciti.biz> under GPL v.2.0+
# Adaptação para pt-br: Leonardo F. Costa <www.difusao.tech/blog>
# -----------------------------------------------------------------------------
#Inserir neste ponto os países que serão bloqueados, verificar na url: http://www.ipdeny.com/ipblocks
ISO="ir ru af cn"
### Variáveis para facilitar o uso do script que aponta para iptables, wget para baixar os arquivos da base de dados e egrep para selecionar o IP sem nenhum símbolo que iptables não possa interpretar ###
IPT=/sbin/iptables
WGET=/usr/bin/wget
EGREP=/bin/egrep
#Nova tabela com as regioes para banir
SPAMLIST="countrydrop"
#Local da base de dados
ZONEROOT="/root/iptables"
#URL com os ips dos países
DLROOT="http://www.ipdeny.com/ipblocks/data/countries"
#Funcao que vai limpar as configuracoes default do iptables
cleanOldRules() {
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
}
#Criamos o diretorio para criar a base de dados.
[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT
#Executamos a função de limpeza do iptables
cleanOldRules
#Criamos a tabela do iptables com o nome da variável SPAMLIST
$IPT -N $SPAMLIST
for c in $ISO; do
# Base de dados das zonas à bloquear.
tDB=$ZONEROOT/$c.zone
# Baixamos a base de datos atualizada.
$WGET -O $tDB $DLROOT/$c.zone
# Mensagem do país bloqueado que aparecerá no log do iptables
SPAMDROPMSG="$c País bloqueado"
# Filtramos a base de dados para que o iptables interprete corretamente a base de dados e vamos analisar cada bloco de IP.
BADIPS=$(egrep -v "^#|^$" $tDB)
for ipblock in $BADIPS; do
$IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
$IPT -A $SPAMLIST -s $ipblock -j DROP
done
done
# Drop todo
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST
exit 0
Crie um arquivo .py com o código acima e execute com um cat nomedoarquivo.py | sh
obs.:
Fiz a revisão do código e tive que fazer poucas alteraçãoes, então mantive os creditos do amigo que iniciou o trabalho (nada mais justo).
Uma outra observação legal a se fazer foi a que passou na minha cabeça em usar o fail2ban, porém o ataque não vinha do mesmo IP, ele ficava variando dentro de um range na localidade bloqueada então o uso de uma ferramenta dessas não seria muito eficiente. O importante é que foi resolvido.
Obrigado por ler tudo e até a próxima.