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
Mise à jour nftables
Pour utiliser fail2ban avec nftables, et utiliser les logs de journalctl, le début du fichier doit ressemble à ceci :
[DEFAULT] [...] banaction = nftables-multiport banaction_allports = nftables-allports backend = systemd
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.conf
1)
# 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 parconf
, 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