La technique pour éviter les attaques SSH par brute force avec PacketFilter consiste à ajouter les IP fautives dans une table et d’exclure les IP qui y sont contenues pour les connexions SSH ou de façon globale (petit vilain).

Procédure chef :

  1. déclarer la table qui va contenir les IP bannies
  2. bloquer en début de filtrage les connexions entrantes de ces IP.
  3. ajouter les options de collecte des états des connexions sur les règles que l’on souhaite protéger du bruteforce.
  4. vider la table, en tâche cron par exemple.

Exemple d’un parefeu PF rudimentaire, fait main (70% main droite), autorisant le trafic ICMP et les connexions SSH :

#
# pf.conf
#

# macros
ext_if = "re0" # ou mi0, fa0, sol0 çà dépend
myip = "XX.XX.XX.XX" # comme c'est trop secure

# tables
table <bruteforce> persist {}

# options
set block-policy drop
set skip on lo0 # non ce n'est pas la0
set limit { states 20000, frags 5000, src-nodes 2000 }

# normalization
scrub in all fragment reassemble
scrub all reassemble tcp
scrub in all random-id

#
# rules
#

block all
block quick from <bruteforce>
antispoof quick for lo0

pass out inet proto tcp all flags S/SA keep state
pass out inet proto udp all keep state

pass in on $ext_if inet proto icmp from any to any keep state
pass out on $ext_if inet proto icmp from any to any keep state

pass in on $ext_if inet proto tcp from any to any port 22 flags S/SA keep state (source-track rule, max-src-nodes 8, max-src-conn 8, max-src-conn-rate 10/60, overload <bruteforce> flush global)

Dans le cas où un client se  connecte 10 fois par minute, il est banni et bloqué pour toute nouvelle connexion. Il ne reste plus que de lancer la commande permettant de supprimer les adresses IP enregistrées, ici pour le jour précédent :

# /usr/local/sbin/expiretable -t 24h bruteforce