Lire le journal d'authentification SSH : ce que signifie chaque ligne d'échec

Où sont enregistrées les connexions SSH échouées selon la distribution, comment décoder les variantes de messages, et comment distinguer une faute de frappe d'un botnet qui déroule une liste.

8 min de lecture

Où se trouve réellement le journal

C'est le premier piège, car cela dépend de la distribution. Debian et Ubuntu écrivent les événements d'authentification dans /var/log/auth.log. RHEL, CentOS, AlmaLinux, Rocky et Fedora utilisent /var/log/secure. Les systèmes entièrement passés à journald peuvent n'avoir aucun de ces fichiers, et tout vit dans le journal.

La réponse portable est journalctl, qui fonctionne partout où systemd tourne :

bash
# Portable : lire le journal de sshd, en temps réel
journalctl -u ssh -f          # nom d'unité Debian/Ubuntu
journalctl -u sshd -f         # nom d'unité RHEL/Fedora

# Uniquement les échecs, dernières 24 heures
journalctl -u ssh --since -24h | grep -E 'Failed|Invalid user'

# Sur les distributions qui écrivent encore le fichier :
grep -E 'Failed|Invalid user' /var/log/auth.log     # Debian/Ubuntu
grep -E 'Failed|Invalid user' /var/log/secure       # famille RHEL

Les variantes de messages, décodées

sshd émet un petit ensemble de messages d'échec, et chacun signifie quelque chose de précis. Ces cinq-là couvrent presque tout ce que vous verrez :

  • Failed password for <user> from <ip> port <n> ssh2 — le compte existe, le mot de passe était faux. Soit un vrai utilisateur qui se trompe, soit un bot qui a deviné un identifiant valide.
  • Failed password for invalid user <user> from <ip> — le compte n'existe pas. Presque toujours une attaque : vos utilisateurs connaissent leurs identifiants. Généralement accompagné d'une ligne « Invalid user » distincte.
  • Connection closed by authenticating user <user> <ip> port <n> [preauth] — le client a abandonné en cours d'authentification. Typique des scanners qui ne voulaient que la bannière, et des serveurs tout-clé rejetant les tentatives par mot de passe.
  • Disconnected from authenticating user root <ip> port <n> [preauth] — une tentative root sur un serveur où root est interdit. Un volume élevé ici est la signature la plus courante sur un hôte exposé.
  • Maximum authentication attempts exceeded for <user> from <ip> — le client a atteint MaxAuthTries sur une connexion. Souvent un agent proposant de nombreuses clés, mais depuis une adresse inconnue c'est un bot qui déroule des identifiants.

Distinguer une attaque d'une faute de frappe

Trois signaux les séparent, et il vous les faut tous les trois avant d'agir automatiquement.

Rythme et persistance. Une personne fait deux ou trois tentatives en une minute puis entre ou vous appelle. Un bot maintient un rythme constant pendant des heures, toute la nuit, sans pause.

Diversité des comptes. Une personne essaie un compte : le sien. Un bot déroule une liste, et la plupart de ces comptes n'existent pas — précisément la signature « invalid user » ci-dessus.

Source. Vos collaborateurs se connectent depuis une poignée d'adresses connues. Les attaques arrivent de plages d'hébergement, depuis une adresse différente toutes les quelques centaines de tentatives, souvent depuis plusieurs pays dans la même heure.

Ceci regroupe les échecs des dernières 24 heures par adresse source et montre quels identifiants chacune a essayés — les trois signaux d'un coup :

bash
journalctl -u ssh --since -24h --no-pager |
  grep -oE 'Failed password for (invalid user )?[^ ]+ from [0-9.]+' |
  awk '{ ip = $NF; user = $(NF-2); count[ip]++; users[ip] = users[ip] " " user }
       END { for (i in count) printf "%6d  %-16s %s\n", count[i], i, users[i] }' |
  sort -rn | head -15

La ligne sur laquelle il faut vraiment alerter

Les connexions échouées sont du bruit. Un message ne l'est pas, et il mérite une alerte plutôt qu'un tableau de bord :

Accepted password for <user> from <ip> — une connexion réussie par mot de passe. Si votre serveur devait être en tout-clé, cette ligne signifie qu'il ne l'est pas et que vous avez un problème de configuration. Si les mots de passe sont permis, cette ligne depuis une adresse inconnue juste après une série d'échecs venant de la même plage est la séquence que vous ne voulez jamais voir.

À surveiller également : Accepted publickey avec une empreinte que vous ne reconnaissez pas, et toute session sudo ouverte pour un utilisateur qui ne devrait pas en avoir. Les deux coûtent peu à alerter et comptent bien plus que le volume de rejets.

bash
# Toutes les connexions réussies de la semaine, avec méthode et source
journalctl -u ssh --since -7d --no-pager |
  grep -E 'Accepted (password|publickey|keyboard-interactive)'

De la lecture au blocage

Lire le journal à la main est un diagnostic, pas une défense — au moment où vous lancez la requête, l'attaque dure depuis une semaine. Ce qui change quelque chose, c'est de le faire en continu et de traduire un seuil en règle de pare-feu.

La version naïve suit le journal, compte les échecs par source et appelle nft pour ajouter l'adresse à un ensemble bloqué. Ça marche, puis ça rencontre les problèmes de tout script du genre : l'ensemble grossit sans limite, le journal tourne sous charge et des événements sont perdus, l'unité meurt silencieusement après une mise à jour, et une mauvaise correspondance coupe l'administrateur du seul accès.

SSH Protector exécute cette boucle en tant que service, avec un ensemble nftables consolidé, une liste blanche toujours prioritaire sur un blocage, des bannissements restaurés au démarrage, et une décision prise localement — elle tient donc quand le réseau ne tient pas. Il lit le même flux que celui montré ci-dessus ; rien ne vous est caché.

FAQ

Où sont journalisées les connexions SSH échouées sous Linux ?
Sous Debian et Ubuntu, /var/log/auth.log. Sous RHEL, CentOS, AlmaLinux, Rocky et Fedora, /var/log/secure. Sur les systèmes reposant entièrement sur journald, aucun de ces fichiers n'existe et vous lisez le journal : journalctl -u ssh (ou -u sshd selon le nom d'unité de la distribution), qui fonctionne partout.
Que signifie « Failed password for invalid user » ?
Que quelqu'un a tenté de s'authentifier avec un compte qui n'existe pas sur la machine. Vos utilisateurs connaissent leurs identifiants, cette ligne est donc presque toujours une attaque — un bot déroulant une liste de noms courants comme root, admin, ubuntu, test, git ou oracle. Le volume seul n'est pas alarmant : c'est le niveau de fond sur tout hôte exposé.
Pourquoi des milliers de tentatives de connexion root ?
Parce que root est le premier identifiant de toute liste d'attaque, et que les bots n'ont aucun moyen de savoir qu'il est interdit sur votre serveur. Avec PermitRootLogin à no ou prohibit-password ils ne peuvent pas réussir, mais ils n'arrêtent jamais non plus, puisqu'une tentative ne leur coûte rien. Contre le volume, c'est le blocage des sources qui agit, pas la politique de connexion.
Comment voir les connexions SSH réussies ?
Cherchez « Accepted » dans le même journal — Accepted publickey, Accepted password ou Accepted keyboard-interactive, suivis de l'identifiant, de l'adresse source et du port. C'est la ligne qui mérite une alerte : une connexion réussie par mot de passe sur un serveur censé être en tout-clé est une erreur de configuration, et une depuis une adresse inconnue après une série d'échecs est un incident.

Arrêtez de lire le journal à la main

L'agent surveille exactement ce flux et le transforme en règles nftables, en continu. Un serveur gratuit à vie, sans carte.