Get an e-mail alert on a SSH login with PAM
An e-mail alert when someone connects to your server via SSH (when you are supposed to be the only one), can be very useful to detect a compromised SSH key. I’m not talking about a compromised password here because you’re not supposed to connect to your server with a password. If this is still the case, I advise you to follow my article on how to secure an SSH server first.
In this article, we are going to use Postfix as a relay host, so it is also necessary to follow my article which explains how to set up a relay host with Postfix.
Once all these things are done, we can start.
Information and requirements
These elements are to be taken into consideration to follow this article:
- The manipulations are carried out on Rocky Linux 8.
- SELinux is in enforcing mode.
Update the system
sudo dnf -y update
PAM’s configuration
A Pluggable Authentication Module (PAM) is a mechanism to integrate multiple low-level authentication schemes into a high-level Application Programming Interface (API). Each PAM-aware software creates a file in the /etc/pam.d/
. Such file controls how PAM will treat new connections and which rules follow for authentication: in our case, OpenSSH server produces the file /etc/pam.d/sshd
.
We can use this file to set up a script that would run whenever a login happens via SSH.
Script’s directory
sudo mkdir /etc/pam.scripts
Script file
Copy the following script into /etc/pam.scripts/ssh
. Replace validemail@gmail.com
to a valid e-mail address (by the one you want to receive the alert) and alert@domain.fr
by the e-mail address through which you want to receive e-mails.
#! /usr/bin/env bash
recipient="validemail@gmail.com"
subject="Successful SSH connection"
body="[PAM] - a login was successful from $PAM_RHOST with user $PAM_USER."
if [ ${PAM_TYPE} = "open_session" ]; then
echo "${body}" | /usr/bin/mail -r "alert@domain.fr" -s "${subject}" "${recipient}"
fi
exit 0
This script is pretty simple. You can add more information into the body
variable if you need, or change the subject by modifying the subject
variable.
Here are some information retrievable via PAM variables:
$PAM_USER
: the username of the entity under whose identity service will be given,$PAM_RHOST
: the requesting hostname (the hostname of the machine from which the $PAM_RUSER entity is requesting service),$PAM_SERVICE
: the service name (which identifies that PAM stack that the PAM functions will use to authenticate the program),$PAM_TTY
: the terminal name: prefixed by/dev/
if it is a device file.
Set the SELinux context
Because SELinux is in enforcing mode, the context must be set to authorize OpenSSH executing a script.
sudo semanage fcontext -a -t bin_t /etc/pam.scripts/ssh
sudo restorecon -v /etc/pam.scripts/ssh
Set the correct permission
sudo chmod 700 /etc/pam.scripts/ssh
Final configuration
Ask PAM to run our script as soon as a connection is established. Copy the following snippet at the end of /etc/pam.d/sshd
.
session required pam_exec.so /etc/pam.scripts/ssh
Now, as soon as an SSH connection is established, you will be immediately notified by e-mail. Of course, you will also receive an e-mail when you are the one to connect. But I think it’s important to have this kind of information.