rss logo

Sécuriser SSH sous Linux avec le pare-feu nftables

Logo OpenSSH avec un tampon rouge 'Protected by nftables'

Dans un article précédent, j’ai expliqué comment sécuriser SSH avec une authentification à deux facteurs (2FA). En complément du 2FA, vous pouvez renforcer la sécurité SSH en utilisant le pare-feu netfilter, géré avec nftables. Cette approche permet de restreindre l’accès afin que seules les adresses IP de confiance puissent se connecter à votre serveur Linux. Les deux protections, 2FA et nftables, sont complémentaires et peuvent être combinées pour une sécurité maximale.

La mise en place de règles nftables pour SSH est relativement simple, il n’y a donc aucune raison de ne pas les appliquer.

Cette méthode est particulièrement utile si seules quelques adresses IP connues doivent être autorisées à se connecter. Vous pouvez également appliquer un filtrage géographique, en restreignant l’accès par pays ou région grâce aux listes d’adresses IP fournies par IPdeny, comme nous le verrons dans la dernière partie de ce tutoriel.

Autoriser l’accès SSH avec une whitelist d’IP

Par exemple, imaginons que nous souhaitions uniquement autoriser l’accès depuis notre réseau local (192.168.0.0/24) et deux adresses IP publiques spécifiques : 198.51.100.51 et 2001:db8:51d:dead:bee5::1. Toutes les autres IP seront bloquées.

Schéma du pare-feu SSH avec whitelist

Schéma du pare-feu Linux nftables protégeant un serveur SSH, bloquant les IP non fiables et autorisant uniquement les utilisateurs valides
Le pare-feu nftables autorise l’accès SSH uniquement depuis des adresses IP de confiance et bloque toutes les autres.

Configurer le fichier /etc/nftables.conf pour SSH

💡 Note : Dans cet exemple, les règles nftables sont spécifiquement centrées sur SSH et volontairement simplifiées. L’objectif est uniquement de sécuriser le service SSH. Pour des configurations nftables plus avancées (incluant d’autres protocoles), consultez mon guide : Comment configurer des règles nftables depuis zéro.

  • Éditez le fichier /etc/nftables.conf :
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
        chain input {
                type filter hook input priority filter; policy accept; # Default: accept all
                iif lo accept comment "Accept any localhost traffic"
                ip saddr { 192.168.0.0/24, 198.51.100.51 } tcp dport { ssh } ct state { new, related, established } counter accept comment "Allow SSH from specific IPv4"
		ip6 saddr { 2001:db8:51d:dead:bee5::1 } tcp dport { ssh } ct state { new, related, established } counter accept comment "Allow SSH from specific IPv6"
                tcp dport { ssh } ct state { new, related, established } counter drop comment "Block all other SSH attempts"

        }
        chain forward {
                type filter hook forward priority filter; policy accept; # Default: accept all
        }
        chain output {
                type filter hook output priority filter; policy accept; # Default: accept all
        }
}
  • Après avoir modifié le fichier /etc/nftables.conf, chargez les règles nftables :
root@debian:~# nft -f /etc/nftables.conf
  • Activez le service nftables afin qu’il démarre automatiquement au boot :
root@debian:~# systemctl enable nftables.service

Autoriser l’accès SSH avec des restrictions Geo-IP

Comme expliqué dans l’introduction, nous allons utiliser les listes IPdeny pour appliquer un filtrage Geo-IP. Les listes IPdeny sont des collections gratuites de plages d’adresses IP regroupées par pays ou par région, qui peuvent être utilisées pour autoriser ou bloquer le trafic réseau en fonction de la localisation géographique.

Dans cet exemple, nous voulons uniquement autoriser les connexions SSH depuis la France 😇 (en IPv4 et en IPv6). Nous allons commencer par télécharger la liste IPv4 de la France et la liste IPv6 de la France.

Schéma du filtrage SSH par Geo-IP

Schéma montrant le pare-feu nftables autorisant SSH depuis la France et bloquant les IP en provenance du Piratistan
Le pare-feu nftables est configuré pour autoriser l’accès SSH depuis la France et bloquer les connexions en provenance de régions non autorisées comme le « Piratistan ».

Télécharger et formater les listes IPdeny pour le filtrage Geo-IP

💡 Note : Ce guide a été testé avec nftables version 1.1.3. Assurez-vous que votre version prend en charge la directive include avant d’utiliser ces exemples.

Nous devons formater notre fichier de liste d’IP afin qu’il corresponde à la syntaxe attendue par nftables. Par exemple, la liste IPv6 pour la France 🇫🇷 devrait ressembler à ceci :

set fr_aggregated_v6 {
    type ipv6_addr
    flags interval
    elements = {
2001:0504:0118:0000:0000:0000:0000:0000/48,
2001:0660:0000:0000:0000:0000:0000:0000/29,
2a14:f100:0000:0000:0000:0000:0000:0000/29,
2a14:f400:0000:0000:0000:0000:0000:0000/29,
2a14:fa80:0000:0000:0000:0000:0000:0000/29
    }
}

Par défaut, les listes IPdeny sont fournies dans un format brut, comme ceci :

2001:0504:0118:0000:0000:0000:0000:0000/48
2001:0660:0000:0000:0000:0000:0000:0000/29
2a14:f100:0000:0000:0000:0000:0000:0000/29
2a14:f400:0000:0000:0000:0000:0000:0000/29
2a14:fa80:0000:0000:0000:0000:0000:0000/29

Mais pas de panique — je vais vous montrer ci-dessous comment reformater les listes IPdeny étape par étape !

  • Commencez par télécharger les listes avec wget et enregistrez‑les sous fr-aggregated-v4.zone et fr-aggregated-v6.zone. Par exemple, voici les commandes pour les IP françaises :
root@debian:~# wget https://www.ipdeny.com/ipblocks/data/aggregated/fr-aggregated.zone -O fr-aggregated-v4.zone
root@debian:~# wget https://www.ipdeny.com/ipv6/ipaddresses/aggregated/fr-aggregated.zone -O fr-aggregated-v6.zone

Selon le pays que vous souhaitez autoriser, vous constaterez peut‑être qu’il y a un grand nombre de lignes à mettre en forme. Heureusement, nous pouvons utiliser la commande sed pour automatiser cette tâche.

  • Pour la liste IPv4 (fr-aggregated-v4.zone), utilisez la commande suivante :
root@debian:~# sed -i -e 's/$/,/' -e '${s/,$/\n    }\n}/}' -e '1s/^/set fr_aggregated_v4 {\n    type ipv4_addr\n    flags interval\n    elements = {\n/' fr-aggregated-v4.zone
  • Pour la liste IPv6 (fr-aggregated-v6.zone), utilisez la commande suivante :
root@debian:~# sed -i -e 's/$/,/' -e '${s/,$/\n    }\n}/}' -e '1s/^/set fr_aggregated_v6 {\n    type ipv6_addr\n    flags interval\n    elements = {\n/' fr-aggregated-v6.zone
  • Enfin, déplacez les fichiers fr-aggregated-v4.zone et fr-aggregated-v6.zone dans le répertoire /etc/nftables (créez‑le au préalable s’il n’existe pas) :
root@debian:~# mkdir -p /etc/nftables
root@debian:~# mv fr-aggregated-v4.zone fr-aggregated-v6.zone -t /etc/nftables

Ajout de règles SSH Geo-IP dans /etc/nftables.conf

  • Ensuite, ajoutez les listes au fichier /etc/nftables.conf en le modifiant comme suit :
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
	include "/etc/nftables/fr-aggregated-v4.zone"
	include "/etc/nftables/fr-aggregated-v6.zone"
        chain input {
                type filter hook input priority filter; policy accept; # Default: accept all
                iif lo accept comment "Allow localhost traffic"
                ip saddr { 192.168.0.0/24 } tcp dport { ssh } ct state { new, related, established } counter accept comment "Allow SSH from LAN"
                ip saddr @fr_aggregated_v4 tcp dport { ssh } ct state { new, related, established } counter accept comment "Allow SSH from France (IPv4)"
                ip6 saddr @fr_aggregated_v6 tcp dport { ssh } ct state { new, related, established } counter accept comment "Allow SSH from France (IPv6)"
                tcp dport { ssh } ct state { new, related, established } counter drop comment "Block SSH from any other IP"

        }
        chain forward {
                type filter hook forward priority filter; policy accept; # Default: accept all
        }
        chain output {
                type filter hook output priority filter; policy accept; # Default: accept all
        }
}

Comme dans l’exemple de la liste blanche d’IP, une fois que vous avez modifié le fichier /etc/nftables.conf, suivez ces étapes :

  • Chargez les nouvelles règles nftables :
root@debian:~# nft -f /etc/nftables.conf
  • Activez le service nftables afin qu’il démarre automatiquement au démarrage :
root@debian:~# systemctl enable nftables.service