Certaines des adresses IP ouvrent des milliers de connexions de mon serveur. J'ai un serveur Ubuntu 14. Je vérifie le nombre total de connexions à l'aide de la commande suivante:
netstat -an | grep tcp | awk '{print $ 5}' | cut -f 1 -d: | trier | uniq -c | trier -n
Ensuite, j'utilise la règle suivante iptables pour bloquer l'adresse IP du coupable.
iptables -I INPUT 1 -s x.x.x.x -j DROP
Cela fonctionne très bien et bloque l'adresse IP. Cependant, je ne peux pas rester en ligne 24h/24 et 7j/7 pour surveiller le serveur. Je me demandais s'il y avait un script Shell que je pourrais utiliser pour le faire automatiquement? Par exemple, si une adresse IP ouvre plus de X connexions à tout moment, elle devrait automatiquement être bannie par la règle iptables ci-dessus.
Tout d'abord, ne réinventez pas la roue. C'est précisément ce à quoi denyhosts
est destiné:
DenyHosts is a python program that automatically blocks ssh attacks by
adding entries to /etc/hosts.deny. DenyHosts will also inform Linux
administrators about offending hosts, attacked users and suspicious
logins.
Autant que je sache, denyhosts
ne concerne que les connexions ssh
, mais il y a aussi fail2ban
qui traite à peu près n'importe quoi:
Fail2Ban consists of a client, server and configuration files to limit
brute force authentication attempts.
The server program fail2ban-server is responsible for monitoring log
files and issuing ban/unban commands. It gets configured through a
simple protocol by fail2ban-client, which can also read configuration
files and issue corresponding configuration commands to the server.
Les deux sont disponibles dans les référentiels:
Sudo apt-get install denyhosts fail2ban
Vous pouvez également écrire ceci, si vous le souhaitez. Quelque chose comme:
#!/usr/bin/env sh
netstat -an |
awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="0.0.0.0"){c[a[1]]++}}
END{for(ip in c){if(c[ip]>max){print ip}}}' |
while read ip; do iptables -I INPUT 1 -s "$ip" -j DROP; done
La awk
extraira les adresses IP, les comptera et imprimera uniquement celles qui apparaissent plus de max
fois (ici, -vmax=100
, changez-le en conséquence). Les adresses IP sont ensuite envoyées à une boucle while qui exécute la règle iptables
appropriée.
Pour exécuter ceci 24/7, je ferais un travail cron qui exécute la commande au-dessus de chaque minute. Ajouter cette ligne à /etc/crontab
* * * * * root /path/to/script.sh
Une autre option possible consiste à identifier et à traiter le problème des adresses IP dans l’ensemble de règles iptables, à l’aide du module recent
. Le défi avec cette méthode est la limite du nombre de hits par défaut de 20; il est donc nécessaire de dévier des valeurs par défaut ou de créer des compteurs de report de niveau supérieur pour atteindre un point de déclenchement du nombre de hits plus élevé.
L'exemple ci-dessous est tiré de mon ensemble de règles iptables et interdira une adresse IP pendant un peu plus d'un jour si elle établit 80 nouvelles connexions TCP sur le port 80 en moins de 12 minutes. Une fois sur la liste des personnes malveillantes, toute tentative de connexion réinitialisera le compteur d'un jour à 0. Cette méthode peut atteindre un maximum de 400 hits avant qu'une extension de report ne soit requise (et j'ai testé une autre chaîne de report). Notez que le code tel que publié contient l'infrastructure à utiliser pour interdire pendant longtemps uniquement plusieurs déclencheurs de temps plus courts. Actuellement, je suis sur le point d'interdire longtemps le premier déclencheur.
#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in4
#
# A NEW Connection on port 80 part 4.
#
# multiple hits on the banned list means you get a one day ban.
# (I re-load the firewall rule set often, so going longer makes
# little sense.)
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
# Place holder routine, but tested. Logs if a day ban would have
# been activated.
#
$IPTABLES -N http-new-in4
#$IPTABLES -A http-new-in4 -m recent --set --name HTTP_BAN_DAY
$IPTABLES -A http-new-in4 -j LOG --log-prefix "DAY80:" --log-level info
$IPTABLES -A http-new-in4 -j DROP
#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in3
#
# A NEW Connection on port 80 part 3.
#
# carry forward to the actual banned list:
# Increment this count. Leave the previous count.
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
$IPTABLES -N http-new-in3
$IPTABLES -A http-new-in3 -m recent --remove --name HTTP_02
$IPTABLES -A http-new-in3 -m recent --update --hitcount 1 --seconds 86400 --name HTTP_BAN -j http-new-in4
$IPTABLES -A http-new-in3 -m recent --set --name HTTP_BAN
$IPTABLES -A http-new-in3 -j LOG --log-prefix "BAN80:" --log-level info
$IPTABLES -A http-new-in3 -j DROP
#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in2
#
# A NEW Connection on port 80 part 2.
#
# carry forward from previous max new connections per unit time:
# Increment this count and clear the lesser significant count.
#
$IPTABLES -N http-new-in2
$IPTABLES -A http-new-in2 -m recent --remove --name HTTP_01
$IPTABLES -A http-new-in2 -m recent --update --hitcount 3 --seconds 720 --name HTTP_02 -j http-new-in3
$IPTABLES -A http-new-in2 -m recent --set --name HTTP_02
$IPTABLES -A http-new-in2 -j LOG --log-prefix "CARRY80:" --log-level info
$IPTABLES -A http-new-in2 -j ACCEPT
#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in
#
# A NEW Connection on port 80:
#
$IPTABLES -N http-new-in
echo Allowing EXTERNAL access to the WWW server
# . check the static blacklist.
#
# http related
$IPTABLES -A http-new-in -i $EXTIF -s 5.248.83.0/24 -j DROP
... delete a bunch on entries ...
$IPTABLES -A http-new-in -i $EXTIF -s 195.211.152.0/22 -j DROP
$IPTABLES -A http-new-in -i $EXTIF -s 198.27.126.38 -j DROP
# . check the dynamic banned list
#
# The 1 Hour banned list (bumped to more than a day):
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j LOG --log-prefix "LIM80:" --log-level info
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j DROP
# A generic log entry. Usually only during degugging
#
#$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80ALL:" --log-level info
# Dynamic Badguy List. Least significant hit counter. Detect and DROP Bad IPs that do excessive connections to port 80.
#
$IPTABLES -A http-new-in -m recent --update --hitcount 20 --seconds 240 --name HTTP_01 -j http-new-in2
$IPTABLES -A http-new-in -m recent --set --name HTTP_01
$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80:" --log-level info
$IPTABLES -A http-new-in -j ACCEPT
... a bunch of stuff not included here
# Allow any related traffic coming back to the server in.
#
#
$IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT
... the above is needed before the below ...
# If required, go to NEW HTTP connection sub-routine
#
$IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 80 -j http-new-in