Locking users after X failed login attempts with pam_tally2
Using pam_tally2 on Linux
Most Linux distributions use pluggable authentication modules (PAM). This modular type of configuration allows system administrators to configure and fine-tune the authentication of users. It also defines the behavior on specific events, like providing an invalid user account or password. PAM can use these events to automatically take an action, like locking an account.
Introduction to PAM
The configuration of PAM is not that hard, but there are risks involved in the process of making changes. An incorrect change could result in unauthorized users being able to log in, or authorized users to be locked out. So before you deploy any change to your production systems, get familiar with the configuration by using a test system. A virtual machine on your own system could be a great way to experiment safely, allowing you to stay connected via the console.
To measure the number of failed logins per user, a module is needed to do the counting. Two popular modules for this are pam_tally and pam_tally2, named after tallying. This is the process of counting things. By putting such a module into your PAM stack, failed logins can be measures and an action can be taken based upon the score. Let’s have a look on how to configure this measurement.
Differences between pam_tally and pam_tally2
If you never configured a tallying module, we suggest using pam_tally2. This newer version has minor differences with the pam_tally module.
No more: no_magic_root, reset, no_reset
With pam_tally2 these configuration settings have been dropped. If you are migrating, know that some of the options are no longer available.
The faillog command shows the number of failed authentication attempts per user. For pam_tally2 this command does not work, and the pam_tally2 command itself should used. Use
-a to see all users, or
-u to specify which user you are interested in.
The modules pam_tally and pam_tally2 both use a slightly different format. For this reason they use different filenames
With these differences in mind, it is time to do some configuration.
For both pam_tally and pam_tally2 there is the deny option. This specifies the number of bad logins before taking action.
Another useful setting is unlock_time, a timer before a locked user it automatically unlocked.
The number of seconds that a particular user can’t log in. If this setting is not used, the account will be locked till an administrative user (like root) unlocks the account.
Using pam_tally2 and Ubuntu 16.04
Add the following lines before the configuration block starts, so it is the first configuration item.
auth required pam_tally2.so deny=2 unlock_time=900
This change will be active at the very first login attempt. So it is important to test if you can still log in yourself (via console, SSH, or otherwise). With this configured, most likely you also want to count failed login attempts via SSH. To tell the SSH daemon to use PAM, a few options should be enabled. We can see the active configuration with the
sshd -T command.
sshd -T | grep -E “(challenge|pam)”
This should at least show
usepam yes and
challengeresponseauthentication yes to have SSH work together with PAM and the tallying module. Next step is restarting ssh
systemctl restart ssh.service
Finally, open up a second terminal screen and use an incorrect password when logging in via SSH. This should activate pam_tally and increase the failure counter. This can be checked with the pam_tally2 command itself.
pam_tally -u username
Resetting locked users on Linux
Users will be automatically unlocked when using a lock time. If you want to enforce this, or unlock a permanently locked user, use the
-r option together with the
pam_tally2 -r -u username
Alternatives to pam_tally2
If you don’t like to fiddle with PAM settings, one of the others options is to use the fail2ban package. This can use the log files of the system to determine incorrect logins and add a system (temporarily) to a blacklist via iptables.
Troubles setting up, or got it running on another Linux distribution? Use the comments and we will update this guide.
Michael, I kind of like this idea of just “tally” failed login attempts and lock them out of course. But as usual, I’m stuck, after many attempts to install an OS that works fine with the BTRFS I ended up installing OpenSuSE Leap 42.2 and of course I don’t have a
“/etc/pam.d/auth-common”, though I have a “common-auth” file, I have serious doubt it’s the exact same file and it’s used in the exact same way.
Finally, I’d like to use as much as possible only public keys for ssh(d) authentication but even if private keys are password protected, most of my users use modern desktop and or mobile device and there is nothing we can do for lazy people that just save their password with the app they use instead of in their head where it should be. Even if I chroot every “external” user, I don’t like the idea that anyone gaining access to their device as quasi automatically access to their stuff that is on our server. There must be a better way.
All this to say, how this tallying and locking out would apply to a configuration that doesn’t use password authentication with ssh, only keys? Would this help reduce the flow of (root) login attempt I see in the logs?
I’ve read a couple article provided here and I like what I see, keep up the good work.
Tallying would work for incorrect password attempts, but simply does not stop people and systems trying to log in. I see two common options: move your SSH port, or use a tool like fail2ban to move IP addresses to a blacklist when there are too many failed attempts.
I found that on Ubuntu 16.04 I needed to add the following line above the pam_permit.so line. Otherwise the failcount wasn’t getting reset in certain situations, for example on successful sudo authentication.
# Resets the tally
account required pam_tally2.so
Please correct the following part in your article:
Using pam_tally2 and Ubuntu 16.04
=> It is “common-auth” file not “auth-common”
If I had seen the error earlier, I would have been spent time.
Your article is the only solution for me to work with account lockout policy – great!
But how to automatically reset the failed login counter if the user successfully loged in? This does not work for me.
Thanks, corrected in the article.