Few weeks ago I thought it would be a good idea to write a script to send me an email whenever some user logs in into my server.

So I came with a perfectly working script notifyLogin.sh, then I decided to call it from each user's .bash_login script.

But I discovered that someone could log in in my server using ssh -t switch to select an available shell. For example:

ssh user@myserver -t sh

This way, .bash_login does not execute, neither does /etc/profile.

Is there any way to call notifyLogin.sh independent of shell type at log in? (It should always work)

up vote 11 down vote accepted

Don't reinvent the wheel, let rsyslog do everything for you. It has the ability to send emails when patterns are matched in syslog messages before they ever hit a file.

Set your email address and SMTP server in the following and put it in your /etc/rsyslog.conf or drop it in /etc/rsyslog.d/ and restart rsyslog

$ModLoad ommail
$ActionMailSMTPServer localhost
$ActionMailFrom rsyslog@whatever.com
$ActionMailTo you@youremail.com
$template mailSubject,"Login Alert on %hostname%"
$template mailBody,"\n\n%msg%"
$ActionMailSubject mailSubject
$ActionExecOnlyOnceEveryInterval 1
# the if ... then ... mailBody mus be on one line!
if $msg contains 'session opened for user' then :ommail:;mailBody

This will fire off an email when rsyslog matches the string session opened for user in a message.

You can look in /var/log/auth.log for messages from sshd to see what else you can use as patterns.

Source: rsyslog ommail

First, you should not rely on user's .profile because they can change it. If it's really your server, you could:

  • test for entries in auth.log, utmp or so periodically (or triggered by inotify)
  • write a wrapper for /bin/login, that does your things and then executes the real /bin/login. (I am not quite sure if e.g. ssh executes /bin/login, but I expect so.) But I can't recommend that - it's too dangerous.
/var/log/auth.log

Keep track of attempts to your system

cat /var/log/auth.log grep sshd.\*Failed 

this can grep failed attempts, also timestamps is available so you can tune it to your script, also maybe with

tail -f /var/log/auth.log 

you can trace input all the time and then do some regexp.

  • This doesn't answer OP's question about sending an email when someone logs in – Creek Jul 10 '14 at 22:46

I know this is old but I wrote something to monitor successful and failed ssh connections/attempts. As well as banned IPs if you're using sshguard. I wrote it in Python and in Ruby. It will email you when someone successfully connects via ssh, when someone gets the ssh password wrong or when someone is banned due to to many failed attempts. Hopefully this will help someone in the future who searches for this issue and finds my code!

Python Implementation:

https://github.com/amboxer21/SSHMonitorPy

Ruby implementation:

https://github.com/amboxer21/SSHMonitor

For the python script, I wrote a bash script to monitor the process. It checks if it's running every minute via root cron task. If it is not running, it starts another process.



Bash script:

/home/anthony/.ssh/is_sshm_running.sh

#!/bin/bash

if [[ `ps aux | egrep --color -i "root.*[0-9]*:[0-9]* sudo /usr/bin/python /usr/bin/SSHMonitor.py" | wc -l` < 1 ]]; then
  sudo /usr/bin/python /usr/bin/SSHMonitor.py -e "example@gmail.com" -p "password" &
fi

if [[ `ps aux | egrep --color -i "root.*[0-9]*:[0-9]* sudo /usr/bin/python /usr/bin/SSHMonitor.py" | wc -l` > 1 ]]; then
  sudo kill -9 `ps aux | egrep --color -i "root.*[0-9]*:[0-9]* sudo /usr/bin/python /usr/bin/SSHMonitor.py" | awk '{print $2}'`;
fi

Which is called by this root cron task every minute:

[anthony@ghost ImageCapturePy]$ sudo crontab -l
[sudo] password for anthony: 
* * * * * /bin/bash /home/anthony/.ssh/is_sshm_running.sh
  • If the exact same answer works for different questions, then it is likely the questions are duplicates. In that case you should flag the duplicate question accordingly. – Stephen Rauch Apr 6 '17 at 20:32

I like @creek's solution from above, but with one small change:

if $msg contains 'session opened for user' then :ommail:;mailBody`

to

if $msg contains 'sshd:session' then :ommail:;mailBody`

If you simply use "session opened for user" you will get a message every time your cronjobs fire. For me at least, I just want to monitor SSH. You could adjust the conditional above to suit any other need.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.