Flow chart of the PAM authentication module operation

Running Arbitrary Script on Multiple Login Attempts (Linux)

It so happens that someone was having trouble writing a login script to run after failed attempts. And they needed not only a login script but one to run after some number of failed login attempts and to commit some arbitrary actions.

You could do that with fail2ban, sure. But in this case there’s already a native way to handle it without going outside most standard Linux installs. Because the authentication layer is handled by PAM.d

And it proved to be quite a bit harder than I had anticipated. Which, to be fair, is usually what happens when I’m looking at PAM. It’s usually an “oh, sure, PAM does that”. And then it doesn’t… quite… work. Because there’s some feature that’s not exactly obvious.

So here’s the solution I came up with. And it should work on most distributions (any that use PAM) in most instances. But it may require some modification to be secure or for your specific instance. Please keep that in mind.

And here we go! We’re going to create two scripts to call, one to do our thing and one to reset the pam tally count on successful login. Which frustratingly enough I couldn’t find a way to do internally in PAM.

I’ll start from the beginning and list out the order of changes I made for my specific situation. Remember this is Ubuntu 18.04 LTS running PAM, you may need to modify the settings for other uses, distributions, etc.

New Scripts, Changes to Existing PAM Login Scripts

/etc/pam.d/common-myscript (script to execute on failed login)

#!/bin/bash
# /etc/pam.d/common-myscript

mydate=`date`

# echo `pam_tally` >> /tmp/myoutput.txt # DEBUG
if {pam_tally | awk '{if ($5 >= "2") print $5;}'}
then
        echo "SUCCEEDED test $mydate" >> /tmp/myoutput.txt
fi

/etc/pam.d/common-pam_tally_reset (script to reset pam_tally on successful login

#!/bin/bash
# /etc/pam.d/common-pam_tally_reset
# script to reset all pam_tally totals on successful 
# login attempt

pam_tally --reset

After creating your scripts remember to permission them executable with “chmod +x common-pam_tally_reset common-myscript” (reminder thanks to reddit user up-sky-7)

Originally the /etc/pam.d/common-auth file read

# here are the per-package modules (the "Primary" block)
auth    [success=1 default=ignore]      pam_unix.so nullok_secure
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
auth    optional        pam_ecryptfs.so unwrap
# end of pam-auth-update config

And my changes to get our tally logging correctly in my bog standard install:

# here are the per-package modules (the "Primary" block)
auth    [success=3 default=ignore]      pam_unix.so nullok_secure
auth    optional                        pam_tally.so    per_user
auth    optional                        pam_exec.so     /etc/pam.d/common-myscript
# here's the fallback if no module succeeds
auth    requisite                       pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
auth    optional                        pam_exec.so     /etc/pam.d/common-pam_tally_reset
auth    required                        pam_permit.so
# and here are more per-package modules (the "Additional" block)
auth    optional        pam_ecryptfs.so unwrap
# end of pam-auth-update config

And there you are, a simple way to log how many attempts have been made to log in and throw an error if it’s more than two. I leave figuring out doing this on a per-user basis as an exercise for the reader. Check our growing section of other linux articles.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.