Fail2ban

J'essaie de passer à Reaction, qui est plus pratique. Mais il me faut traduire les règles utiles de Fail2ban…

Fail2ban logiciel me file des boutons. Son principal mérite est de délayer les attaques par brute-force ; en principe notre serveur n'y est pas vulnérable, mais les principes et la sécurité… Bref, c'est aussi bien de l'avoir comme protection supplémentaire, selon le principe du tamis : si ça passe une couche, avec un peu de chance ça ne passera pas la suivante.

En principe aussi, il marche bien avec nftables, le nouveau pare-feu par défaut sur debian. Sauf que là aussi le principe se heurte à la pratique et j'ai le droit à des erreurs si je tente de l'utiliser. En plus y'a pas autant de tutos avec nftables et je trouve ce soft encore plus illisible qu'iptable, c'est dire… Comme iptable et nftables peuvent cohabiter, je vais gérer fail2ban avec iptable, et lui adjoindre ipset afin de gérer les ip qui ont un peu trop abusé.

Fail2ban

On crée un fichier dans /etc/fail2ban/jail.d/custom.conf qui va contenir nos règles.

Il faudra aussi les tester, regarder les logs d'erreurs, etc… parce que c'est assez facile de croire que Fail2ban fonctionne, alors que non, il a bugué sur un truc obscur et en réalité ne fait rien du tout.

Sur ssh : il ne faut pas indiquer ssh et sftp dans les ports, juste les numéros. Et ça va mieux. J'ai galéré un moment pour que ça marche, à cause de ça…

Le principe est simple : on regarde dans /etc/fail2ban/jail.conf les prisons disponibles et les diverses options, puis dans /etc/fail2ban/jail.d/custom.conf on ne copie que ce qu'on veut changer par rapport au fonctionnement par défaut, et en particulier les “jails” qu'on va activer.

Ça pourrait probablement s'optimiser en créant une jail sur mesure avec toutes les regexp utiles, en particulier sur apache ici. À ce stade, je fais confiance aux devs de Fail2ban pour que les filtres soient efficaces contre pas mal de choses. Mais l'examen des logs montre que c'est quand même perfectible.

Voici à quoi ressemble mon custom.conf actuellement, sur un serveur mail avec un bout de site apache.

[DEFAULT]
# Envoi un mail pour voir que ça marche...
destemail = monmail@mondomaine.org
sender = root
action = %(action_mwl)s
# Cette "action" envoie un courriel avec le détail de qui et pourquoi on bannit. C'est verbeux mais j'aime bien.

# Actions par défaut. Peut être surchargé dans les jails.
# Nombre de fois où une ip peut se planter 
maxRetry = 4
# Regarder les logs sur ce temps là pour voir à quel point les ip retentent le coup
# Pas besoin de mettre trop long, ça bouffe de la mémoire et on a autre chose pour virer 
# celles qui s'acharnent
findtime = 3h
# Durée du bannissement. 
bantime  = 3d
# Si on ban quelque part, c'est partout (en principe)
banaction = iptables-multiport

## Les services surveillés, dits "jail"
[sshd]
enabled = true
port = 22,226
bantime  = 10m

[apache-auth]
enabled = true
[apache-badbots]
enabled = true
[apache-noscript]
enabled = true
[apache-overflows]
enabled = true
[apache-nohome]
enabled = true
[apache-botsearch]
enabled = true
[apache-fakegooglebot]
enabled = true
[apache-modsecurity]
enabled = true
[apache-shellshock]
enabled = true

[dovecot]
enabled = true
port = pop3,pop3s,imap2,imaps,submission,465,sieve
#filter    = dovecot

[postfix]
enabled = true
port  = pop3,pop3s,imap2,imaps,submission,465,sieve
#filter = postfix

[sieve]
enabled = true

Ne pas oublier de redémarrer fail2ban ensuite.

fail2ban-server -t
systemctl restart fail2ban

Commandes fail2ban utilisées régulièrement

  • Liste des jails : fail2ban-client status
  • Statut d'une jail : fail2ban-client status <prison>
  • Vérifier la configuration avant de relancer : fail2ban-server -t
  • Bannir une ip en particulier : fail2ban-client set <prison> banip <adresse IP>
  • Et la débannir : fail2ban-client set <prison> unbanip <adresse IP>

Faire ses propres règles Fail2ban

Il y a quelques améliorations à faire concernant les filtres.

Rendre le filtre postfix par défaut plus agressif

Par défaut, la jail “postfix” va se baser sur le filtre dans /etc/fail2ban/filter.d/postfix.conf. Et, par défaut, celui-ci n'est pas trop vache, mais il peut le devenir.

Cherchez la ligne

mode = more

Et remplacer par

mode = aggressive

Et voilà, là, des messages comme “warning: non-SMTP command from …” seront détectés comme louches et bannis au bout du nombre de tentatives déclarés dans la jail “postfix” (ou la valeur par défaut si on n'a rien précisé).

Ajouter des regex et configurer une jail "aucune chance"

Malgré ça, j'ai encore quelques tentatives des plus douteuses, pas toujours repérées/bannies, et puis surtout, c'est tellement suspect qu'une seule tentative devrait suffire à bannir.

Voici un exemple de certaines lignes que je souhaite filtrer :

2023-10-09T22:48:16.607827+02:00 poste postfix/smtpd[6341]: improper command pipelining after CONNECT from unknown[192.241.223.63]: MGLNDD_109.190.202.194_25\n
2023-10-08T18:50:51.080640+02:00 poste postfix/smtpd[1963528]: NOQUEUE: reject: RCPT from unknown[87.120.84.203]: 504 5.5.2 <WIN-CLJ1B0GQ6JP>: Helo command rejected: need fully-qualified hostname; from=<spameri@tiscali.it> to=<spameri@tiscali.it> proto=ESMTP helo=<WIN-CLJ1B0GQ6JP>
2023-10-15T22:04:39.456433+02:00 poste postfix/submission/smtpd[749737]: connect from scanner-29.ch1.censys-scanner.com[167.248.133.189]
2023-07-28T09:19:04.783707+02:00 poste postfix/smtpd[608140]: warning: non-SMTP command from scan-15n.shadowserver.org[184.105.247.252]: GET / HTTP/1.1
  • Envoyer une commande foireuse ? Qui fait ça en dehors de ceux qui testent les fragilités d'une installation ?
  • Un hostname mal déclaré ? Sérieusement, c'est n'importe quoi.
  • Notez au passage que tout ce qui contient tiscali.it et censys est toujours bon à bloquer, c'est toujouuuurs des comportements douteux.
  • Une commande non SMTP ? Hey, t'as cru que c'était le web ?

On va donc se créer son propre filtre pour ces cochons, avec un sudo nano /etc/fail2ban/filter.d/XX_perso_postfix.conf1)

# Filtre perso alimenté par les détections de trucs vraiment louches.
[INCLUDES]
before = common.conf
[Definition]
failregex = ^.*\[<HOST>\].*tiscali.it.*
        ^.* NOQUEUE: reject: RCPT from unknown\[<HOST>\]: 504 5.5.2 .* Helo command rejected: need fully-qualified hostname; .*
        ^.*connect from .*censys.*\[<HOST>\]
ignoreregex =
[Init]
journalmatch = _SYSTEMD_UNIT=postfix.service

Notez que chaque ligne de la partie “failregex” correspond à une expression régulière différente. La partie importante est <HOST> qui correspond à l'ip à bannir ; il faut aussi commencer toute regex par ^ afin d'indiquer le début de ligne.

Par ailleurs il faut inclure common.conf au début… et indiquer les logs à checker dans la section Init.

On peut ensuite lancer cette commande pour voir si ça checke des correspondances :

sudo fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/XX_perso_postfix.conf

Dans le résultat, on doit avoir quelque chose comme ça :

Failregex: 21 total
|-  #) [# of hits] regular expression
|   1) [9] ^.* improper command pipelining after CONNECT from unknown\[<HOST>\].*
|   2) [1] ^.*\[<HOST>\].*tiscali.it.*
|   3) [1] ^.* NOQUEUE: reject: RCPT from unknown\[<HOST>\]: 504 5.5.2 .* Helo command rejected: need fully-qualified hostname; .*
|   4) [10] ^.*connect from .*censys.*\[<HOST>\]
`-

Ici j'ai donc 9 correspondances sur la première expression, 1 pour chacune des deux suivants et 10 pour ce sale bot à la fin : c'est bon, ça scanne.

On ajoute ensuite la jail dans notre /etc/fail2ban/jail.d/custom.conf :

[XX_perso_postfix]
#mes propres bidouilles pour virer des chieurs bien repérés
enabled = true
port  = pop3,pop3s,imap2,imaps,submission,465,sieve
filter = XX_perso_postfix
maxretry = 1
findtime = 600
bantime = 30d
action   = iptables-ipset-proto4[name=blocklist_ip, protocol=tcp, bantime=0]
  • Le nom de la jail doit être celui du filtre, visiblement, sinon ben ça bugue.
  • Il va chercher tout seul le filtre dans /etc/fail2ban/filter.d et attends que ça se termine par conf, on ne met que le nom du fichier.
  • Les ports j'ai copié ce qui marchait avec la jail de base de postfix.
  • 1 tentative. Une seule. Limite je me demande pourquoi je déclare le findtime. Et ensuite 30 jours de bannissement !
  • l'action bannit avec ipset, mais là j'ai un peu des doutes sur ce que j'ai fait, ça va demander quelques essais.

Ensuite, on teste si on n'a pas fait de bêtise avec cette commande (ça évitera des agacements) :

sudo fail2ban-server -t

Tout marche ? alors, on charge :

sudo service fail2ban reload

Il faut améliorer les regexp (avec fail2ban-regex). pour virer plus large : - toute ip qui tente de se co en ssh avec un user qui n'est pas autorisé ⇒ ban définitif

Sources

1)
Vous l'appelez comme vous voulez, mais perso j'aime retrouver d'un coup d'œil ce que j'ai bidouillé et le préfixe XX marche bien, et ensuite il faut donner le même nom à la jail pour éviter les soucis.
CC Attribution-Noncommercial-Share Alike 4.0 International Driven by DokuWiki
pratique/informatique/parefeu/fail2ban.txt · Dernière modification : 30/05/2024 08:20 de Zatalyz