Setting up an email notification for SSH logins


I want to set up our server so that I get emailed when someone logs in via SSH. We recently had a malicious actor get in, and I want to be more up to date if it happens again. So I have a bash script:

recipient="[email protected]"

subject="SSH Login Alert"

message="SSH login detected on $(hostname) at $(date) by user $(whoami) from $(echo $SSH_CONNECTION | awk '{print $1}')"

echo "Message: $message" >> /tmp/ssh_login_debug.log

echo "$message" | /usr/bin/mail -s "$subject" "$recipient"

and /usr/local/bin/


# Your email notification script


# Execute the internal-sftp command


Then in /etc/ssh/sshd_config, I have:

Match User sftp_dummy99,admin,north_admin,athertons,westbrook,bfc,saliscare,camera,brettinc,katie,costumes,marike,tessa,bob,andyadmin,directmilk,newstreet,ukraine,stats,newstree2,test,raffner,newbyhost,euprwire,george,executivethreat,machinegazette,nettlegrasp,punkindustry,ukprwire,usprwire,clickpress,octobrachia,store,accounts,willr,gcsescience,teardrop,hatlamp,ibrahim,usinglaw
ChrootDirectory %h
    X11Forwarding no
    AllowTCPForwarding no
    #ForceCommand internal-sftp
    **ForceCommand /usr/local/bin/**

I restart the ssh service, and then connect via SSH again. But nothing. It logs me in, but no emails

Also as a sidenote - does sshd_config get overwriten? I can see the Match User part updates with new users, so I’m not sure if the new ForceCommand would get re-written as well?



I think only the match User line get overwritten

Cool thanks. I’m still trying to work out how to get this to work:

    #ForceCommand internal-sftp
    ForceCommand /usr/local/bin/

Is it possible to do && like we do in crons? So:

ForceCommand /usr/local/bin/ && internal-sftp


The current way I have it never seems to trigger the second script (I’m not sure where internal-sftp is… is it a script?)

Ok, I worked out a way :slight_smile: Rather than editing sshd_config, I edited


Add this to the end:

session optional seteuid /usr/local/bin/

So have the script:

/usr/local/bin/ =>


# Change this to your email address

recipient="[email protected]"

subject="SSH Login Alert"

message="SSH login detected on $(hostname) at $(date) by user $(whoami) from $(echo $SSH_CONNECTION | awk '{print $1}')"

#echo "Message: $message" >> /tmp/ssh_login_debug.log

echo "$message" | /usr/bin/mail -s "$subject" "$recipient"

Now I get the emails fine. If you don’t want it emailing when you login, just put an extra condition in the script:

# if the IP is ours, lets skip - otherwise lets do the email
if [ "$(echo $SSH_CONNECTION | awk '{print $1}')" == "" ]; then
        exit 0

Hopefully that helps someone else :})

If you have CSF/LFD installed (By default is not in hestiaCP)…, it will trigger the emails to you on-time. Also it will give more security of logins. It can prevent lot of malicious login SPAMMER attempts too.

1 Like

For anyone interested, this is the new script I’ve come up with:


this_ip=$(echo $SSH_CONNECTION | awk '{print $1}')

# IPs to skip
skip_ips=("") # your IP - add in as many as you want to ignore

if [ "$PAM_TYPE" = "close_session" ]; then
    exit 0

for ip in "${skip_ips[@]}"; do
    if [ "$this_ip" == "$ip" ]; then
        exit 0

# File to store the timestamp of the last sent message

# Check if we can send a message based on the timestamp
if [ -f "$timestamp_file" ]; then
    last_sent=$(cat "$timestamp_file")
    current_time=$(date +%s)
    if (( current_time - last_sent < 300 )); then
        echo "less than 5 mins ago... skip"
        exit 0

# If we are on localhost, we are most likely using the filemanager... so lets grab the last line of the access log, so wecan see the true IP accessing it
if [ "$this_ip" == "" ]; then
    last_log=$(grep -E 'GET /fm/' /var/log/hestia/nginx-access.log | tail -n 1)
last_log_sanitized=$(echo "$last_log" | sed 's/\\/\\\\/g; s/"/\\"/g')

message="SSH login detected on $(hostname) at $(date) by user $PAM_USER from $this_ip $last_log_sanitized"

curl --include --header "Authorization: Authorization: Basic xxxxx=" --request POST --header "Content-Type: application/json" --data-binary "{
        \"messages\":[ { \"source\":\"admin-script\", \"body\":\"$message \", \"to\":\"+44123412341234\" } ]
    }" ''

echo "$message" | /usr/bin/mail -s "SSH Login Alert" "[email protected]"

# Update the timestamp
date +%s > "$timestamp_file"

It uses to send out the SMS’s to my phone. It also has a 5 minute timer so that it doesn’t ping you lots of times if someone keeps opening new sessions (something that was very annoying!)

If you wanted the timeout to work on a per-IP basis, you could also do:


If someone logs in via the FileManager, this uses a SSH (well, SFTP) connection - which triggers this script. So what I’ve done is also included a tail of the nginx-access.log log, so that you can see the actual IP being used to access it :slight_smile:

1 Like