Limiting Failed SSH Logins using PAM

Ever wanted to limit the number of ssh login attempts a user can make before their account gets locked? Well, not really, but when brute force tools are so common and easy to use it’s another useful trick in the sysadmins arsenal.

In this example I’ll show you how to install, configure and audit failed ssh loging attempts on Linux. While the PAM mod_tally module is available for a number of different distros and Unix variants we’ll set it up on Debian. First of all grab the package if you don’t already have it -

apt-get install libpam-modules

Now we’ve installed mod_tally you have to add a couple of lines to the /etc/pam.d/ssh PAM config file for ssh.

$ vi /etc/pam.d/ssh

# add before @include common-auth
# lock the buggers after 3 attempts
auth required pam_tally.so onerr=fail deny=3

# add before @include common-account
# resets count if login successful
account required pam_tally.so reset

The ordering of the lines is important. In some configurations previous PAM checks can shortcut the full process. While this post isn’t the place to learn all about PAM the first line of the example sets what to do if something strange happens, such as the log file being unavailable (onerr=fail) and how many times a login can fail before being locked (deny=3). The second line tells PAM to reset the counter once a successful login has occurred for a specific user. If you leave this one out every failure is remembered for ever and eventually all will be locked out.

Now you’re up and running how do you find out what’s happening? If you want to look at the current status then you can run the pam_tally command and you’ll see output like this -

root@pam:/etc/pam.d# /usr/sbin/pam_tally
User ajones     (1000)   has 2
User lockme     (10010)  has 4

pam_tally also logs wherever your authentication events go (/var/log/auth.log on Debian by default ) so you can keep historical information or feed the attempts in to your normal log monitoring systems

# sample log line
Jan  8 19:16:24 pam pam_tally[30086]: user lockme (10010) tally 4, deny 3

To close the loop let’s cover resetting the locked accounts. If you have a user complaining then you can run pam_tally --reset --user lockme to clear their tally. Another option (worth considering) is a scheduled reset. This gives you the benefit of slowing down brute force attacks while not requiring you to unlock all accidentally locked accounts. The simplest way to do this is to add a cronjob that runs a reset. Newer versions have an unlock_time=n option you can supply in the ssh PAM config file but that didn’t work for me under Etch.