Envoyé par unreal
Si vous regardez vos logs SSH de temps en temps, vous avez sans doute constaté des milliers d'IP qui tentent de se logger sur le serveur. Ils auront peu de chance de se connecter pour peu que les mots de passe soient sûrs, mais si vous hébergez des clients ou des amis, comment protéger leurs comptes, et le serveur par la même occasion ?
Décidément PF offre une solution très élégante à ce problème par le bias du firewall Packet Filter qui dispose d'options de détection de fréquence de connexions.
Passons directement dans le vif du sujet avec un exemple sous FreeBSD 7.2.
On commence par activer PF dans rc.conf :
Ensuite, on crée un fichier de configuration qui s'appelle donc /etc/pf.conf :
Quelques explications s'imposent ici. La ligne 2 active la suivie d'état sur les interfaces en0 et en1 vers le service ssh. Quand une même IP source dépasse 3 nouvelles connexions dans une fenêtre de 120 secondes, PF rajoute automatiquement cette IP dans la table ssh-bruteforce. La ligne 1 sert alors de bloquer tous les paquets en provenance de cette la table ssh-bruteforce, qu'elles viennent de l'interface en0 ou en1.
On offre une protection similiaire pour le service HTTP (lignes 3 et 4) avec les paramètres suivants :
- 50 connexions par plage de 10 secondes
- 100 connexions max par IP source
Si un client dépasse ses limites, son IP sera bloquée.
Comme les tables ne sont jamais vidées (sauf redémarrage du service pf), il faut purger via un crontab :
On débloque donc les connexions au bout d'une heure (ssh) et 10 mintes (http).
Pour démarrer pf, il suffit enfin de lancer le son script rc :
La commande pfctl permet de surveiller les IP bloquées :
En pratique, on peut écrire un petit script shell pour surveiller d'un coup toutes les tables :
Et pour finir, un exemple d'affichage du script ci-dessus :
Si vous avez des questions, n'hésitez pas à laisser un commentaire !
Décidément PF offre une solution très élégante à ce problème par le bias du firewall Packet Filter qui dispose d'options de détection de fréquence de connexions.
Passons directement dans le vif du sujet avec un exemple sous FreeBSD 7.2.
On commence par activer PF dans rc.conf :
# Firewall
pf_enable="YES" # Enable PF (load module if required)
pf_rules="/etc/pf.conf" # rules definition file for pf
pf_flags="" # additional flags for pfctl startup
pflog_enable="YES" # start pflogd(8)
pflog_logfile="/var/log/pflog" # where pflogd should store the logfile
pflog_flags="" # additional flags for pflogd startup
pf_enable="YES" # Enable PF (load module if required)
pf_rules="/etc/pf.conf" # rules definition file for pf
pf_flags="" # additional flags for pfctl startup
pflog_enable="YES" # start pflogd(8)
pflog_logfile="/var/log/pflog" # where pflogd should store the logfile
pflog_flags="" # additional flags for pflogd startup
Ensuite, on crée un fichier de configuration qui s'appelle donc /etc/pf.conf :
#################################################################
# Interface definitions
ethif0 = "em0"
ethif1 = "em1"
loopback_if = "lo0"
# Set options
set limit states 100000
set skip on lo0
#################################################################
scrub in on $ethif0 all
scrub in on $ethif1 all
# SSH bruteforce protection.
block drop in quick on { $ethif0, $ethif1 } from <ssh-bruteforce> (1)
pass in on { $ethif0, $ethif1 } proto tcp from any to any port ssh flags S/SA keep state (max-src-conn-rate 3/120, overload <ssh-bruteforce> flush global) (2)
# HTTP flood protection.
block drop in quick on $ethif0 proto tcp from <http-antiflood> to any port 80 (3)
pass in on $ethif0 proto tcp from any to any port http flags S/SA keep state (max-src-conn 100, max-src-conn-rate 50/10, overload <http-antiflood> flush global) (4)
# Interface definitions
ethif0 = "em0"
ethif1 = "em1"
loopback_if = "lo0"
# Set options
set limit states 100000
set skip on lo0
#################################################################
scrub in on $ethif0 all
scrub in on $ethif1 all
# SSH bruteforce protection.
block drop in quick on { $ethif0, $ethif1 } from <ssh-bruteforce> (1)
pass in on { $ethif0, $ethif1 } proto tcp from any to any port ssh flags S/SA keep state (max-src-conn-rate 3/120, overload <ssh-bruteforce> flush global) (2)
# HTTP flood protection.
block drop in quick on $ethif0 proto tcp from <http-antiflood> to any port 80 (3)
pass in on $ethif0 proto tcp from any to any port http flags S/SA keep state (max-src-conn 100, max-src-conn-rate 50/10, overload <http-antiflood> flush global) (4)
Quelques explications s'imposent ici. La ligne 2 active la suivie d'état sur les interfaces en0 et en1 vers le service ssh. Quand une même IP source dépasse 3 nouvelles connexions dans une fenêtre de 120 secondes, PF rajoute automatiquement cette IP dans la table ssh-bruteforce. La ligne 1 sert alors de bloquer tous les paquets en provenance de cette la table ssh-bruteforce, qu'elles viennent de l'interface en0 ou en1.
On offre une protection similiaire pour le service HTTP (lignes 3 et 4) avec les paramètres suivants :
- 50 connexions par plage de 10 secondes
- 100 connexions max par IP source
Si un client dépasse ses limites, son IP sera bloquée.
Comme les tables ne sont jamais vidées (sauf redémarrage du service pf), il faut purger via un crontab :
# PF bruteforce reset
*/5 * * * * /sbin/pfctl -t ssh-bruteforce -T expire 3600 2>/dev/null
*/5 * * * * /sbin/pfctl -t http-antiflood -T expire 600 2>/dev/null
*/5 * * * * /sbin/pfctl -t ssh-bruteforce -T expire 3600 2>/dev/null
*/5 * * * * /sbin/pfctl -t http-antiflood -T expire 600 2>/dev/null
On débloque donc les connexions au bout d'une heure (ssh) et 10 mintes (http).
Pour démarrer pf, il suffit enfin de lancer le son script rc :
/etc/rc.d/pf start
La commande pfctl permet de surveiller les IP bloquées :
pfctl -t <nom de table> -vTshow
En pratique, on peut écrire un petit script shell pour surveiller d'un coup toutes les tables :
#!/usr/local/bin/bash
TABLES=`pfctl -s Tables 2>/dev/null`
for ONETABLE in $TABLES; do
echo " -- $ONETABLE --"
echo
pfctl -t $ONETABLE -vTshow 2>/dev/null
echo
done
TABLES=`pfctl -s Tables 2>/dev/null`
for ONETABLE in $TABLES; do
echo " -- $ONETABLE --"
echo
pfctl -t $ONETABLE -vTshow 2>/dev/null
echo
done
Et pour finir, un exemple d'affichage du script ci-dessus :
# ./showtables.sh
-- http-antiflood --
-- ssh-bruteforce --
202.108.103.2
Cleared: Fri May 15 09:30:20 2009
In/Block: [ Packets: 8 Bytes: 428 ]
In/Pass: [ Packets: 0 Bytes: 0 ]
Out/Block: [ Packets: 0 Bytes: 0 ]
Out/Pass: [ Packets: 0 Bytes: 0 ]
-- http-antiflood --
-- ssh-bruteforce --
202.108.103.2
Cleared: Fri May 15 09:30:20 2009
In/Block: [ Packets: 8 Bytes: 428 ]
In/Pass: [ Packets: 0 Bytes: 0 ]
Out/Block: [ Packets: 0 Bytes: 0 ]
Out/Pass: [ Packets: 0 Bytes: 0 ]
Si vous avez des questions, n'hésitez pas à laisser un commentaire !
Posté le 14/05/09 à 19:53