[Tutoriel] Recevoir une alerte à chaque connexion SSH

Publié le 10 septembre 2023

Tutoriel Informatique Sécurité Linux

Bonjour à tous,

J’ai mis en place ce mécanisme il y a déjà pas mal de temps, je le partage ici si ça peut servir à d’autres, ou encore mieux vous donner des idées.

Edit 21 février 2024

Ajout de la section en utilisant l’API PAM.

Objectif

L’objectif est plutôt simple, ça permet de rajouter une couche de sécurité sur mes différents serveurs. En effet, le seul moyen de s’y connecter est de passer par une connexion SSH. Je cherchais une application mobile pour faire du SSH en cas d’extrême urgence, mais si j’étais tombé sur une application malveillante, une attaque man-in-the-middle aurait été possible.

L’idée à travers ce tutoriel est de pouvoir recevoir une alerte à chaque connexion SSH. De ce fait, je serai rapidement au courant si ma clé privée (et son mot de passe) serait tombée entre de mauvaises mains.

Encore une fois, c’est un petit plus sympa, mais ce n’est pas un mécanisme de sécurité fiable, il ne faut pas s’y reposer et penser qu’aucune intrusion ne sera désormais possible sans que vous n’y soyez au courant.

Types d’alertes

Là, le champ des possibles est infini. Globalement, on va pouvoir recevoir une alerte avec tous les systèmes possédant une API HTTP, un client Linux, etc …

Ici, on va montrer comment faire avec Telegram et ntfy.

Telegram

Envoyer un message sur Telegram est vraiment très simple, il suffit d’une requête curl et le tour est joué.

Avant cela, il faut tout de même créer un bot et récupérer son token.

Il existera ensuite 2 types de conversations:

  • une conversation en tête à tête avec votre bot
  • un groupe Telegram (1 ou plusieurs bots et 1 ou plusieurs “vraies personnes”)

Je ne vais pas réécrire une procédure que l’on peut trouver partout sur le net. Je peux tout de même vous diriger vers une procédure écrite par mes soins.

Ensuite, on peut faire un petit script bash assez simple pour faire ce fameux curl:

#!/bin/bash

if [ "$#" -ne 3 ]; then
  echo "Usage: $0 <bot_token> <group_id> <text message>"
  exit 1
fi

BOT_TOKEN=$1
GROUP_ID=$2
TEXT=$3
URL="https://api.telegram.org/bot${BOT_TOKEN}/sendMessage"

RES=$(curl -i -s -X POST "${URL}" --data "text=${TEXT}" --data "chat_id=${GROUP_ID}")
STATUS_CODE=$(echo "$RES" | head -n 1 | awk -F' ' '{print $2}')

if [[ $STATUS_CODE -ne 200 ]] ; then
  echo "error while sending message"
  echo "${RES}"
  exit 1
fi

Je vous laisse placer ce script à l’endroit de votre choix, on pourrait par exemple le placer dans /usr/bin ou tout autre dossier de votre $PATH. Il ne faut ensuite pas oublier de lui donner les droits d’exécution avec chmod +x <script-path>.

Faites attention lorsque vous lancez ce script pour le tester dans votre terminal, je vous conseille de rajouter un espace devant la commande comme le conseille le man de bash. Cela vous permettra de ne pas enregistrer la commande dans votre historique et de ne pas y dévoiler le token.

Ntfy

Au début, j’avais prévu de faire l’article en ne parlant que de Telegram. J’avais également prévu de mettre un petit encadré pour dire “faites attention, par design, Telegram aura accès à toutes vos alertes, blabla”.

Et puis je me suis souvenu de ntfy que je n’avais jamais pris le temps de tester. Pour faire simple, c’est un service de notification/alerte en publish-subscribe Open Source et qu’il est possible d’auto-héberger. Le slogan est Push notifications made easy et c’est vraiment le cas. Je vous invite à faire un tour sur leur site et la documentation associée, ça marche bien, vite et simplement.

Voilà un script équivalent à celui pour Telegram:

#!/bin/bash

set -eu

if [ "$#" -ne 4 ]; then
  echo "Usage: $0 <ntfy_url> <basic_auth> <topic> <text message>"
  echo "Help basic_auth: \"echo -n 'testuser:fakepassword' | base64\""
  exit 1
fi

NTFY_URL=$1
BASIC_AUTH=$2
TOPIC=$3
TEXT=$4

RES=$(curl -i -s -X POST -H "Authorization: Basic ${BASIC_AUTH}" -d "${TEXT}" "${NTFY_URL}/${TOPIC}")
STATUS_CODE=$(echo "$RES" | head -n 1 | awk -F' ' '{print $2}')

if [[ $STATUS_CODE -ne 200 ]] ; then
  echo "error while sending alert"
  echo "${RES}"
  exit 1
fi

On pourrait également utiliser la CLI pour quelque-chose de similaire (voir ici).

L’avantage en auto-hébergement est que vous restez maitre de vos données. L’inconvénient vient des cas d’usages. Par exemple, si vous avez:

  • un serveur A avec quelques services dont ntfy
  • un serveur B avec un service de monitoring comme uptime-kuma qui est censé envoyer un message quand un service est tombé sur le serveur A, si le service en question est ntfy, c’est ballot (idem si c’est tout le serveur A qui tombe).

Envoyer l’alerte à la connexion SSH

Avec profile.d

L’astuce va être de profiter de /etc/profile qui va exécuter des scripts à chaque connexion (SSH ou pas) pour chaque utilisateur de la machine.

Il suffit alors de créer un fichier (disons login-notify.sh) dans le dossier /etc/profile.d/ avec ce type de contenu (à adapter selon vos besoins/envies):

#!/bin/bash

BOT_TOKEN="to-replace"
GROUP_ID="to-replace"

IP="$(echo "${SSH_CONNECTION}" | awk -F' ' '{print $1}')"  # does not work for local connection
DATE="$(date)"
NAME="$(whoami)"
NB_USERS=$(who | wc -l)

MESSAGE="""
New login to ${HOSTNAME} server!
\"${NAME}\" from \"${IP}\"
${NB_USERS} users connected
${DATE}
"""

/path/to/send-telegram.sh "${BOT_TOKEN}" "${GROUP_ID}" "${MESSAGE}"

Vous pouvez ne mettre les droits de lecture à ce fichier qu’à l’utilisateur root si vous y mettez votre BOT_TOKEN par exemple.

Là, j’utilise le script pour Telegram, mais on pourrait utiliser celui pour ntfy (avec pourquoi pas du retry sur Telegram en cas d’échec). On pourrait également n’envoyer une notification que via le ~/.bash_profile pour rester uniquement à notre utilisateur.

Avec l’API PAM

L’astuce avec profile.d marche bien dans le cas de connexions ssh classiques. Mais si je fais ce type de commande ssh user@mymachine uptime, aucune notification ne sera envoyée parce qu’au environnement ne sera créé.

On peut alors dans ce cas plutôt se tourner vers l’API PAM dont voici sa description selon Wikipédia:

Pluggable Authentication Modules est une API permettant d’offrir aux programmes des services d’authentification, d’autorisation et de contrôle d’ouverture de sessions.

Bref, entrons dans le vif du sujet.

Dans votre fichier /etc/ssh/sshd_config, assurez-vous de mettre la valeur UsePAM à yes. Personnellement, j’ai également ChallengeResponseAuthentication et PasswordAuthentication à no: dans ce cas, on utilise pas PAM pour l’authentification (je continue à utiliser uniquement l’authentification par clés).

On peut ensuite commencer:

  • on crée un dossier: mkdir -p /etc/pam.scripts
  • on y place le même contenu que le fichier login-notify.sh de la section précédente
  • on ajoute les droits exécutables sur notre fichier: chmod +x /etc/pam.scripts/login-notify.sh
  • à la fin de /etc/pam.d/sshd, on rajoute session optional pam_exec.so /etc/pam.scripts/login-notify.sh

Le mot clé optional est important, parce que si votre message Telegram ou votre notification ntfy retourne une erreur, alors la connexion SSH sera bloquée. Or si c’est le même serveur qui gère votre serveur ntfy et qu’il est tombé, vous ne pourrez plus vous y connecter. On reste donc sur du “best-effort”, ce n’est donc pas une sécurité absolue mais un petit plus (comme toujours en sécurité).

Aussi, il est possible d’utiliser if [ ${PAM_TYPE} = "open_session" ]; then autour de l’envoi du message (sans oublier le fi à la fin) pour notifier uniquement en cas d’ouverture de session, sinon il y aura aussi les fermetures.

Conclusion

Voilà qui clôt ce tutoriel. Je ne vous invite pas forcément à copier-coller les scripts mais plutôt à les adapter à vos besoins. Le but était surtout de donner des idées: on peut en effet exécuter des scripts à chaque login (et donc par extension faire ce que l’on veut).

Dans le même esprit, si vous avez d’autres idées dans le même genre, n’hésitez pas à les partager dans les commentaires ci-dessous.

Commentaires




Ailleurs sur le Web


Home Screen Advantage - Infrequently Noted

A slide from Apple's presentation in Apple v. Epic, attempting to make the claim Epic could have just made a PWA if they didn't like the App Store terms because circa '20 Safari was so capable. LOL. Je n'aurai pas assez de popcorn pour le DM…

via Shaarli le 28 février 2024

800 employés de la poste britannique condamnés à tort à cause d’un logiciel défectueux - Next

En droit anglais et gallois, les ordinateurs sont considérés comme « fiables », sauf preuve du contraire, souligne The Guardian, ce qui « renverse la charge de la preuve normalement appliquée dans les affaires pénales ». Euh, ok !

via Shaarli le 15 janvier 2024

Mise en place et étude d'un Honey Pot SSH (Cowrie) | | Sécurité Informatique | IT-Connect (it-connect.fr) – wallabag

Article intéressant. C'est clairement dans la même démarche que mon article sur les phishing.

via Shaarli le 09 janvier 2024

Généré avec openring


Recettes de gourmands


Purée

Un minimum d'ingrédients mais une texture parfaite.

via cooking.pofilo.fr le 15 mai 2024

Meringues

Pratique pour utiliser des blancs d'œufs, car les ingrédients sont au tant pour tant.

via cooking.pofilo.fr le 21 mars 2024

Risotto classique

Vraiment très simple mais le résultat est succulent.

via cooking.pofilo.fr le 28 février 2024

Généré avec openring