Usando Linux Debian Bookworm.
Problema
Quero bloquear todas as conexões de entrada do meu servidor provenientes de países específicos.
Editar
Como alguém apontou nos comentários, eu realmente não deveria fazer isso com o iptables, pois isso paralisará meu servidor quando a lista de endereços IP que ele bloqueia crescer para um tamanho incontrolável (como milhares de endereços IP). Em vez disso, devo usar ipset
(para bloquear intervalos inteiros). O problema é que depende das listas que preciso baixar regularmente. Quero algo que configurei uma vez (de preferência).
Então, como posso interromper conexões de países específicos? O tráfego (e por vezes ataques de força bruta) proveniente da China e da Rússia está a ficar fora de controlo. Eles colocam meu servidor de joelhos regularmente. Eles não aderem ao arquivo robots.txt e rastreiam o site de forma muito agressiva (com centenas, às vezes milhares de conexões simultaneamente). Eu realmente preciso parar com isso. Minha estimativa é que mais de 90% de todo o tráfego que meu servidor gerencia é malicioso/malformado.
Editar 2
Encontrei alguns tutoriais online ( como este ) sobre como fazer isso, mas parece que esses tutoriais são bem antigos. Além disso, requer download e compilação/instalação de alguns módulos. Estou preocupado que isso possa falhar no futuro (ao atualizar/atualizar outros pacotes ou até mesmo a distribuição) ou possa se tornar um risco de segurança no futuro. Eu mantenho meu servidor atualizado e atualizado (executando apt-get update / apt-get upgrade / apt-get dist-upgrade regularmente).
mensagem original
Encontrei um script on-line que (em poucas palavras) obtém uma lista de endereços IP de conexões estabelecidas a cada segundo e depois usa o geoiplookup para obter o país do endereço IP. Se o país estiver na lista de países que você deseja bloquear, ele adiciona o endereço IP ao filtro do firewall usando iptables. Fiz algumas pequenas alterações no script (tornando-o mais legível e porque não estava interessado neste script me enviando um e-mail toda vez que bloqueava um endereço IP). Este script é executado a cada minuto através do crontab:
#!/bin/bash
# Script found on lautenbacher.io"
end=$((SECONDS+55))
while [ $SECONDS -lt $end ]; do
echo $SECONDS
netstat -ant | egrep ':.*ESTABLISHED' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c > testcc.txt
sed 's/^[ t]*//' -i testcc.txt
sed '/^$/d' -i testcc.txt
while read c d; do
if [[ $c > "0" ]]; then
bGF1dGVuYmFjaGVyLmlv=$(geoiplookup $d | awk -v ip="$d" '{FS=" "} {if($4 == "RU," || $4 == "CN," || $4 == "BLR,") {print 1}}')
if [[ $bGF1dGVuYmFjaGVyLmlv = "1" ]]; then
echo "running geolookup"
echo checking ip $d
geoiplookup $d
isCloudflare=0
# The original script made an exception for CLOUDFLARE. I don't want that exception
# bGF1dGVuYmFjaGVyLmlX=$(whois $d)
# if [[ "$bGF1dGVuYmFjaGVyLmlX" == *"CLOUDFLARE "* ]]; then
# isCloudflare=1
# echo Cloudflare detected
# fi
if [[ "$isCloudflare" != 1 ]]; then
echo try to add ip $d to blocklist
sudo iptables -I INPUT -s $d -j DROP
### I would like to sever the connection here ###
fi
fi
fi
done < testcc.txt
sleep 1
:
done
Aliás, não tenho ideia de por que o autor do script usa nomes de variáveis tão estranhos ("bGF1dGVuYmFjaGVyLmlv").
De qualquer forma, o problema é que sempre que encontra uma conexão com um endereço IP de um país banido, ele executa
sudo iptables -I INPUT -s $d -j DROP
no endereço IP. Tudo bem, mas a maioria dessas conexões é um tanto persistente, o que significa que um segundo depois o mesmo endereço IP é encontrado e adicionado novamente usando iptables. Não tenho certeza do que acontece (isso cria regras duplicadas?), mas gostaria de interromper imediatamente a conexão após o endereço IP ser adicionado ao iptables.
Resumindo: como posso eliminar todas as conexões com um endereço IP?