Vérifier ma connexion

Guides · Enquêter sur une IP

Des tentatives de connexion SSH dans mes logs : suis-je piraté ?

Vous vous connectez à votre serveur, jetez un œil à /var/log/auth.log, et ce sont des milliers de lignes Failed password for root venues d'adresses du monde entier. On dirait un siège. C'est surtout de la météo.

Le port 22 est la porte la plus prévisible d'internet : des scripts automatiques y frappent sans arrêt, partout, toute la journée. Ce n'est pas vous qu'ils visent. Ils essaient une courte liste de noms d'utilisateur (root, admin, oracle, ubuntu, test) avec les mots de passe les plus choisis, puis passent à autre chose. Un échec ne leur coûte rien et vous apprend seulement que SSH est joignable. Votre travail consiste à répondre à deux questions : une tentative a-t-elle réussi, et une tentative future le pourrait-elle ?

Où regarder

Sous Debian et Ubuntu avec rsyslog, SSH écrit dans /var/log/auth.log. Sous Red Hat, Fedora, Rocky et Alma, c'est /var/log/secure. Les installations Debian récentes peuvent ne pas écrire ce fichier du tout et tout garder dans le journal systemd. Le journal fonctionne partout où tourne systemd ; le service s'appelle ssh sous Debian et Ubuntu et sshd dans la famille Red Hat :

sudo journalctl -u ssh --since today        # Debian, Ubuntu
sudo journalctl -u sshd --since "1 hour ago" # Red Hat, Fedora, Rocky, Alma

Trois comptages racontent l'essentiel :

sudo grep -c "Failed password" /var/log/auth.log
sudo grep "Accepted" /var/log/auth.log
sudo grep "Failed password" /var/log/auth.log | grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn | head

Le premier donne l'ampleur du bruit. Le deuxième est celui qui compte : chaque connexion réussie. Le troisième montre quelles adresses insistent le plus.

Un exemple concret : une nuit sur un petit VPS

Douze lignes d'un serveur nommé web1. Les deux adresses de personnes (l'attaquant qui essaie admin, et le propriétaire qui se connecte le lendemain matin) sont des adresses de documentation : aucune personne réelle n'apparaît ici. Les autres appartiennent à des infrastructures publiques.

Le log d'exemple (12 lignes)
Nov  6 03:12:41 web1 sshd[24811]: Invalid user admin from 203.0.113.77 port 51022
Nov  6 03:12:43 web1 sshd[24811]: Failed password for invalid user admin from 203.0.113.77 port 51022 ssh2
Nov  6 03:12:44 web1 sshd[24811]: Connection closed by invalid user admin 203.0.113.77 port 51022 [preauth]
Nov  6 03:12:50 web1 sshd[24815]: Failed password for root from 185.220.101.1 port 40122 ssh2
Nov  6 03:12:53 web1 sshd[24815]: Failed password for root from 185.220.101.1 port 40122 ssh2
Nov  6 03:12:55 web1 sshd[24815]: Disconnected from authenticating user root 185.220.101.1 port 40122 [preauth]
Nov  6 03:14:02 web1 sshd[24830]: Invalid user oracle from 3.5.140.1 port 33412
Nov  6 03:14:04 web1 sshd[24830]: Failed password for invalid user oracle from 3.5.140.1 port 33412 ssh2
Nov  6 03:14:04 web1 sshd[24830]: Received disconnect from 3.5.140.1 port 33412:11: Bye Bye [preauth]
Nov  6 03:20:17 web1 sshd[24902]: Connection closed by 167.94.138.35 port 49212 [preauth]
Nov  6 08:41:09 web1 sshd[25510]: Accepted publickey for deploy from 198.51.100.20 port 52814 ssh2: ED25519 SHA256:k3X0exampleexampleexampleexampleexampleexa
Nov  6 08:41:09 web1 sshd[25510]: pam_unix(sshd:session): session opened for user deploy(uid=1001) by (uid=0)

Passées dans l'analyse de journaux d'iplover, les cinq adresses se répartissent ainsi :

Adresse IPLignesCatégorieType de réseau
203.0.113.773Privées ou réservéesAdresse privée ou réservée (non vérifiée)
185.220.101.13Nœuds de sortie TorNœud de sortie Tor
3.5.140.13Cloud et hébergementHébergement, cloud ou centre de données
167.94.138.351Scanners d'internetNon identifié
198.51.100.201Privées ou réservéesAdresse privée ou réservée (non vérifiée)

(Les deux adresses de documentation apparaissent comme réservées ; dans votre propre log, les vraies adresses seraient vérifiées.) Lisez maintenant les lignes, car les catégories disent seulement qui a frappé, pas si la porte s'est ouverte.

Verdict : une connexion acceptée, et c'est celle du propriétaire. Personne n'est entré. Mais root accepte encore les mots de passe : les essais de la quatrième ligne pourraient donc réussir un jour si le mot de passe de root est faible. C'est ce qu'il faut corriger.

Quelqu'un est-il vraiment entré ?

Vérifiez chaque ligne Accepted. Pour chacune, demandez-vous : est-ce mon nom d'utilisateur, ma clé ou mon mot de passe, et une adresse que je reconnais (domicile, bureau, VPN) ? Puis croisez avec les registres de connexion :

last -a | head -20     # connexions réussies récentes, avec l'adresse distante
sudo lastb | head -20  # échecs récents (sur les systèmes qui les conservent)
who                     # qui est connecté en ce moment

Certaines distributions récentes ont remplacé last et lastb par d'autres outils ; s'ils manquent, le journal et auth.log contiennent les mêmes informations.

Une ligne Accepted password ou Accepted publickey que vous ne pouvez pas expliquer est le seul résultat qui change tout. Dans ce cas, considérez le compte comme compromis :

Si vous voyez ceci, faites cela

Ce que vous voyezCe que ça signifieQue faire
Invalid user … pour des noms que vous n'avez pasDes essais qui ne peuvent pas marcherRien d'urgent. Ça disparaît une fois les mots de passe désactivés.
Failed password for root ou pour un autre compte réelDes essais contre un compte qui existeDésactivez la connexion par mot de passe (plus bas), au moins pour root.
Connection closed by … [preauth] sans mot de passe essayéUn scanner qui lit votre bannière SSHRien.
Des milliers d'échecs par jour depuis quelques adressesDes bots persistantsAjoutez fail2ban, ou n'autorisez SSH que depuis vos propres adresses.
Des lignes Accepted … qui sont toutes les vôtresPersonne d'autre n'est entréRien, à part renforcer la sécurité.
Accepted … depuis une adresse ou pour un utilisateur que vous ne pouvez pas expliquerUne intrusion probableSuivez les étapes ci-dessus, en commençant par authorized_keys.

Rendre les essais inutiles : uniquement des clés

Un mot de passe peut se deviner ; une clé SSH, en pratique, non. Dès que seules les clés sont acceptées, les bots peuvent essayer indéfiniment.

Commencez par créer une clé sur votre ordinateur et copiez-la sur le serveur. macOS et Linux intègrent le client OpenSSH. Sous Windows, c'est une fonctionnalité facultative, souvent déjà installée ; si ssh n'est pas reconnu, le guide de Microsoft Bien démarrer avec OpenSSH pour Windows explique comment l'ajouter :

ssh-keygen -t ed25519
ssh-copy-id vous@votre-serveur     # sous Windows, collez ~/.ssh/id_ed25519.pub dans le ~/.ssh/authorized_keys du serveur

Ensuite, sur le serveur, définissez ceci dans /etc/ssh/sshd_config :

PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password

prohibit-password n'autorise root qu'avec une clé ; mettez no pour tenir root complètement à l'écart de SSH. Avant de redémarrer, vérifiez ce que SSH va réellement utiliser. Les fichiers de /etc/ssh/sshd_config.d/ sont lus aussi, et certaines images cloud en fournissent un qui réactive les mots de passe. Pour la plupart des réglages, la première valeur lue par sshd l'emporte :

sudo sshd -T | grep -Ei "passwordauthentication|kbdinteractive|permitrootlogin"

Redémarrez SSH (sudo systemctl restart ssh, ou sshd dans la famille Red Hat), et gardez votre session actuelle ouverte pendant que vous testez une nouvelle connexion dans une seconde fenêtre. Si la nouvelle connexion échoue, vous pouvez encore réparer depuis l'ancienne.

Réduire le bruit : fail2ban et pare-feu

Les clés rendent les essais inoffensifs. fail2ban rend le log lisible : il surveille les échecs répétés et bloque ces adresses un moment dans le pare-feu. Sous Debian et Ubuntu, sudo apt install fail2ban, puis créez /etc/fail2ban/jail.local :

[sshd]
enabled  = true
maxretry = 5
findtime = 10m
bantime  = 1h
# Sans /var/log/auth.log (Debian récent), lire le journal :
# backend = systemd

Redémarrez-le avec sudo systemctl restart fail2ban et vérifiez-le avec sudo fail2ban-client status sshd.

Si vous êtes seul à avoir besoin de SSH, le meilleur filtre anti-bruit est une règle de pare-feu qui n'autorise le port 22 que depuis vos propres adresses, ou un VPN devant le serveur. Déplacer SSH sur un autre port réduit aussi beaucoup le bruit, mais c'est du camouflage, pas une protection : un scanner le trouvera quand même.

Ce que les adresses ne peuvent pas vous dire

Les adresses d'auth.log sont l'origine des connexions : souvent une sortie Tor, un serveur cloud loué ou la machine piratée de quelqu'un d'autre. Elles n'identifient pas une personne, et les bloquer une par une ne suivra jamais le rythme. Signaler des attaques persistantes au contact abus du réseau (la recherche IP l'affiche) est raisonnable pour un serveur cloud qui vous martèle pendant des jours ; pour quelques échecs de connexion, ça ne vaut pas votre temps.

Sources

Documents officiels utilisés pour vérifier les faits de ce guide.