Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
pratique:informatique:fail2ban [01/10/2023 20:18] – [Bannir des plages d'ip] Zatalyzpratique:informatique:fail2ban [23/01/2024 11:48] (Version actuelle) – [Commandes Iptables utiles] Zatalyz
Ligne 1: Ligne 1:
 ====== Fail2ban et Iptables ====== ====== Fail2ban et Iptables ======
 +
 +<WRAP center round important 100%>
 +Tout ça n'est pas encore au point. 
 +
 +À un moment faudra que tout ça soit revu de fond en comble... J'apprends petit à petit.
 +
 +En attendant, n'utilisez pas ça "comme ça", ne croyez pas à la qualité de ce qui est là !
 +</WRAP>
 +
 Fail2ban logiciel me file des boutons mais je n'ai pas vraiment trouvé de remplaçant. 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. Fail2ban logiciel me file des boutons mais je n'ai pas vraiment trouvé de remplaçant. 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.
  
Ligne 75: Ligne 84:
 #-A INPUT -m set --match-set blocklist_ip src -j DROP #-A INPUT -m set --match-set blocklist_ip src -j DROP
 # Ça, ça ne veut pas... # Ça, ça ne veut pas...
 +
 +#rejeter tout le reste 
 +-A INPUT -j REJECT --reject-with icmp-port-unreachable
  
 </code> </code>
 +
 ==== Commandes Iptables utiles ==== ==== Commandes Iptables utiles ====
 Lister "tout" en vrac :  Lister "tout" en vrac : 
Ligne 86: Ligne 99:
   iptables -L INPUT --line-numbers   iptables -L INPUT --line-numbers
  
 +Sauf que ce n'est pas "tout", genre pour lister les règles nat :
 +  iptables -t nat -S
 + 
 Enlever une règle d'après son numéro de ligne Enlever une règle d'après son numéro de ligne
   iptables -D INPUT 14   iptables -D INPUT 14
Ligne 91: Ligne 107:
 Restaurer des règles  Restaurer des règles 
   iptables-restore /etc/iptables/rules.v4   iptables-restore /etc/iptables/rules.v4
 +
 +==== Quelques explications ====
 +=== Différence entre -I et -A ===
 +  * ''-I'' signifie "insérer la règle à la ligne n° X" ; sans préciser de numéro, la règle se retrouve au début et a donc la priorité sur tout autre.
 +  * ''-A'' indique d'ajouter donc ce sera à la suite du reste des règles.
 +
 +Bref, quand on a un fichier qui charge les règles, elles sont forcément les unes après les autres, ''-A'' est indiqué. Si on teste une règle, alors ''-I'' peut être plus pertinent. 
 +
 +=== DROP ou REJECT --reject-with icmp-port-unreachable ===
 +  * ''DROP'' ignore complètement le paquet (comme si le serveur n'existait pas). Il ne renvoie pas de message, ce qui évite les attaques où on force le serveur à envoyer des messages icmp à un autre serveur par exemple.
 +  * ''REJECT --reject-with icmp-port-unreachable'' renvoie un message icmp disant que le port est fermé (comme si le service qui écoute sur ce port n'était pas lancé et que le port était inutilisé).
 +
 +
 +
 +=== Ordre des règles ===
 +Les règles sont appliquées dans l'ordre. 
 +
 +Donc il faut que les commandes d'ipset et fail2ban soient avant celles qui acceptent une connexion : 
 +  - On regarde si l'un de ces logiciels dit qu'il faut bloquer l'ip 
 +    - Si oui, elle dégage
 +    - Si non, on passe à la règle suivante
 +  - La règle suivante étant "on accepte".
 +
 +Sinon, ça serait :
 +  - On accepte la connexion
 +  - On regarde si fail2ban... ah ben non, forcément, ça ne marche pas, puisque la connexion est acceptée. 
  
 ===== Ipset ===== ===== Ipset =====
-Créer une entrée pour toutes les ip qui vont être renvoyées dans les limbes (adapter le nom ''blocklist_ip'':+Créer une entrée pour toutes les ip qui vont être renvoyées dans les limbes (adapter le nom ''blocklist_ip''):
   ipset create blocklist_ip hash:ip   ipset create blocklist_ip hash:ip
  
Ligne 205: Ligne 247:
   fail2ban-server -t   fail2ban-server -t
   systemctl restart fail2ban   systemctl restart fail2ban
-==== À faire ====+   
 +==== 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 :
 +<code>
 +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
 +</code>
 +  * 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''((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.))
 +<code>
 +# 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
 +
 +</code>
 +
 +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 : 
 +<code>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>\]
 +`-
 +</code>
 +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'' :
 +<code>
 +[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]
 +</code>
 +  * 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
  
 <WRAP center round todo 100%> <WRAP center round todo 100%>
 Il faut améliorer les regexp (avec fail2ban-regex). pour virer plus large : 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  - toute ip qui tente de se co en ssh avec un user qui n'est pas autorisé => ban définitif 
-- toute ip qui passe des commandes à postfix qui ne sont pas "valides" => idem 
 </WRAP> </WRAP>
-La ligne postfix que j'aimerais détecter pour bannir, car trop louche :  
-  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 
  
 ===== Bannir définitivement les IP harcelantes ===== ===== Bannir définitivement les IP harcelantes =====
Ligne 331: Ligne 461:
 et ''ipset list'' va nous montrer les 254 nouvelles adresses bloquées... Pfiou ! et ''ipset list'' va nous montrer les 254 nouvelles adresses bloquées... Pfiou !
  
-==== D'où viennent les attaques ? ====+===== D'où viennent les attaques ? =====
 Là c'est de la curiosité car je ne pense pas que je puisse y faire grand chose. Mais, quand même, ça permet de voir la pertinence (ou pas) de bloquer un pays.  Là c'est de la curiosité car je ne pense pas que je puisse y faire grand chose. Mais, quand même, ça permet de voir la pertinence (ou pas) de bloquer un pays. 
  
Ligne 353: Ligne 483:
  
 Si je ne me vois pas bloquer ces pays (même la Chine), je me demande s'il y a moyen de filtrer quel pays a le droit de tester certaines actions, comme se connecter à un compte mail. Si je ne me vois pas bloquer ces pays (même la Chine), je me demande s'il y a moyen de filtrer quel pays a le droit de tester certaines actions, comme se connecter à un compte mail.
 +
 +==== Une alternative via systemd ====
 +Pour les IPs qui ont le plus chercher à se connecter au serveur mail sans succès, pour une journée donnée : 
 +  journalctl --since=2023-10-06 --until=2023-10-07 --grep='SASL LOGIN authentication failed' --unit=postfix@-.service | sed 's/.*warning: \([^ ]*\): .*$/\1/' | sort | uniq --count | sort --human-numeric-sort --reverse | head
 +
 +Et juste pour le jour même : 
 +  journalctl --since=today --grep='SASL LOGIN authentication failed' --unit=postfix@-.service | sed 's/.*warning: \([^ ]*\): .*$/\1/' | sort | uniq --count | sort --human-numeric-sort --reverse | head
 +
  
 ===== Sources ===== ===== Sources =====
Ligne 365: Ligne 503:
   * https://www.malekal.com/comment-utiliser-ipset-sur-linux/   * https://www.malekal.com/comment-utiliser-ipset-sur-linux/
   * https://sysreseau.net/iptables-12-commandes/   * https://sysreseau.net/iptables-12-commandes/
 +  * http://www.delafond.org/traducmanfr/man/man8/iptables.8.html
  
  
CC Attribution-Noncommercial-Share Alike 4.0 International Driven by DokuWiki
pratique/informatique/fail2ban.1696184317.txt.gz · Dernière modification : 01/10/2023 20:18 de Zatalyz