linux pam不提供失败延迟功能,仅通过pam_faillock.so配置fail_interval、deny和unlock_time实现滑动窗口锁定;需在common-auth和sshd中均添加三行严格顺序的auth规则,并用faillock命令管理状态。

Linux PAM 本身不提供“失败延迟”(即输错密码后强制等待几秒再试)功能,它只做计数、锁定与状态检查。所谓“增加失败延迟”,实际是通过账户锁定策略间接实现的防护效果——用户被锁后无法登录,自然形成时间阻断。真正有效的做法不是加延迟,而是用 pam_faillock.so 配置带时间窗口的失败锁定,这是当前主流发行版唯一推荐且安全可靠的机制。
为什么不能靠“延迟响应”防暴力破解
单纯在认证流程中插入 sleep 或延时,既无法阻止并发连接尝试,也无法对抗分布式爆破。攻击者可同时发起成百上千个 SSH 连接,每个都独立走认证流程,延时对整体攻击速度几乎无影响。PAM 设计初衷是状态控制,不是流量节流。
- SSH 层面的 MaxAuthTries 控制单次连接内最多试几次密码,但不跨连接累积
- 系统级防护必须依赖 pam_faillock.so 的 fail_interval + deny 组合,实现「60 秒内连续失败 5 次即锁 15 分钟」这类滑动窗口策略
- 旧模块 pam_tally2.so 不支持时间窗口,已在 Ubuntu 22.04+、RHEL 8+、Debian 12+ 中废弃
正确配置 pam_faillock.so 实现强防护
以 Ubuntu/Debian 系统为例,在 /etc/pam.d/common-auth 开头添加三行(顺序不可颠倒):
-
preauth 行:记录失败但不拒绝,加
silent避免暴露用户名是否存在auth [default=ignore] pam_faillock.so preauth silent deny=5 unlock_time=900 fail_interval=60 -
authfail 行:真正触发拒绝,放于 pam_unix.so 之后
auth [default=die] pam_faillock.so authfail deny=5 unlock_time=900 fail_interval=60 -
account 行:启用状态检查,防止绕过锁定
account required pam_faillock.so
注意:deny=5 是触发阈值,fail_interval=60 表示只统计最近 60 秒内的失败,unlock_time=900 即 15 分钟自动解锁。所有参数在三行中必须完全一致。
SSH 登录必须单独配置生效
仅改 common-auth 只影响本地终端和 su,对 SSH 无效。还需编辑 /etc/pam.d/sshd,同样插入上述三行(位置建议在 #%PAM-1.0 注释下方、其他 auth 行之前)。否则你会测试半天发现 root 能登、普通用户也照登不误。
- 验证方式:用错误密码反复登录目标用户,执行
faillock --user username查看计数是否递增 - 锁定后日志会写入
/var/log/auth.log,搜索pam_faillock或Authentication failure - 若误锁自己,用 root 执行
faillock --user username --reset立即恢复
避免 root 被锁导致运维中断
默认情况下 pam_faillock.so 不锁定 root,这是合理设计。如需合规强制锁定,必须显式添加 even_deny_root 参数,并建议设更长解锁时间(如 unlock_time=3600),同时确保 root 有密钥登录或 sudo 权限备用。
- 更稳妥的做法是加
silent跳过 root 计数,或用pam_succeed_if.so排除关键账户 - 对于 SSH 密钥登录等免密场景,可在 /etc/pam.d/sshd 中前置判断,避免干扰正常运维流程
- 切勿在未备份原配置、未开好备用 root 会话的情况下直接重载 sshd











