Comment protéger SSH avec Fail2Ban sur Ubuntu 22.04

Introduction

SSH est la méthode de facto pour se connecter à un serveur cloud. Elle est durable et extensible : à mesure que de nouvelles normes de cryptage sont développées, elles peuvent être utilisées pour générer de nouvelles clés SSH, garantissant ainsi que le protocole de base reste sécurisé. Cependant, aucun protocole ou pile logicielle n’est totalement infaillible, et le fait que SSH soit si largement déployé sur Internet signifie qu’il représente une surface d’attaque très prévisible à travers laquelle les gens peuvent essayer de gagner un accès.

Tout service exposé au réseau est une cible potentielle de cette manière. Si vous examinez les journaux de votre service SSH fonctionnant sur un serveur très fréquenté, vous verrez souvent des tentatives de connexion systématiques et répétées qui représentent des attaques par force brute menées par des utilisateurs et des robots. Bien que vous puissiez apporter certaines optimisations à votre service SSH pour réduire les chances que ces attaques réussissent à presque zéro, telles que désactiver l’authentification par mot de passe au profit des clés SSH, elles peuvent néanmoins constituer une petite responsabilité continue.

Les déploiements de production à grande échelle pour lesquels cette responsabilité est totalement inacceptable mettront généralement en place un VPN tel que WireGuard devant leur service SSH, de sorte qu’il soit impossible de se connecter directement au port SSH par défaut 22 depuis l’Internet extérieur sans abstraction logicielle supplémentaire ou passerelles. Ces solutions VPN sont largement fiables, mais elles ajoutent de la complexité et peuvent interrompre certaines automatisations ou autres petits crochets logiciels.

Avant de vous engager dans une configuration VPN complète ou en complément de celle-ci, vous pouvez mettre en œuvre un outil appelé Fail2ban. Fail2ban peut atténuer considérablement les attaques par force brute en créant des règles qui modifient automatiquement la configuration de votre pare-feu pour interdire des adresses IP spécifiques après un certain nombre de tentatives de connexion infructueuses. Cela permettra à votre serveur de se protéger contre ces tentatives d’accès sans intervention de votre part.

Dans ce guide, vous verrez comment installer et utiliser Fail2ban sur un serveur Ubuntu 22.04.

Prérequis

Pour mener à bien ce guide, vous aurez besoin de :

  • Un serveur Ubuntu 22.04 et un utilisateur non root avec des privilèges sudo. Vous pouvez en apprendre davantage sur la façon de configurer un utilisateur avec ces privilèges dans notre guide Configuration initiale du serveur avec Ubuntu 22.04.

  • Facultativement, un deuxième serveur auquel vous pouvez vous connecter depuis votre premier serveur, que vous utiliserez pour tester le fait d’être délibérément banni.

Étape 1 — Installation de Fail2ban

Fail2ban est disponible dans les dépôts logiciels d’Ubuntu. Commencez par exécuter les commandes suivantes en tant qu’utilisateur non root pour mettre à jour vos listes de paquets et installer Fail2ban :

  1. sudo apt update
  2. sudo apt install fail2ban

Fail2ban configurera automatiquement un service en arrière-plan après son installation. Cependant, il est désactivé par défaut, car certains de ses paramètres par défaut peuvent entraîner des effets indésirables. Vous pouvez le vérifier en utilisant la commande systemctl :

  1. systemctl status fail2ban.service
Output
○ fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: enabled Active: inactive (dead) Docs: man:fail2ban(1)

Vous pourriez activer Fail2ban tout de suite, mais d’abord, vous passerez en revue certaines de ses fonctionnalités.

Étape 2 — Configuration de Fail2ban

Le service fail2ban conserve ses fichiers de configuration dans le répertoire /etc/fail2ban. Il y a un fichier avec des valeurs par défaut appelé jail.conf. Allez dans ce répertoire et imprimez les 20 premières lignes de ce fichier en utilisant head -20 :

  1. cd /etc/fail2ban
  2. head -20 jail.conf
Output
# # AVERTISSEMENT : largement refactorisé dans la version 0.9.0. Veuillez examiner et # personnaliser les paramètres pour votre configuration. # # Changements : dans la plupart des cas, vous ne devriez pas modifier ce # fichier, mais fournir des personnalisations dans le fichier jail.local, # ou des fichiers .conf distincts dans le répertoire jail.d/, par exemple : # # COMMENT ACTIVER LES JAILS : # # VOUS NE DEVRIEZ PAS MODIFIER CE FICHIER. # # Il sera probablement écrasé ou amélioré lors d'une mise à jour de la distribution. # # Fournissez des personnalisations dans un fichier jail.local ou jail.d/customisation.local. # Par exemple, pour changer le délai de bannissement par défaut pour tous les jails et activer le # jail ssh-iptables, les lignes suivantes (décommentées) apparaîtraient dans le fichier .local. # Voir man 5 jail.conf pour plus de détails. # # [DEFAULT]

Comme vous le verrez, les premières lignes de ce fichier sont commentées – elles commencent par des caractères # indiquant qu’elles doivent être lues comme de la documentation plutôt que comme des paramètres. Comme vous le verrez également, ces commentaires vous dirigent pour ne pas modifier ce fichier directement. Au lieu de cela, vous avez deux options : soit créer des profils individuels pour Fail2ban dans plusieurs fichiers au sein du répertoire jail.d/, soit créer et rassembler l’ensemble de vos paramètres locaux dans un fichier jail.local. Le fichier jail.conf sera périodiquement mis à jour à mesure que Fail2ban lui-même sera mis à jour, et servira de source de paramètres par défaut pour lesquels vous n’avez pas créé de remplacements.

Dans ce tutoriel, vous allez créer jail.local. Vous pouvez le faire en copiant jail.conf :

  1. sudo cp jail.conf jail.local

Maintenant, vous pouvez commencer à apporter des modifications de configuration. Ouvrez le fichier dans nano ou votre éditeur de texte préféré :

  1. sudo nano jail.local

Pendant que vous parcourez le fichier, ce tutoriel passera en revue certaines options que vous voudrez peut-être mettre à jour. Les paramètres situés sous la section [DEFAULT] près du haut du fichier seront appliqués à tous les services pris en charge par Fail2ban. Ailleurs dans le fichier, il y a des en-têtes pour [sshd] et pour d’autres services, qui contiennent des paramètres spécifiques au service qui s’appliqueront par-dessus les paramètres par défaut.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
bantime = 10m
. . .

Le paramètre bantime définit la durée pendant laquelle un client sera banni s’il a échoué à s’authentifier correctement. Cela est mesuré en secondes. Par défaut, cela est réglé à 10 minutes.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .

Les deux prochains paramètres sont findtime et maxretry. Ils travaillent ensemble pour établir les conditions selon lesquelles un client est considéré comme un utilisateur illégitime qui doit être banni.

La variable maxretry définit le nombre de tentatives qu’un client a pour s’authentifier dans une fenêtre de temps définie par findtime, avant d’être banni. Avec les paramètres par défaut, le service fail2ban bannira un client qui tente sans succès de se connecter 5 fois dans une fenêtre de 10 minutes.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .

Si vous avez besoin de recevoir des alertes par e-mail lorsque Fail2ban agit, vous devez évaluer les paramètres destemail, sendername et mta. Le paramètre destemail définit l’adresse e-mail qui doit recevoir les messages de bannissement. Le sendername définit la valeur du champ « De » dans l’e-mail. Le paramètre mta configure le service de messagerie qui sera utilisé pour envoyer des e-mails. Par défaut, il s’agit de sendmail, mais vous pouvez vouloir utiliser Postfix ou une autre solution de messagerie.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
action = $(action_)s
. . .

Ce paramètre configure l’action que Fail2ban prend lorsqu’il veut instituer un bannissement. La valeur action_ est définie dans le fichier peu avant ce paramètre. L’action par défaut est de mettre à jour la configuration de votre pare-feu pour rejeter le trafic provenant de l’hôte fautif jusqu’à ce que le temps de bannissement soit écoulé.

Il existe d’autres scripts action_ fournis par défaut que vous pouvez remplacer $(action_) par ci-dessus:

/etc/fail2ban/jail.local
…
# bannir et envoyer un e-mail avec le rapport whois à l'adresse de destination.
action_mw = %(action_)s
            %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# bannir et envoyer un e-mail avec le rapport whois et les lignes de journal pertinentes
# à l'adresse de destination.
action_mwl = %(action_)s
             %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]

# Voir la note IMPORTANTE dans action.d/xarf-login-attack pour savoir quand utiliser cette action
#
# bannir et envoyer un e-mail xarf au contact d'abus de l'adresse IP et inclure les lignes de journal pertinentes
# à l'adresse de destination.
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]

# bannir l'IP sur CloudFlare et envoyer un e-mail avec le rapport whois et les lignes de journal pertinentes
# à l'adresse de destination.
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
…

Par exemple, action_mw prend une action et envoie un e-mail, action_mwl prend une action, envoie un e-mail et inclut un journal, et action_cf_mwl fait tout cela en plus d’envoyer une mise à jour à l’API Cloudflare associée à votre compte pour bannir le contrevenant là-bas également.

Paramètres de prison individuels

Ensuite, voici la partie du fichier de configuration qui traite des services individuels. Ceux-ci sont spécifiés par des en-têtes de section, comme [sshd].

Chacune de ces sections doit être activée individuellement en ajoutant une ligne enabled = true sous l’en-tête, avec leurs autres paramètres.

/etc/fail2ban/jail.local
[jail_to_enable]
. . .
enabled = true
. . .

Par défaut, le service SSH est activé et tous les autres sont désactivés.
.
D’autres paramètres définis ici sont le filter qui sera utilisé pour décider si une ligne dans un journal indique une authentification échouée et le logpath qui indique à fail2ban où se trouvent les journaux pour ce service particulier.

La valeur du filter est en fait une référence à un fichier situé dans le répertoire /etc/fail2ban/filter.d, avec son extension .conf supprimée. Ces fichiers contiennent des expressions régulières (une abréviation courante pour l’analyse de texte) qui déterminent si une ligne dans le journal est une tentative d’authentification échouée. Nous n’allons pas couvrir ces fichiers en détail dans ce guide, car ils sont assez complexes et les paramètres prédéfinis correspondent bien aux lignes appropriées.

Cependant, vous pouvez voir quels types de filtres sont disponibles en regardant dans ce répertoire :

  1. ls /etc/fail2ban/filter.d

Si vous voyez un fichier qui semble lié à un service que vous utilisez, vous devriez l’ouvrir avec un éditeur de texte. La plupart des fichiers sont assez bien commentés et vous devriez au moins pouvoir dire quel type de condition le script a été conçu pour protéger contre. La plupart de ces filtres ont des sections appropriées (désactivées) dans le fichier jail.conf que nous pouvons activer dans le fichier jail.local si nécessaire.

Par exemple, imaginez que vous servez un site web en utilisant Nginx et que vous réalisez qu’une partie de votre site protégée par mot de passe est attaquée avec de nombreuses tentatives de connexion. Vous pouvez dire à fail2ban d’utiliser le fichier nginx-http-auth.conf pour vérifier cette condition dans le fichier /var/log/nginx/error.log.

Cela est en fait déjà configuré dans une section appelée [nginx-http-auth] dans votre fichier /etc/fail2ban/jail.conf. Vous auriez juste besoin d’ajouter le paramètre enabled:

/etc/fail2ban/jail.local
. . .
[nginx-http-auth]

enabled = true
. . .

Lorsque vous avez terminé d’éditer, enregistrez et fermez le fichier. À ce stade, vous pouvez activer votre service Fail2ban afin qu’il s’exécute automatiquement à partir de maintenant. Tout d’abord, exécutez systemctl enable:

  1. sudo systemctl enable fail2ban

Ensuite, démarrez-le manuellement pour la première fois avec systemctl start:

  1. sudo systemctl start fail2ban

Vous pouvez vérifier qu’il fonctionne avec systemctl status:

  1. sudo systemctl status fail2ban
Output
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enab> Active: active (running) since Mon 2022-06-27 19:25:15 UTC; 3s ago Docs: man:fail2ban(1) Main PID: 39396 (fail2ban-server) Tasks: 5 (limit: 1119) Memory: 12.9M CPU: 278ms CGroup: /system.slice/fail2ban.service └─39396 /usr/bin/python3 /usr/bin/fail2ban-server -xf start Jun 27 19:25:15 fail2ban22 systemd[1]: Started Fail2Ban Service. Jun 27 19:25:15 fail2ban22 fail2ban-server[39396]: Server ready

À l’étape suivante, vous allez démontrer Fail2ban en action.

Étape 3 — Test des politiques de bannissement (Facultatif)

À partir d’un autre serveur, un qui n’aura pas besoin de se connecter à votre serveur Fail2ban à l’avenir, vous pouvez tester les règles en faisant bannir ce deuxième serveur. Après vous être connecté à votre deuxième serveur, essayez de vous connecter en SSH au serveur Fail2ban. Vous pouvez essayer de vous connecter en utilisant un nom inexistant :

  1. ssh blah@your_server

Entrez des caractères aléatoires dans la boîte de dialogue du mot de passe. Répétez cette opération plusieurs fois. À un moment donné, l’erreur que vous recevez devrait changer de Permission denied à Connection refused. Cela indique que votre deuxième serveur a été banni du serveur Fail2ban.

Sur votre serveur Fail2ban, vous pouvez voir la nouvelle règle en vérifiant la sortie de votre iptables. iptables est une commande pour interagir avec les règles de port et de pare-feu de bas niveau sur votre serveur. Si vous avez suivi le guide de configuration initiale du serveur de DigitalOcean, vous utiliserez ufw pour gérer les règles de pare-feu à un niveau supérieur. L’exécution de iptables -S vous montrera toutes les règles de pare-feu que ufw a déjà créées:

  1. sudo iptables -S
Output
-P INPUT DROP -P FORWARD DROP -P OUTPUT ACCEPT -N f2b-sshd -N ufw-after-forward -N ufw-after-input -N ufw-after-logging-forward -N ufw-after-logging-input -N ufw-after-logging-output -N ufw-after-output -N ufw-before-forward -N ufw-before-input -N ufw-before-logging-forward -N ufw-before-logging-input -N ufw-before-logging-output …

Si vous redirigez la sortie de iptables -S vers grep pour rechercher dans ces règles la chaîne f2b, vous pouvez voir les règles qui ont été ajoutées par fail2ban:

  1. sudo iptables -S | grep f2b
Output
-N f2b-sshd -A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd -A f2b-sshd -s 134.209.165.184/32 -j REJECT --reject-with icmp-port-unreachable -A f2b-sshd -j RETURN

La ligne contenant REJECT --reject-with icmp-port-unreachable aura été ajoutée par Fail2ban et devrait refléter l’adresse IP de votre deuxième serveur.

Conclusion

Vous devriez maintenant être en mesure de configurer certaines politiques de bannissement pour vos services. Fail2ban est un moyen utile de protéger tout type de service qui utilise une authentification. Si vous souhaitez en savoir plus sur le fonctionnement de fail2ban, vous pouvez consulter notre tutoriel sur comment les règles et les fichiers de fail2ban fonctionnent.

Pour des informations sur la manière d’utiliser fail2ban pour protéger d’autres services, vous pouvez lire sur Comment Protéger un Serveur Nginx avec Fail2Ban sur Ubuntu 14.04 et Comment Protéger un Serveur Apache avec Fail2Ban sur Ubuntu 14.04.

Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-22-04