Comment protéger SSH avec Fail2Ban sur Ubuntu 20.04
Introduction
SSH est la méthode de facto pour se connecter à un serveur cloud. Il est durable et extensible - à mesure que de nouvelles normes de chiffrement sont développées, elles peuvent être utilisées pour générer de nouvelles clés SSH, garantissant que le protocole principal reste sécurisé. Cependant, aucun protocole ou pile logicielle n'est totalement infaillible, et SSH étant si largement déployé sur Internet signifie qu'il représente une surface d'attaque ou vecteur d'attaque très prévisible à travers laquelle les gens peuvent essayer de accéder.
Tout service exposé au réseau est une cible potentielle de cette manière. Si vous examinez les journaux de votre service SSH exécuté sur un serveur à fort trafic, vous verrez souvent des tentatives de connexion répétées et systématiques qui représentent des attaques par force brute de la part des utilisateurs et des bots. Bien que vous puissiez apporter certaines optimisations à votre service SSH pour réduire les risques de réussite de ces attaques à près de zéro, comme désactiver l'authentification par mot de passe en faveur des clés SSH, elles peuvent toujours constituer une responsabilité mineure et continue.
Les déploiements de production à grande échelle pour lesquels cette responsabilité est totalement inacceptable implémenteront généralement un VPN tel que WireGuard devant leur service SSH, de sorte qu'il est impossible de se connecter directement au port SSH 22 par défaut depuis l'extérieur Internet sans abstraction logicielle ni passerelles supplémentaires. Ces solutions VPN sont largement approuvées, mais ajouteront de la complexité et peuvent casser certaines automatisations ou autres petits crochets logiciels.
Avant ou en plus de vous engager dans une configuration VPN complète, vous pouvez implémenter un outil appelé Fail2ban. Fail2ban peut considérablement atténuer 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 prémunir 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 20.04.
Conditions préalables
Pour compléter ce guide, vous aurez besoin de :
- Un serveur Ubuntu 20.04 et un utilisateur non root avec des privilèges sudo. Vous pouvez en savoir plus sur la configuration d'un utilisateur avec ces privilèges dans notre guide Configuration initiale du serveur avec Ubuntu 20.04.
- En option, un deuxième serveur à partir duquel vous pouvez vous connecter à votre premier serveur, que vous utiliserez pour tester votre bannissement délibéré.
Étape 1 - Installation de Fail2ban
Fail2ban est disponible dans les dépôts de logiciels d'Ubuntu. Commencez par exécuter les commandes suivantes en tant qu'utilisateur non root pour mettre à jour vos listes de packages et installer Fail2ban :
sudo apt update sudo apt install fail2ban
Fail2ban mettra automatiquement en place un service d'arrière-plan après avoir été installé. Cependant, il est désactivé par défaut, car certains de ses paramètres par défaut peuvent provoquer des effets indésirables. Vous pouvez le vérifier en utilisant le systemctl
commande:
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 pouvez 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 /etc/fail2ban
annuaire. Il existe un fichier avec les 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
:
cd /etc/fail2ban head -20 jail.conf
Output# # WARNING: heavily refactored in 0.9.0 release. Please review and # customize settings for your setup. # # Changes: in most of the cases you should not modify this # file, but provide customizations in jail.local file, # or separate .conf files under jail.d/ directory, e.g.: # # HOW TO ACTIVATE JAILS: # # YOU SHOULD NOT MODIFY THIS FILE. # # It will probably be overwritten or improved in a distribution update. # # Provide customizations in a jail.local file or a jail.d/customisation.local. # For example to change the default bantime for all jails and to enable the # ssh-iptables jail the following (uncommented) would appear in the .local file. # See man 5 jail.conf for details. # # [DEFAULT]
Comme vous le verrez, les premières lignes de ce fichier sont commentées - elles commencent par #
caractères indiquant qu'ils doivent être lus comme documentation plutôt que comme paramètres. Comme vous le verrez également, ces commentaires vous demandent de ne pas modifier directement ce fichier. Au lieu de cela, vous avez deux options : soit créer des profils individuels pour Fail2ban dans plusieurs fichiers au sein du jail.d/
répertoire, ou créez et collectez tous vos paramètres locaux dans un jail.local
dossier. La jail.conf
sera périodiquement mis à jour au fur et à mesure que Fail2ban lui-même est mis à jour, et sera utilisé comme source de paramètres par défaut pour lesquels vous n'avez créé aucun remplacement.
Dans ce didacticiel, vous allez créer jail.local
. Vous pouvez le faire en copiant jail.conf
:
sudo cp jail.conf jail.local
Vous pouvez maintenant commencer à modifier la configuration. Ouvrez le fichier dans nano
ou votre éditeur de texte préféré :
sudo nano jail.local
Pendant que vous faites défiler le fichier, ce didacticiel passera en revue certaines options que vous souhaiterez peut-être mettre à jour. Les paramètres situés sous le [DEFAULT]
près du haut du fichier sera appliqué à tous les services pris en charge par Fail2ban. Ailleurs dans le fichier, il y a des en-têtes pour [sshd]
et pour les autres services, qui contiennent des paramètres spécifiques au service qui s'appliqueront en plus des valeurs par défaut.
/etc/fail2ban/jail.local
[DEFAULT] . . . bantime = 10m . . .
La bantime
Le paramètre définit la durée pendant laquelle un client sera banni lorsqu'il n'a pas réussi à s'authentifier correctement. Ceci est mesuré en secondes. Par défaut, il est défini sur 10 minutes.
/etc/fail2ban/jail.local
[DEFAULT] . . . findtime = 10m maxretry = 5 . . .
Les deux paramètres suivants sont findtime
et maxretry
. Ceux-ci travaillent ensemble pour établir les conditions dans lesquelles un client s'avère être un utilisateur illégitime qui devrait être interdit.
La maxretry
définit le nombre d'essais qu'un client doit effectuer 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 entre en action, vous devez évaluer le destemail
, sendername
, et mta
réglages. La destemail
paramètre définit l'adresse e-mail qui doit recevoir les messages d'interdiction. La sendername
définit la valeur du champ "De" dans l'e-mail. La mta
Le paramètre configure le service de messagerie qui sera utilisé pour envoyer le courrier. Par défaut, c'est sendmail
, mais vous pouvez 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 une interdiction. La valeur action_
est défini dans le fichier juste avant ce paramètre. L'action par défaut consiste à mettre à jour la configuration de votre pare-feu pour rejeter le trafic de l'hôte incriminé jusqu'à ce que le délai d'interdiction soit écoulé.
Il y a d'autres action_
scripts fournis par défaut que vous pouvez remplacer $(action_)
avec ci-dessus :
/etc/fail2ban/jail.local
… # ban & send an e-mail with whois report to the destemail. action_mw = %(action_)s %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"] # ban & send an e-mail with whois report and relevant log lines # to the destemail. action_mwl = %(action_)s %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"] # See the IMPORTANT note in action.d/xarf-login-attack for when to use this action # # ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines # to the destemail. action_xarf = %(action_)s xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"] # ban IP on CloudFlare & send an e-mail with whois report and relevant log lines # to the destemail. 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 des mesures et envoie un e-mail, action_mwl
prend des mesures, envoie un e-mail et inclut la journalisation, et action_cf_mwl
fait tout ce qui précède en plus d'envoyer une mise à jour à l'API Cloudflare associée à votre compte pour y bannir également le contrevenant.
Paramètres de prison individuels
Vient ensuite 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 un enabled = true
ligne 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. . Certains autres paramètres définis ici sont les filter
qui sera utilisé pour décider si une ligne dans un journal indique un échec d'authentification et le logpath
qui indique à fail2ban où se trouvent les journaux de ce service particulier.
La filter
value est en fait une référence à un fichier situé dans le /etc/fail2ban/filter.d
répertoire, avec son .conf
extension supprimée. Ces fichiers contiennent des expressions régulières (un raccourci courant pour l'analyse de texte) qui déterminent si une ligne du journal est une tentative d'authentification ayant échoué. Nous ne couvrirons pas ces fichiers en profondeur 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 consultant ce répertoire :
ls /etc/fail2ban/filter.d
Si vous voyez un fichier qui semble lié à un service que vous utilisez, vous devez l'ouvrir avec un éditeur de texte. La plupart des fichiers sont assez bien commentés et vous devriez au moins être en mesure de dire contre quel type de condition le script a été conçu pour se prémunir. La plupart de ces filtres ont des sections appropriées (désactivées) dans le jail.conf
fichier que nous pouvons activer dans le jail.local
fichier si vous le souhaitez.
Par exemple, imaginez que vous servez un site Web en utilisant Nginx et réalisez qu'une partie protégée par mot de passe de votre site est victime de tentatives de connexion. Vous pouvez dire à fail2ban d'utiliser le nginx-http-auth.conf
fichier pour vérifier cette condition dans le /var/log/nginx/error.log
dossier.
Ceci est en fait déjà configuré dans une section appelée [nginx-http-auth]
dans ton /etc/fail2ban/jail.conf
dossier. Il vous suffirait d'ajouter le enabled
paramètre:
/etc/fail2ban/jail.local
. . . [nginx-http-auth] enabled = true . . .
Lorsque vous avez terminé l'édition, enregistrez et fermez le fichier. À ce stade, vous pouvez activer votre service Fail2ban afin qu'il s'exécute automatiquement à partir de maintenant. Première exécution systemctl enable
:
sudo systemctl enable fail2ban
Ensuite, démarrez-le manuellement pour la première fois avec systemctl start
:
sudo systemctl start fail2ban
Vous pouvez vérifier qu'il fonctionne avec systemctl status
:
sudo systemctl status fail2ban
Output● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enab> Active: active (running) since Tue 2022-06-28 19:29: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 28 19:29:15 fail2ban20 systemd[1]: Started Fail2Ban Service. Jun 28 19:29:15 fail2ban20 fail2ban-server[39396]: Server ready
Dans l'étape suivante, vous démontrerez Fail2ban en action.
Étape 3 - Test des politiques d'interdiction (facultatif)
À partir d'un autre serveur, qui n'aura plus 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 :
ssh blah@your_server
Entrez des caractères aléatoires dans l'invite de mot de passe. Répétez cela plusieurs fois. À un moment donné, l'erreur que vous recevez devrait passer de Permission denied
à Connection refused
. Cela signale 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 votre iptables
production. iptables
est une commande permettant d'interagir avec les règles de port et de pare-feu de bas niveau sur votre serveur. Si vous avez suivi le guide de DigitalOcean pour la configuration initiale du serveur, vous utiliserez ufw
pour gérer les règles de pare-feu à un niveau supérieur. Fonctionnement iptables -S
vous montrera toutes les règles de pare-feu qui ufw
déjà créé :
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
à grep
pour rechercher dans ces règles la chaîne f2b
, vous pouvez voir les règles ajoutées par fail2ban :
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é 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 d'interdiction pour vos services. Fail2ban est un moyen utile de protéger tout type de service qui utilise l'authentification. Si vous souhaitez en savoir plus sur le fonctionnement de fail2ban, vous pouvez consulter notre didacticiel sur comment fonctionnent les règles et les fichiers fail2ban.
Pour plus d'informations sur l'utilisation de fail2ban pour protéger d'autres services, vous pouvez lire 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 .