在Ubuntu系统中,如果你想防止暴力破解SSH登录或者本地用户被反复尝试密码,最直接有效的方法就是配置pam_tally2模块。它的核心逻辑非常简单:当某个用户连续输入错误密码达到设定次数后,系统会自动锁定该账户,必须等到解锁时间结束或者管理员手动解锁才能再次登录。这不是什么高深的技术,但很多运维人员在实际部署时容易踩坑,比如配置文件写错位置、参数理解偏差、或者忽略了与其他认证模块的冲突。下面我会从原理到实操,把每一步都讲透。
pam_tally2到底是什么,和pam_tally有什么区别PAM(Pluggable Authentication Modules)是Linux系统的可插拔认证模块框架,pam_tally2就是其中一个专门用来统计登录失败次数的模块。它会在/var/log/faillog文件中记录每个用户的失败登录次数和最近一次失败时间。需要注意的是,pam_tally2在较新的Ubuntu版本(如20.04、22.04)中已经被标记为过时,官方推荐使用pam_faillock替代,但pam_tally2依然可用且配置更直观,很多老系统和生产环境还在用。如果你的系统是Ubuntu 18.04或更早版本,pam_tally2完全没问题;如果是20.04以上,建议了解两者差异后再做选择。
检查系统是否已安装pam_tally2模块在动手配置之前,先确认模块是否存在。打开终端执行以下命令:
find / -name "pam_tally2*" 2>/dev/null
通常你会在/lib/x86_64-linux-gnu/security/或者/usr/lib/x86_64-linux-gnu/security/目录下找到pam_tally2.so这个共享库文件。如果找不到,说明你的系统可能已经移除了它,这时候需要安装libpam-modules包:
sudo apt update sudo apt install libpam-modules核心配置步骤:修改PAM规则文件
Ubuntu的PAM配置文件集中在/etc/pam.d/目录下。你需要根据要保护的服务来选择对应的配置文件。最常见的两个场景是:保护SSH远程登录和保护本地控制台登录。
场景一:保护SSH登录(/etc/pam.d/sshd)
用编辑器打开sshd的PAM配置文件:
sudo vim /etc/pam.d/sshd
在文件末尾(或者auth部分的合适位置)添加以下两行:
auth required pam_tally2.so deny=5 unlock_time=600 even_deny_root root_unlock_time=600 account required pam_tally2.so
参数解释:deny=5表示连续失败5次后锁定;unlock_time=600表示锁定600秒(10分钟)后自动解锁;even_deny_root表示root账户也受同样限制;root_unlock_time=600表示root账户的解锁时间也是10分钟。如果你不想锁定root,可以把even_deny_root去掉。
场景二:保护本地登录(/etc/pam.d/login)
同样的方式编辑login文件:
sudo vim /etc/pam.d/login
添加相同的配置行:
auth required pam_tally2.so deny=5 unlock_time=600 even_deny_root root_unlock_time=600 account required pam_tally2.so
如果你还想保护su命令切换用户的场景,就编辑/etc/pam.d/su文件,添加同样的内容。
配置文件中参数的详细解读很多人配置完发现效果不对,往往是参数没理解清楚。下面把关键参数逐一拆解:
deny=N:这是核心参数,N代表允许的最大失败次数。超过N次就锁定。一般生产环境设3到5次比较合理,设太高没意义,设太低容易误伤正常用户。
unlock_time=秒数:锁定后自动解锁的等待时间。单位是秒。600秒就是10分钟,3600秒是1小时。根据你的安全策略来定,高安全场景可以设3600甚至更长。
even_deny_root:默认情况下pam_tally2不会锁定root用户,加上这个参数后root也会被锁定。强烈建议加上,因为暴力破解最喜欢尝试root账户。
root_unlock_time=秒数:单独为root设置的解锁时间。如果你希望root锁定更久,可以设成比普通用户更大的值。
per_user:这个参数表示每个用户独立计数。如果不加,系统会把所有用户的失败次数累加在一起,这显然不合理。建议始终加上。
magic_root:如果加上这个参数,root用户执行pam_tally2 --reset命令时不需要密码。方便管理员快速解锁,但也有安全隐患,看你权衡。
一个更完善的推荐配置是这样的:
auth required pam_tally2.so deny=5 unlock_time=1800 per_user even_deny_root root_unlock_time=3600 account required pam_tally2.so配置完成后的验证方法
配置写好保存后,不要急着重启服务。先做验证,避免把自己锁在外面。打开一个新的终端窗口(千万不要关闭当前会话),尝试用错误密码登录几次:
ssh testuser@your-server-ip
故意输错5次密码,然后看系统提示是否显示"Account locked due to X failed logins"。如果出现这个提示,说明配置生效了。
你也可以用pam_tally2命令直接查看当前状态:
sudo pam_tally2 --user=testuser
输出会显示该用户的失败次数、最近失败时间、是否被锁定等信息。如果显示"Account is locked",就确认锁定机制在工作。
手动解锁被锁定的账户如果某个用户被误锁定了,管理员可以用以下命令手动解锁:
sudo pam_tally2 --user=testuser --reset
如果你想一次性解锁所有被锁定的用户:
sudo pam_tally2 --reset
注意:解锁操作需要root权限,普通用户无法自行解锁。
与fail2ban配合使用效果更佳pam_tally2只能在系统层面锁定账户,但它有个短板:攻击者可以通过分布式方式从不同IP尝试,每次只试2-3次就换IP,这样永远不会触发锁定阈值。这时候就需要fail2ban来配合。
fail2ban会监控系统日志(包括/var/log/auth.log),当检测到某个IP在短时间内多次尝试失败登录时,直接在防火墙层面(iptables或ufw)封禁该IP。pam_tally2负责锁账户,fail2ban负责封IP,两者形成双层防护。
安装fail2ban:
sudo apt install fail2ban
fail2ban默认就有sshd的jail配置,在/etc/fail2ban/jail.local中可以调整:
[sshd] enabled = true port = ssh filter = sshd logpath = /var/log/auth.log maxretry = 3 bantime = 3600
这样设置后,同一个IP连续3次SSH登录失败就会被封禁1小时。和pam_tally2的5次锁定形成互补。
常见问题和排错指南问题一:配置后SSH无法登录
这通常是因为配置文件语法错误或者参数写错了位置。解决办法是用另一个终端或者通过控制台(如果是云服务器可以用VNC)登录进去,检查/etc/pam.d/sshd文件是否有拼写错误。特别注意auth和account两行都要加,缺一不可。
问题二:锁定后自动解锁不生效
检查unlock_time参数的单位是否正确,必须是秒。另外确认/var/log/faillog文件存在且可写,pam_tally2依赖这个文件记录状态。
问题三:root用户始终不被锁定
确认是否加了even_deny_root参数。有些旧版本的pam_tally2对root的处理逻辑不同,如果加了还不行,检查是否有其他PAM模块在auth部分先于pam_tally2执行了pam_rootok,导致root直接跳过认证。
问题四:Ubuntu 22.04上pam_tally2找不到
22.04默认可能不再包含pam_tally2模块。这时候有两个选择:一是安装libpam-modules包尝试找回;二是迁移到pam_faillock。pam_faillock的配置方式类似但参数名不同,需要单独学习。
安全加固的其他建议光靠pam_tally2还不够,以下几点同样重要:
第一,禁用root密码登录,改用密钥认证。编辑/etc/ssh/sshd_config,设置PermitRootLogin prohibit-password,然后用ssh-keygen生成密钥对。
第二,修改SSH默认端口22为其他端口,比如2222或者更高的随机端口,能减少大量自动化扫描。
第三,设置密码复杂度策略,用pam_pwquality模块强制要求密码长度、大小写、特殊字符等。
第四,定期检查/var/log/auth.log,关注异常登录尝试。可以用aureport或者journalctl来快速筛选。
第五,考虑使用ufw或者iptables限制SSH访问来源IP,只允许特定网段访问管理端口。
总结pam_tally2是Ubuntu系统中一个轻量但实用的账户锁定工具,配置简单、效果直接。核心就是在对应的PAM配置文件中加上auth和account两行规则,设定好失败次数和锁定时间。实际生产环境中建议和fail2ban、密钥认证、端口修改等手段组合使用,构建多层次的安全防护体系。不管你是管理几台服务器还是几百台,这个基础配置都应该作为安全基线的一部分快速落地。
