在Ubuntu系统中,pam_tally2模块是控制用户登录失败次数并自动锁定账户的核心安全机制。简单来说,当某个用户连续输入错误密码达到设定次数(默认5次),系统就会自动锁定该账户一段时间,防止暴力破解攻击。要配置它,你需要编辑/etc/pam.d/common-auth和/etc/pam.d/common-account文件,在相应位置添加pam_tally2.so的参数,比如deny=5 unlock_time=600,意思是失败5次后锁定600秒。这套机制从Ubuntu 14.04开始就被广泛使用,但到了Ubuntu 22.04和24.04,官方已经逐步推荐用pam_faillock替代pam_tally2,不过pam_tally2依然可用且功能完整。

很多运维人员在管理Ubuntu服务器时,最容易忽略的就是登录失败计数策略。默认情况下,Ubuntu的PAM配置其实并没有启用pam_tally2,也就是说,即使有人疯狂尝试密码,系统也不会自动锁定账户。这是一个非常大的安全隐患,尤其是当你的SSH端口暴露在公网的时候。所以,手动配置pam_tally2是加固Ubuntu服务器的第一步。

pam_tally2的工作原理详解

pam_tally2是Linux PAM(Pluggable Authentication Modules,可插拔认证模块)框架下的一个组件。它的工作方式非常直观:每次用户登录失败,它就在/var/log/faillog文件中给对应用户的失败计数加一;当登录成功时,计数清零。一旦失败次数达到deny参数设定的阈值,该用户账户就会被锁定,在unlock_time指定的时间内无法登录,即使密码正确也不行。只有等计时结束,或者管理员手动重置计数,账户才能恢复正常。

需要注意的是,pam_tally2记录的数据存储在/var/log/faillog这个二进制文件中,你不能直接用cat查看,必须使用pam_tally2命令本身来读取。这一点和很多人想象的"查看日志文件"不一样,它有自己独立的数据存储方式。

如何在Ubuntu中启用pam_tally2

配置pam_tally2需要修改两个PAM配置文件。第一个是/etc/pam.d/common-auth,用于在认证阶段记录失败次数;第二个是/etc/pam.d/common-account,用于在账户验证阶段检查是否被锁定。

首先编辑common-auth文件,在auth部分添加以下内容:

auth required pam_tally2.so deny=5 unlock_time=600 even_deny_root root_unlock_time=3600

然后编辑common-account文件,在account部分添加:

account required pam_tally2.so

参数解释:deny=5表示允许5次失败;unlock_time=600表示锁定600秒(10分钟);even_deny_root表示即使是root用户也会被锁定;root_unlock_time=3600表示root用户锁定时间更长,为3600秒(1小时)。这些参数可以根据你的安全需求自由调整。

修改后如何验证配置是否生效

配置完成后,不需要重启系统,PAM是即时生效的。你可以用一个测试账户故意输错密码来验证。连续输错5次后,再尝试登录,系统会提示"Account locked due to X failed logins"。这时候你就知道配置成功了。

查看当前所有用户的失败登录计数,使用以下命令:

sudo pam_tally2 --user=username

或者查看所有用户的汇总:

sudo pam_tally2

输出结果会显示每个用户的登录次数、失败次数、被锁定状态等信息。如果你发现某个用户被误锁定了,可以用以下命令手动重置:

sudo pam_tally2 --user=username --reset
pam_tally2与pam_faillock的区别和选择

从Ubuntu 18.04开始,pam_faillock作为pam_tally2的升级版本被引入。两者功能几乎一样,但pam_faillock在架构上更现代,支持更细粒度的控制,比如可以针对不同的服务(ssh、su、sudo)分别设置策略。在Ubuntu 22.04和24.04中,pam_faillock已经成为默认推荐方案。

但pam_tally2并没有被废弃,它依然稳定可用。如果你管理的是老版本Ubuntu(14.04、16.04),或者你已经有一套基于pam_tally2的脚本和监控体系,继续使用完全没有问题。两者的配置方式类似,只是模块名和部分参数名不同。pam_faillock用的是pam_faillock.so,参数是deny、unlock_time等,逻辑一致。

常见问题和排错指南

实际部署中,很多人会遇到几个典型问题。第一个是配置了但不生效,这通常是因为参数写错了位置。pam_tally2在common-auth中必须放在其他auth模块之后、pam_unix之前或之后都可以,但顺序会影响行为。建议放在pam_unix.so的后面,这样先走传统密码验证,失败后再由pam_tally2记录。

第二个问题是root用户被锁定后无法解锁。如果你设置了even_deny_root,root也会被锁,这时候你需要通过单用户模式或者从控制台直接登录来重置。单用户模式下不走PAM认证,所以可以绕过锁定直接操作。

第三个问题是/var/log/faillog文件权限问题。这个文件默认只有root可读,如果你用普通用户运行pam_tally2命令查看,会报权限错误。必须加sudo。

还有一个容易被忽视的点:如果你同时配置了pam_tally2和pam_faillock,可能会产生冲突,导致计数混乱。建议二选一,不要混用。如果要迁移到pam_faillock,先把pam_tally2的配置全部清除,再添加pam_faillock的配置。

进阶用法:结合fail2ban实现自动化防护

pam_tally2本身只是记录和锁定,它不会主动封禁IP。如果你想实现更强的防护,可以结合fail2ban使用。fail2ban会监控系统日志(包括/var/log/auth.log),当检测到某个IP短时间内大量失败登录时,自动在iptables或ufw中封禁该IP。而pam_tally2负责在账户层面锁定,两者配合形成双重防护:账户被锁+IP被封,暴力破解基本无解。

具体做法是在fail2ban的jail.local中配置sshd的监控规则,同时确保pam_tally2已经启用。fail2ban的banaction可以设置为同时调用pam_tally2来锁定账户,这样一次攻击就能触发两层防御。

安全建议和最佳实践

从安全角度讲,建议把deny设置为3到5次之间,不要设太高,否则暴力破解有更多尝试机会;unlock_time设为300到900秒比较合理,太短用户容易被误锁,太长则影响正常使用。如果是生产环境的关键服务器,建议deny=3,unlock_time=900,同时开启even_deny_root。

另外,强烈建议配合SSH密钥认证使用,从根本上杜绝密码暴力破解的可能性。pam_tally2只是最后一道防线,当密码认证无法避免时才依赖它。同时,定期用pam_tally2命令检查有没有异常的失败计数,如果某个账户突然出现大量失败记录,说明可能正在被攻击,需要立即排查。

最后提醒一点,Ubuntu 24.04已经开始在新安装中默认使用pam_faillock,如果你是全新部署,建议直接用pam_faillock,配置方式和pam_tally2几乎一样,只是把模块名换掉,参数微调即可。老系统升级时也建议逐步迁移,避免未来版本彻底移除pam_tally2后出现兼容问题。

总结一下,pam_tally2是Ubuntu系统中一个简单但非常有效的账户保护机制。配置只需要改两个文件、加几行参数,就能让你的服务器具备基本的防暴力破解能力。它不复杂,但很多人不知道或者懒得配,这恰恰是最容易被攻击者利用的漏洞。花五分钟配好它,比事后亡羊补牢强得多。