Receiving a mail when someone connect through SSH

:fr: Version française

Bonjour,

Voici un petit script bash qui vise à envoyer un mail à chaque fois que quelqu’un se connecte en SSH. Dans mon cas, je suis le seul utilisateur autorisé à se connecter au serveur de cette manière, ce script me sert donc d’alerte en cas de compromission du serveur.
Il y a une partie géolocalisation qui est optionnelle.

Le script se trouve ici :

Pensez à ajouter la ligne suivante dans /etc/pam.d/sshd : session optional pam_exec.so seteuid /path/authentication_alert.bash

  • Le mail par défaut est celui de root, si vous ne redirigez pas vos mail vous pouvez entrer une autre adresse sur laquelle vous voulez revoir les mails envoyés par ce script.

  • Vous avez besoin d’un package pour envoyer les mails. Personnellement j’utilise mailutils, mais il y en a d’autres. Utilisez celui qui vous plait et modifiez le script en conséquence.

:uk: English version

Hello,

Here is a little bash script which is ran everytime a user connect through SSH. Il will display the geolocation of the connecting user.

In my case, I am the only user allowed to connect through SSH, so the script intends to alert me if the server is compromised.

Here is the script :

  • You will need to add this ligne in /etc/pam.d/sshd : session optional pam_exec.so seteuid /path/authentication_alert.bash

  • Much comments are in french, use a translator like deepl if needed and don’t forget to translate the subject (“sujet”) and mail body (“Envoi mail” bloc) into your own language :smiley:

  • Nota : If you don’t redirect the root mail to another mail, change the “email” variable with the one where you want to receive those mails.

  • You will need a package to send the mail. I use mailutils, but you can use another one.

8 Likes

Hey hello,
Really nice script :slight_smile:
I had a little question about those lines:

if [ "grep "PubkeyAuthentication" /etc/ssh/sshd_config | grep "yes"" != "" ]; then
	type_authent="Accepted publickey"
else
	type_authent="Accepted password"
fi

It seems to me like it orients the whole script to look only for key authentication or password authentication, but not both.
But what if both are allowed, and the last login was done through password authentication? It seems that the script will miss it.
Or is there something I’m misunderstanding somehow?

SSH login alert with sendmail and PAM

You’re right, the script doesn’t allow to use both authentication ways (pubkey/password).

Yunohost setup allow admin to choose between pubkey or password authentication (see Security | Yunohost Documentation ).

You can use both pubkey and password, but that’s weird (pubkey setup is more tricky than password setup, but improves security). You should stick to pubkey only if you can.

If you want to check both ways, you need to rework the first part of the script.

What if you replace the bloc you quoted by a simple

type_authent="Accepted"

?

Edit : Less dirty (or not D: ), you could probably get rid of the type_authent variable and grep the two paterns :

auth_message=$(grep -E 'Accepted publikey|Accepted password' $LOG_AUTH_FILE | tail -l)

$user should be adapted by piping two times the sed part (one with “Accepted password”, the second with “Accepted publikey”)

1 Like

Well I also usually only use ssh keys for login, but I still prefer if the script can handle any case, also since it’s purpose is to get notified if something unusual is happening.

I did like you suggested and removed the type_authent variable, so it becomes:

	auth_message=$(grep -e 'Accepted publickey' -e 'Accepted password' $LOG_AUTH_FILE | tail)

	user=$(echo $auth_message | sed -re "s/.*Accepted publickey for (\S+).*/\1/g" | sed -re "s/.*Accepted password for (\S+).*/\1/g")

And it seems to work like a charm.

Also I was wondering what is the -l in auth_message ... | tail -l. It doesn’t seem to be a valid tail option, so I guess it’s just a typo.

Anyway, thanks a lot for sharing the script, it’s really nice :slight_smile:

Hum, yeah, l looks like 1 :smiley:

I updated the script on my git, thank you for the correction and improvement :slight_smile:

Oh ok, nice I didn’t know about the -1 option, so I learned something :slight_smile:

tail -NUMBER FILE output le last NUMBER lines of a file (or a variable, command output…).
In this cas, tail -1 output the last line of the grep command.

1 Like

Hi,
Thanks a lot for this script ! I don’t know if it is a real something more for security, but it fells like it for me :slight_smile:
For my setup, $hostname was not my domain name, but the name of my virtual machine. So I change the script in order to work by adding the domain name in it.

Added a few improvements and an option to NOT send mail if the user and IP are the same as the last login (could be useful if you test a lot of things in a row or use app like Restic, which can connect dozen of times in a row).

Edit : @ludovic : does your avatar come from The Three Robbers ?

Hello
Very interesting script, but why do we have to use mailx? Undeed, there’s already postfix running on most yunohost servers…
So why not using postfix to send the notification alerts

Hi,

Because i used mailx for a while on non-yunohost server.

Postfix seems not to be used as a replacement of mailx : linux - How to send email with attachment by postfix from command-line? - Super User

According to this post, postfix is a mail-transfer-agent (MTA), and mailx is a mail-user-agent (MUA).

Btw seems i don’t use mailx package but mailutils one.

@kit yes, it comes from The Three Robbers :slightly_smiling_face: