SSH login alert by mail Linux or Unix based systems


You can get mail lerts on SSH login to any Linux server using the script below. This script sends mail to predefined email address each time someone successfully logs in by SSH to the machine.

I take advantage here of the built-in feature of the  OpenSSH daemon – if you create text file containing commands (as if you typed them on the command line), and name it either /etc./ssh/sshrc or /.ssh/rc , these commands in file will be run each time user logs in through SSH daemon to the system. The file has to be readable by the user logging in through SSH.

Note 1:
file /etc/ssh/sshrc is applied globally to any user logging in, unless:
file /.ssh/rc   overrides action of /etc/ssh/sshrc . Caveat here – it is enough for a user to put in his home .ssh directory empty file named rc and it will disable /etc/ssh/sshrc including mail alerts sent from it. Actually it is not that big of an issue as you may create rc file in the home directory of the user yourself, give it 644 permissions and while user will know what is going on when doing ssh login he/she won’t be able to do anything about that.

So to script itself. Here:
yurisk@yurisk.info –   mail to which I get mail alert
mail.yurisk.info   -   mail server that accepts mails destined for yurisk.info domain (its MX record)
SENDING_HOST   -  hostname of sending host, will be included in the subject so later I can create mail inbox rule to pay appropriate attention   to such mails
USER_ID     - output of the #id command so I will also be able to filter incoming messages on the user logged in

/etc/ssh/mail_alert.awk

BEGIN {
# Set up some info to be included in the mail
# As you see I prefer to use absolute pathnames , but you don't have to
# Find the hostname to which SSH login happened , to be included in the Subject
"/bin/hostname" | getline SENDING_HOST
# FInd ID of logged
"/usr/bin/id" | getline
USER_ID = $1
SMTP = "/inet/tcp/0/mail.yurisk.info/25"
RS = ORS = "\r\n"
print "helo yurisk.info"     |& SMTP
SMTP                       |& getline
print "mail from: <yurisk@yurisk.info>" |& SMTP
SMTP                       |& getline
print  "rcpt to: <yurisk@yurisk.info>"  |& SMTP
SMTP                       |& getline
print   "data"             |& SMTP
SMTP                       |& getline
print  "Subject:SSH login alert - user " USER_ID "logged in " SENDING_HOST  |& SMTP
print                       |&  SMTP
"/usr/bin/w" | getline
print  $0                  |& SMTP
print   " He is most free from danger, who, even when safe, is on his guard  "     |& SMTP
print   "  "               |& SMTP
print  "."                 |& SMTP
print                      |& SMTP
print  "quit"              |& SMTP

}

- Now the file that is checked on each login for commands ( I put both files  in /etc/ssh/) :

/etc/ssh/sshrc
awk -f /etc/ssh/mail_alert.awk > /dev/null

Note for FreeBSD (I guess any BSD) users:  in rc file above you will have to replace awk with gawk, as in *BSD systems awk behaves as the old-style Unix awk that has no bidirectional pipe to connect to mail server.

PS. You might be asking why awk here ? True, Linux/Unix have perfect tool for sending mails called #mail, but I did it with awk for a reason - not on every (especially if hardened) system you will find mail/telnet/etc utilities with which sending mails is more simple and more reliable. The biggest one is Checkpoint firewall - it has NO mail or telnet clients, neither scripting language beyond AWK and Bash.

The downside of awk is that it is not perfect for more or less complex protocols. So script may stuck / send commands too fast/ etc and therefore be disconnected by the server.

Also if a receiving mail server uses greylisting - this script won't understand it. So check it in interactive session before using.

Follow me on https://www.linkedin.com/in/yurislobodyanyuk/ not to miss what I publish on Linkedin, Github, blog, and more.