/etc/profile, bashrc, etc.
One can first think of a script in /etc/profile - I saw that solution on many websites - but it is wrong because the user can connect with ssh /bin/sh and it will not run any login script. Also, this kind of login does not appear in last/wtmp but only in auth.log by sshd (because it's not considered as an "interactive login").Parse logs
Second solution is to parse the auth.log - for instance with SEC, Simple Event Correlator - and use a notify script. It should work, yet I prefer the third solution.pam_exec
Third solution is to use PAM (Pluggable Authentication Modules). It has a module named pam_exec to execute a script at every PAM event, such as a successfull login.First, create a notify-login script. According to pam_exec manual, PAM items are passed to the script as environment variables, so we are able not only to restrict the script to open_session (login) event but also to get user, remote host and other information. I made the following notify script, adapt it to your needs:
#!/bin/sh [ "$PAM_TYPE" = "open_session" ] || exit 0 { echo "User: $PAM_USER" echo "Ruser: $PAM_RUSER" echo "Rhost: $PAM_RHOST" echo "Service: $PAM_SERVICE" echo "TTY: $PAM_TTY" echo "Date: `date`" echo "Server: `uname -a`" } | mail -s "`hostname -s` $PAM_SERVICE login: $PAM_USER" rootI chose to email root but thanks to /etc/aliases it arrives directly in my inbox.
Note: you may need a recent version of PAM library to have PAM_TYPE (it was added in rev 1.8). For instance Debian lenny's pam_exec does not support it (libpam-modules 1.0) while Debian squeeze's has it (libpam-modules 1.1).
Second, we prepare a pam_exec rule:
session optional pam_exec.so /usr/local/bin/notify-loginWe have to add this rule to every login service that uses PAM: SSH but also su, login, sudo, etc. We want to avoid logins via cron that are not interative. On Debian (and maybe other distros), PAM provides a common-session rule that is included for almost all these services:
# grep 'common-session$' /etc/pam.d/* /etc/pam.d/chfn:@include common-session /etc/pam.d/chsh:@include common-session /etc/pam.d/cvs:# @include common-session /etc/pam.d/login:@include common-session /etc/pam.d/other:@include common-session /etc/pam.d/sshd:@include common-session /etc/pam.d/su:@include common-sessionNote: Cron and other non interactive services are using common-session-noninteractive rule. The only missing service is sudo which does not include common-session (Debian bug #519700 still not fixed). So we add the pam_exec rule to /etc/pam.d/common-session and /etc/pam.d/sudo, and we are all set!
Hi,
ReplyDeleteI'm trying to implement something similar, but all my PAM environment variables are coming back empty.
I've googled for hours and there's very little out there on PAM that I can find, have you any pointers in the right direction?
Thanks in advance for any help!
What is your PAM version?
ReplyDeleteHave you installed PAM modules?
Under Debian you can see both with dpkg -l |grep libpam. For instance on Debian Squeeze I have libpam0g, libpam-modules and libpam-runtime, all in version 1.1.1-6.1.
Thanks for this great hint!
ReplyDeleteWe should also mention that sending mails to local mail accounts is witless if you want to monitor break-ins ;-)
Layout broken?
ReplyDeleteThanks, fixed :)
ReplyDeleteIs it possible to execute the script as root at each user logon ?
ReplyDeleteThanks
I've no idea. What do you want to do?
ReplyDeleteI ran into
ReplyDelete/usr/local/bin/notify-login failed: exit code 13
which could be fixed through
chmod 755 /usr/local/bin/notify-login
as root.
Thx 4 ya infos!
I'm trying to create a script as to notify wenever someone fails to provide a correct password for ssh.
ReplyDeletethe script is basically echo `date`';'$PAM_SERVICE';'$PAM_USER';'$PAM_TYPE >> $logfile
The log looks like this (date;service;user;event):
lun ago 5 01:52:06 ART 2013;su;root;open_session
lun ago 5 01:52:08 ART 2013;su;root;close_session
Mon Aug 5 01:52:17 ART 2013;sshd;alejandro;auth
lun ago 5 01:52:17 ART 2013;sshd;alejandro;open_session
lun ago 5 01:52:19 ART 2013;sshd;alejandro;close_session
However I'm failing to record when someone gives an incorrect password.
Dont know if will help but there is the /var/log/auth.log output for the incorrect attemps:
Aug 5 01:56:07 d-U10 sshd[24161]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=d-u10.local user=alejandro
Aug 5 01:56:07 d-U10 sshd[24161]: pam_winbind(sshd:auth): getting password (0x00000388)
Aug 5 01:56:07 d-U10 sshd[24161]: pam_winbind(sshd:auth): pam_get_item returned a password
Aug 5 01:56:07 d-U10 sshd[24161]: pam_winbind(sshd:auth): internal module error (retval = PAM_AUTHINFO_UNAVAIL(9), user = 'alejandro')
Aug 5 01:56:08 d-U10 sshd[24161]: Failed password for alejandro from 192.168.1.100 port 38441 ssh2
What entry should I add (and where) besides the session optional pam_exec.so /usr/local/bin/notify-login.
Thanks in advance
Hello, I don't know if it's possible via PAM: it looks like the failure is logged before by PAM itself and not given to pam_exec.
ReplyDeleteYou can try a different approach by tail+grep auth.log and notifying on lines matching "Failed password".
Runs very well :-) thanks man!!!
ReplyDeleteHi,
ReplyDeleteI'm trying to implement this, but got the message while i logged in "/usr/local/bin/notify-login failed: exit code 127"
I've googled, but only thing i got, this is due to "command not found" and possible problem is with $PATH or a typo.
Thanks in advance for any help!
Make sure to save the script above as /usr/local/bin/notify-login and executable.
ReplyDeleteMake sure to have mail command installed.
If it still does not work it could be $PATH, you can set it in the script.
Hello,
ReplyDeleteThanks for the reply, i found the exact issue.
Mail command is missing on my server, thats why server is throwing "code 127"
i simply installed it by "apt-get install bsd-mailx" and now script is working good for me. :-)
thanks for that tip!
DeleteWorks great on Debian Squeeze. Thanks for sharing!
ReplyDeleteWorks great! Thanks for this article, helped allot. I did change a few things in the script:
ReplyDeleteSince there aren't many system vars loaded (on my ubuntu machine anyway) i just used env to dump them all. I also added date, who (current logged on identities) and a searchable string.
(echo "Subject: Remote login: $PAM_RHOST"; echo 'Somebody logged on from a remote terminal!'; date ; who ; env) | ssmtp foo@foobar.com | exit 0