Sécuriser SSH avec iptables

Recettes iptables pratiques pour sécuriser l'accès SSH.

iptables est un utilitaire en ligne de commande et l'interface standard pour gérer le pare-feu Netfilter intégré au noyau Linux. Il permet de créer et de modifier des règles qui contrôlent la façon dont les paquets réseau sont filtrés et acheminés. L'utilisation d'iptables nécessite les privilèges root.

Concepts fondamentaux

Une règle se compose d'un critère de correspondance, d'une action cible et d'un compteur de paquets. Lorsqu'un paquet entrant satisfait le critère, l'action est appliquée et le compteur s'incrémente. Les règles sont évaluées dans l'ordre — la séquence est importante.

  • Critère — une expression logique qui inspecte les propriétés du paquet et de la connexion pour déterminer si une règle s'applique. Plusieurs critères sont combinés par un ET logique.
  • Action (cible) — ce qu'il faut faire avec un paquet lorsqu'il correspond : l'accepter, le rejeter, le transmettre à une autre chaîne, etc.
  • Compteur — suit le nombre de paquets ayant correspondu à la règle et leur taille totale en octets.

Une chaîne est une liste ordonnée de règles. Il en existe deux types :

  • Chaînes intégrées — créées automatiquement lors de l'initialisation d'une table. Chacune dispose d'une politique par défaut qui s'applique à tout paquet ne correspondant à aucune autre règle. Les noms des chaînes intégrées sont toujours en majuscules : PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING.
  • Chaînes définies par l'utilisateur — créées manuellement, limitées à leur propre table. Utilisez des noms en minuscules pour éviter toute confusion avec les chaînes intégrées et les cibles.

Une table est un ensemble de chaînes regroupées par fonction. Les noms de tables sont en minuscules. Vous spécifiez une table avec le flag -t nom_table — si omis, iptables utilise filter par défaut.

1. Limitation du taux de connexions (protection contre le brute force)

Pour se protéger contre le brute force sur les mots de passe, vous pouvez limiter le nombre de nouvelles connexions SSH depuis une même IP — par exemple, 2 tentatives par minute — et rejeter tout ce qui dépasse ce seuil.

## Créer la chaîne sshguard
/sbin/iptables -N sshguard

# Optionnel : journaliser les tentatives bloquées
#/sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --rcheck --seconds 60 --hitcount 2 -j LOG --log-prefix "SSH-shield: "

# Rejeter les connexions dépassant le taux limite
/sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --update --seconds 60 --hitcount 2 -j DROP

# Accepter et enregistrer l'IP si elle est sous le seuil
/sbin/iptables -A sshguard -m state --state NEW -m recent --name SSH --set -j ACCEPT
/sbin/iptables -A sshguard -j ACCEPT

## Acheminer tout le trafic SSH via sshguard
/sbin/iptables -A INPUT -p tcp --dport 22 -j sshguard

Ces règles reposent sur le module noyau recent, qui gère des listes dynamiques d'adresses IP. Voici ce que fait chaque option :

  • --name name — le nom de la liste d'IP à utiliser (par défaut : DEFAULT)
  • --rcheck — vérifie si l'IP de l'expéditeur est dans la liste ; retourne false si non trouvée
  • --update — identique à --rcheck, mais actualise également l'horodatage si l'IP est trouvée
  • --hitcount hits — retourne true lorsque le nombre de paquets provenant d'une IP atteint ou dépasse la valeur spécifiée ; utilisé avec --rcheck ou --update
  • --seconds seconds — définit la durée pendant laquelle une IP reste dans la liste après avoir été ajoutée
  • --set — ajoute l'IP de l'expéditeur à la liste, ou met à jour son entrée si elle est déjà présente
  • --remove — supprime une IP de la liste ; retourne false si non trouvée

Important

Utiliser --update au lieu de --rcheck signifie que chaque nouvelle tentative de connexion remet le minuteur à zéro. Si quelqu'un continue d'essayer sans attendre, son délai de 60 secondes recommence à chaque fois.

2. Ouverture et fermeture dynamique du port SSH (port knocking)

Plutôt que de laisser SSH exposé en permanence, vous pouvez le masquer derrière une séquence de frappe. Le port ne s'ouvre que pour l'IP qui envoie la bonne séquence — et se referme à la demande.

Pour ouvrir l'accès SSH, frappez d'abord le port 1500 — via telnet :

telnet myserver 1500

ou directement depuis un navigateur :

http://192.168.0.100:1500

Pour le refermer, frappez le port 1499.

iptables -N sshguard

# Autoriser la connexion si l'IP est déjà dans la liste
iptables -A sshguard -m state --state NEW -m recent --rcheck --name SSH -j ACCEPT

# Autoriser les paquets des connexions déjà établies
iptables -A sshguard -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A sshguard -j DROP

# Ouverture : ajouter l'IP à la liste lorsque le port 1500 est touché
#iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1500 -j LOG --log-prefix "SSH-open: "
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1500 -m recent --name SSH --set -j DROP

# Fermeture : retirer l'IP de la liste lorsque le port 1499 est touché
iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 1499 -m recent --name SSH --remove -j DROP

## Acheminer le trafic SSH via sshguard
iptables -A INPUT -p tcp --dport 22 -j sshguard

L'accès est accordé uniquement à l'IP qui a effectué la frappe.

3. Accès SSH à durée limitée

Cette approche permet d'ouvrir SSH pour une IP spécifique pendant une fenêtre de temps fixe — utile lorsque vous avez besoin d'un accès temporaire sans laisser un port exposé en permanence.

## Créer et vider la chaîne sshguard
iptables -N sshguard
iptables -F sshguard

# Autoriser la connexion si l'IP est dans la liste et vue pour la dernière fois dans les 30 heures (108000 secondes)
iptables -A sshguard -m state --state NEW -m recent --update --seconds 108000 --name SSH -j ACCEPT

# Autoriser les paquets des connexions déjà établies
iptables -A sshguard -m state --state ESTABLISHED,RELATED -j ACCEPT

# Rejeter tout le reste
iptables -A sshguard -j DROP

## Enregistrer l'IP lorsque le port 222 est touché
iptables -A INPUT -m state --state NEW -p tcp --dport 222 -m recent --name SSH --set

## Acheminer le trafic SSH via sshguard
iptables -A INPUT -p tcp --dport 22 -j sshguard

Pour obtenir l'accès, connectez-vous d'abord au port 222 :

ssh user@server.name -p 222

Après cela, votre IP disposera d'un accès SSH pour la durée spécifiée. Chaque nouvelle connexion SSH renouvelle le minuteur. Si vous préférez ne pas prolonger la fenêtre à chaque connexion, remplacez --update --seconds 108000 par --rcheck.

L'accès est accordé uniquement à l'IP qui a effectué la connexion initiale.

Pour voir quelles IP ont actuellement accès à SSH :

cat /proc/net/ipt_recent/SSH

Aide

Une question ou besoin d'un coup de main ? Écrivez-nous via le système de tickets — nous sommes toujours là pour vous aider !

Besoin d’aide?Nos ingénieurs vous aideront gratuitement pour n’importe quelle question en quelques minutesNous contacter