当Ubuntu系统用户连续多次输入错误密码,默认设置下攻击者仍可无限次尝试登录,这构成了严重的安全隐患。解决这个问题的核心在于配置“失败锁定”策略,即当登录失败次数达到阈值后,临时或永久锁定该用户账户或来源终端。在Ubuntu中,这一切主要通过可插拔认证模块(PAM)及其pam_tally2或更新的pam_faillock模块来实现,同时配合时间策略,可以精细控制锁定的持续时间。

理解PAM:Ubuntu认证的基石

PAM(Pluggable Authentication Modules)是Linux系统中处理身份认证的灵活框架。它通过一系列可配置的模块,将认证过程与具体应用程序(如login, sshd, sudo)解耦。当谈到登录失败锁定,我们主要与Pam_tally2(较旧系统)和Pam_faillock(现代系统,如Ubuntu 20.04及更高版本推荐使用)这两个模块打交道。它们负责计数失败尝试,并在达到限制后执行锁定动作。你的系统使用哪个模块,可以通过检查/etc/pam.d/common-auth等配置文件来确定。

方法一:使用pam_tally2模块配置账户锁定

对于许多Ubuntu版本,pam_tally2是一个经典选择。配置分为两步:首先修改PAM配置文件以启用计数和锁定,其次使用命令行工具进行管理和查看。

1. 编辑PAM认证配置文件:你需要修改/etc/pam.d/common-auth文件,在其中添加pam_tally2模块用于认证阶段。在文件开头附近添加一行:

auth required pam_tally2.so deny=5 unlock_time=600 onerr=succeed file=/var/log/tallylog

这行参数的意思是:deny=5表示连续失败5次后锁定;unlock_time=600表示锁定600秒(10分钟),之后自动解锁;onerr=succeed确保模块出错时不阻断认证流程;file指定记录文件。

2. 编辑PAM账户配置文件:接着,修改/etc/pam.d/common-account文件,添加账户管理阶段的模块:

account required pam_tally2.so

3. 管理与查看锁定状态:配置完成后,使用"pam_tally2"命令管理。查看所有用户失败次数:"sudo pam_tally2"。重置特定用户的计数(解锁):"sudo pam_tally2 --user=用户名 --reset"。若要手动锁定一个用户,可以将其失败次数设为超过阈值:"sudo pam_tally2 --user=用户名 --reset --bad=5"。

方法二:使用更现代的pam_faillock模块

从Ubuntu 20.04 LTS开始,更推荐使用pam_faillock模块,它功能更强大,支持目录存储锁定文件,且默认集成在系统中。配置同样直观。

1. 编辑PAM配置文件:首先,确保/etc/pam.d/common-auth文件中包含以下行(通常可能需要添加):

auth required pam_faillock.so preauth silent audit deny=5 unlock_time=600
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=600
auth sufficient pam_faillock.so authsucc audit deny=5 unlock_time=600

然后,在/etc/pam.d/common-account文件中添加:

account required pam_faillock.so

参数解释:deny=5和unlock_time=600与之前意义相同。preauth在认证前检查,silent不向用户显示消息;authfail处理认证失败;authsucc处理认证成功,重置计数器。

2. 使用faillock命令进行管理:这是pam_faillock的配套工具。查看状态:"sudo faillock"。重置用户:"sudo faillock --user 用户名 --reset"。你可以清晰看到每个用户的失败次数、最近尝试和锁定状态。

精细化的PAM时间策略:基于时间的访问控制

除了失败锁定,PAM还提供pam_time模块,允许你基于时间(如星期几、具体时间段)来控制用户或组的登录权限。这对于限制工作时间外的访问非常有用。配置通过/etc/security/time.conf文件实现。

例如,只允许用户“developer”在工作日的上午9点到下午6点通过ssh登录,配置如下:

# 格式:services;ttys;users;times
sshd;*;developer;Al0900-1800

首先,你需要在相应的PAM服务文件(如/etc/pam.d/sshd)中加入:"account required pam_time.so"。然后编辑time.conf文件。时间字段语法灵活:Al代表周一至周五,Wk代表周末,具体时间范围用HHMM格式表示。这为系统访问增加了另一层时间维度的安全策略。

配置SSH服务增强防护:结合Fail2ban

对于通过SSH的远程登录,仅靠PAM锁定可能不够。因为PAM通常针对本地用户或单个终端会话。网络攻击往往来自大量不同IP。因此,强烈建议结合Fail2ban工具。Fail2ban会监控系统日志(如/var/log/auth.log),当发现来自同一IP的多次失败登录尝试后,它会自动调用iptables或firewalld临时禁止该IP地址。你可以针对SSH服务配置独立的封禁规则和时长,这与PAM的用户账户锁定形成了互补的纵深防御。

关键注意事项与最佳实践

1. 防止root账户被锁的风险:在配置时,务必小心root账户。一旦root被锁定,可能导致无法通过控制台修复。建议在配置行中添加"even_deny_root root_unlock_time=1200"(针对pam_tally2)或"deny_root"(针对pam_faillock)等参数,为root设置不同的、更宽松的阈值或完全排除,并确保你有其他sudo用户可用。

2. 测试!测试!再测试!:在应用到生产环境前,务必在测试环境或另一个终端会话中用普通用户账号测试锁定策略。错误配置可能导致所有用户被锁在外面。始终保持一个活跃的管理员会话用于回滚配置。

3. 锁定与解锁的平衡:设置合理的deny和unlock_time值。太严格(如deny=3, unlock_time=86400)可能误伤合法用户;太宽松则失去安全意义。通常,5-10次失败,锁定10-30分钟是一个合理的起点。

4. 审计与监控:定期检查/var/log/auth.log和/var/log/faillock目录(或/var/log/tallylog),监控登录失败和锁定事件。这有助于你发现攻击企图并调整策略。

5. 配置备份:在修改任何PAM配置文件前,使用"sudo cp /etc/pam.d/common-auth /etc/pam.d/common-auth.backup"进行备份。如果出现问题,可以快速恢复。

总结:构建动态的登录防御层

Ubuntu的登录安全并非一成不变。通过合理配置PAM的失败锁定模块(pam_tally2或pam_faillock),你为系统建立了一道动态的、基于行为的防御门。当异常的重试行为出现时,系统会自动激活锁定。进一步,利用pam_time模块可以叠加基于时间的静态访问策略。而对于面向网络的SSH服务,将PAM与Fail2ban这样的工具结合,能从用户账户和来源IP两个层面实施封锁,极大地提升了暴力破解攻击的门槛。记住,安全是一个层次化的过程,正确配置并理解这些工具,是确保你的Ubuntu系统登录入口坚固可靠的关键一步。