Ops

Monitorer les connexions SSH de son serveur sans service externe

Author Photo

Quentin Lerebours

Thumbnail

Il y a quelques semaines, j’ai eu un doute sur des connexions SSH suspectes sur l’un de mes serveurs. Finalement, il n’y avait aucun problème, mais par souci d’amélioration continue, je me suis dit :

Et si je pouvais recevoir des alertes en temps réel quand une connexion SSH est établie sur un de mes serveurs ?

Mes contraintes

Comme toujours, c’est important de regarder le contexte pour voir si ça vaut le coup de construire soi-même ce genre de système, j’ai donc établi mes contraintes :

  • pas de dépendance externe
  • rapide à mettre en place
  • être prévenu peu importe le moment et le lieu où je me trouve

Le principe

SSH passe par PAM (Pluggable Authentication Modules).
PAM permet d’exécuter un script à chaque ouverture de session.

L’idée est donc simple :

  1. Un script bash déclenché à chaque login SSH
  2. Il envoie un message via un webhook (Discord ou Slack)
  3. Je suis notifié en temps réel

Mise en place

Le script d’alerte SSH

Créer le script qui va envoyer un message via Discord (une alternative pour Slack est disponible plus bas) :

sudo vim /usr/local/bin/ssh-session-alert.sh

mettre le contenu suivant :

#!/bin/bash

[ "$PAM_TYPE" != "open_session" ] && exit 0

WEBHOOK_URL="https://discord.com/api/webhooks/XXX/YYY" # à remplacer

CONTENT="SSH login user=$PAM_USER ip=${PAM_RHOST:-local} host=$(hostname) date=$(date '+%F %T')"

JSON=$(printf '{"content":"%s"}' "$CONTENT")

/usr/bin/curl \
  --silent \
  --fail \
  -H "Content-Type: application/json" \
  -X POST \
  -d "$JSON" \
  "$WEBHOOK_URL" \
  >> /tmp/ssh-alerting-error.log 2>&1

Il faut bien penser à :

  • Remplacer l’URL de Webhook Discord par votre URL de webhook
  • Rendre le script exécutable : sudo chmod +x /usr/local/bin/ssh-session-alert.sh

Brancher le script à SSH via PAM

Éditer le fichier PAM de SSH :

sudo vim /etc/pam.d/sshd

Ajouter à la fin du fichier :

session optional pam_exec.so /usr/local/bin/ssh-session-alert.sh

À partir de là, chaque nouvelle session SSH déclenchera le script, avec pour résultat :

SSH login user=qlerebours ip=x.y.z.a host=my-server date=2026-02-02 14:32:10

Version Slack du curl

Slack attend un payload légèrement différent.
Voici la version Slack du curl, à utiliser à la place de celui de Discord si besoin :

JSON=$(printf '{"text":"%s"}' "$CONTENT")

/usr/bin/curl
--silent
--fail
-H "Content-Type: application/json"
-X POST
-d "$JSON"
"$WEBHOOK_URL"
>> /tmp/ssh-alerting-error.log 2>&1

Le reste du script reste strictement identique.


Tips pour débugger si ça ne marche pas

  1. Vérifier que le script est bien exécuté
    • Ajouter au tout début du script echo "SSH LOGIN $(date) user=$PAM_USER rhost=$PAM_RHOST" >> /tmp/ssh-test.log
    • Puis tenter une connexion SSH et vérifier que /tmp/ssh-test.log a été rempli
  2. Vérifier les erreurs du curl, si le script s’exécute, mais que rien n’arrive sur Discord / Slack :
    • Aller vérifier le fichier : cat /tmp/ssh-alerting-error.log
  3. Tester le script manuellement
    • /usr/local/bin/ssh-session-alert.sh

Si ça marche en manuel mais pas via SSH, le problème vient quasi toujours du contexte PAM.


Pourquoi j’aime bien cette solution

  • Facile à mettre en place
  • Zéro dépendance externe
  • Suffisamment efficace pour détecter rapidement un comportement suspect

Ce n’est pas un système de sécurité complet, évidemment.
Mais comme souvent, avoir un signal simple et immédiat vaut mieux qu’une solution parfaite jamais mise en place.

#security#linux#ssh#monitoring#devops
Author Photo

À propos de Quentin Lerebours

Entrepreneur mais avant tout développeur, j'ai choisi de rester polyvalent afin de travailler avec une vision d'ensemble cohérente des projets. Développement, Commerce, Entrepreneuriat et Gestion de projet font donc partie intégrante de mon quotidien — et si c'était à refaire, je referais pareil !