PAM(Pluggable Authentication Modules,可插拔认证模块)是 Linux 系统中负责身份认证的核心框架。在 Debian 及其衍生发行版上,无论是通过 SSH 登录、本地控制台登录,还是执行 sudo 提权操作,背后几乎都有 PAM 的参与。理解 PAM 的配置方式,是系统管理员进行安全加固和定制认证策略的基础功。本文将从原理、配置文件结构、控制标志到实战案例,完整讲解 Debian 下 PAM 模块的配置方法。

一、PAM 的基本原理与模块类型
PAM 的设计思想是将认证逻辑从应用程序中剥离出来。应用程序(如 sshd、login、sudo)只需要调用 PAM 提供的标准接口,具体的认证工作交给一个个独立的模块去完成。这样做的好处是:更换认证方式(比如从本地密码切换到 LDAP 或双因素认证)时,应用程序本身不需要任何修改,只需调整 PAM 配置即可。
PAM 配置中每一行都对应一个模块类型,共分为四种,各自负责认证流程中的不同阶段:
- auth:验证用户身份,例如校验密码是否正确。
- account:检查账户是否被允许登录,例如账户是否过期、是否在允许的登录时间段内。
- password:负责密码的更新与强度校验。
- session:在登录前后执行一些准备工作和清理工作,例如挂载用户目录、记录审计日志、设置资源限制。
这四种类型的执行顺序是固定的:auth 先执行,然后是 account,登录成功后执行 session,涉及改密时才走 password 流程。理解这个顺序对排查登录问题非常重要。
二、Debian 下 PAM 配置文件的结构解析
在 Debian 中,PAM 的配置集中在 /etc/pam.d 目录下,每个文件对应一个服务,例如 /etc/pam.d/sshd、/etc/pam.d/sudo、/etc/pam.d/common-auth。Debian 与 RedHat 系发行版一个显著的区别是:Debian 把通用的认证配置抽取到了 common-* 系列文件中,各个服务文件通过 @include 指令引用它们,避免重复配置。
打开 /etc/pam.d/sshd,你会看到类似下面的内容:
# PAM configuration for the Secure Shell service # Standard Un*x authentication. @include common-auth # This allows certain additional account restrictions account required pam_nologin.so # Standard Un*x authorization. @include common-account # Set up session environment session required pam_env.so @include common-session
配置文件的每一行由四个字段组成:模块类型、控制标志、模块路径、模块参数。模块路径如果在 /lib/x86_64-linux-gnu/security/ 下可以直接写文件名,否则要写绝对路径。以 auth required pam_unix.so nullok 为例,类型是 auth,控制标志是 required,模块是 pam_unix.so,参数 nullok 表示允许空密码账户通过认证。
Debian 常见的 common 系列文件包括 common-auth(通用身份认证)、common-account(通用账户检查)、common-password(通用密码策略)和 common-session(通用会话设置)。修改这些文件会影响所有引用它们的服务,因此改动前建议先备份,并且在一个已经登录的终端会话中操作,避免配置出错把自己锁在系统外面。
三、控制标志的执行逻辑详解
控制标志决定了某个模块验证失败后整个认证流程如何继续,是 PAM 配置中最容易搞混的部分。简单控制标志有四个:
- required:该模块必须通过。即使失败,也会继续执行后续同类型模块,但最终认证一定失败。这样设计是为了不暴露哪个环节出了问题。
- requisite:该模块必须通过。一旦失败,立即终止认证流程,不再执行后续模块。
- sufficient:该模块通过即可放行(前提是之前没有 required 模块失败)。如果失败,则忽略,继续执行后续模块。
- optional:该模块的结果不影响最终认证结论,通常只用于辅助功能如记录日志。
举个例子,假设系统同时配置了本地密码认证和 LDAP 认证,希望两者任一通过即可登录,可以这样写:
# /etc/pam.d/common-auth 片段 auth sufficient pam_unix.so auth sufficient pam_ldap.so auth required pam_deny.so
如果希望必须同时满足两个条件(例如密码正确且来自内网网段),则应把两个模块都设为 required。控制标志的选择直接决定了认证策略的安全性与可用性之间的平衡,配置时一定要想清楚业务需求。
四、实战案例一:登录失败锁定
暴力破解 SSH 是服务器最常见的攻击手段之一。通过 PAM 实现登录失败锁定,可以有效缓解这类风险。在较新的 Debian 版本(Debian 12 及以后)中,推荐使用 pam_faillock:
# 编辑 /etc/pam.d/common-auth,在 pam_unix 之前添加 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 # 在 /etc/pam.d/common-account 中添加 account required pam_faillock.so
上述配置表示同一账户连续失败 5 次后将被锁定 600 秒。用户锁定状态可以通过 faillock --user 用户名 查看,用 faillock --user 用户名 --reset 解锁。
对于较旧的系统,可以使用 pam_tally2 模块,参数类似:auth required pam_tally2.so deny=5 unlock_time=600。需要特别注意模块位置,必须放在 pam_unix.so 之前才能正确计数。配置完成后建议用 sshd -t 检查语法,并在新终端中测试登录,确认正常后再关闭当前会话。
五、实战案例二:使用 pam_limits 限制用户资源
pam_limits 模块通过 session 类型加载,用于限制用户的资源占用,例如最大进程数、打开文件数等。Debian 默认在 /etc/pam.d/common-session 中已经启用了它:
session required pam_limits.so
具体的限制规则写在 /etc/security/limits.conf 中,格式为“域、类型、项目、值”。例如限制 dev 用户最多打开 65536 个文件、最多运行 200 个进程:
dev soft nofile 65536 dev hard nofile 65536 dev soft nproc 200 dev hard nproc 200 * soft core 0
soft 是软限制,用户可以用 ulimit 命令在 hard 范围内自行调整;hard 是硬限制,普通用户无法突破。修改后需要重新登录才生效。对于运行 Java、数据库等服务的账户,合理设置 nofile 限制尤其重要,否则容易出现 Too many open files 报错。
六、配置调试与常见问题排查
PAM 配置出错最直接的后果就是无法登录,因此调试时要格外谨慎。排查的第一步是查看日志,Debian 下认证相关日志主要在 /var/log/auth.log 中,可以配合 journalctl -u ssh 查看 sshd 的详细输出。
几个实用的排查技巧:
- 修改配置前先备份:
cp /etc/pam.d/common-auth /etc/pam.d/common-auth.bak。 - 始终保持至少一个已登录的 root 会话,配置验证无误后再退出。
- 模块文件缺失会导致认证直接失败,可用
ls /lib/x86_64-linux-gnu/security/确认模块是否存在。 - 如果配置了 LDAP 或其他远程认证,网络故障时可用
pam_localuser或sufficient标志保证本地管理员仍能登录。
另外,Debian 提供了 pam-auth-update 工具,用于在软件包安装时统一管理 PAM 配置。如果你手工修改过 common 系列文件,执行该工具时要注意保留自定义内容,避免被覆盖丢失。
总结
PAM 是 Debian 系统认证体系的骨架,掌握它就等于掌握了系统安全策略的定制能力。本文从四种模块类型、配置文件结构、控制标志讲起,再到失败锁定和资源限制两个实战案例,覆盖了日常运维中最常用的场景。实际操作时牢记两条原则:改动前备份,验证前不退出已有会话。做到这两点,即使配置失误也能快速回滚,安全地完成各类认证策略的调整。