29·用户与权限高级

PAM 认证模块

pamauthentication

第29课 - PAM 认证模块

课程: Linux 系统管理与运维
所属模块: 用户与权限
难度: Advanced
标签: pam, authentication
上一课: ACL 访问控制列表
下一课: 登录 Shell 与环境变量


1. 学习目标

完成本课后,你将能够:

  • 理解 PAM (Pluggable Authentication Modules) 的架构和工作原理
  • 掌握 PAM 配置文件的结构和关键指令
  • 能够为常见服务(如 sshd、login)配置 PAM 认证策略
  • 学会编写简单的自定义 PAM 模块
  • 掌握调试 PAM 认证问题的基本方法

2. 核心概念

什么是 PAM?

PAM 是 Linux 系统中模块化的认证框架,它将应用程序的认证逻辑与具体的认证方法分离。想象一下,PAM 就像一个保安团队:

  • 应用程序(如 sshd)是需要被保护的建筑物
  • PAM 是保安系统
  • PAM 模块是不同的保安手段(指纹识别、密码检查、人脸识别等)

PAM 的四大管理组

PAM 通过四种类型来管理认证流程:

管理组功能典型应用
auth认证用户身份(你是谁?)密码验证、指纹扫描
account账户管理(允许登录吗?)检查账户是否过期、登录时间限制
password密码管理(修改密码)密码强度检查、密码历史
session会话管理(登录后做什么)日志记录、挂载用户目录

配置文件结构

PAM 配置文件位于 /etc/pam.d/ 目录下,每个文件对应一个服务。

语法格式

管理组  控制标志  模块路径  [参数]

控制标志 决定模块失败时的行为:

  • required - 必须成功,但延迟返回失败
  • requisite - 必须成功,立即返回失败
  • sufficient - 成功则立即返回成功,失败则继续
  • optional - 成功失败都不影响总体结果

3. 代码示例

示例 1:查看和分析 SSH 的 PAM 配置

# 查看 sshd 的 PAM 配置
cat /etc/pam.d/sshd

# 典型输出分析
# 第一行:auth 类型的模块,required 表示必须成功
auth       required     pam_sepermit.so
# 第二行:认证失败延迟 2 秒(安全措施)
auth       substack     password-auth
auth       include      postlogin
# 账户检查:检查账户是否有效
account    required     pam_nologin.so
account    include      password-auth
# 密码修改规则
password   include      password-auth
# 会话设置:登录后记录日志
session    required     pam_loginuid.so
session    include      password-auth
session    optional     pam_keyinit.so force revoke

示例 2:配置 SSH 使用双因素认证

首先,安装 Google Authenticator PAM 模块:

# 安装必要组件
sudo yum install google-authenticator
# 或
sudo apt install libpam-google-authenticator

# 为用户配置验证器
google-authenticator

然后编辑 /etc/pam.d/sshd

# 在 auth 类型部分添加两行
sudo vi /etc/pam.d/sshd

# 在 "auth required pam_sepermit.so" 下面添加:
auth required pam_google_authenticator.so nullok

注意:nullok 表示没有配置验证器的用户仍可使用密码登录。

示例 3:限制只有特定组可以 SSH 登录

# 编辑 /etc/pam.d/sshd
sudo vi /etc/pam.d/sshd

# 在 auth 类型部分添加以下行(在 include 之前)
auth required pam_listfile.so item=group sense=allow file=/etc/ssh/allowed_groups onerr=fail

# 创建允许的组文件
sudo vi /etc/ssh/allowed_groups

# 添加允许的组(每行一个)
wheel
sysadmin
remote-access

示例 4:自定义 PAM 模块示例

创建一个简单的脚本模块,记录登录尝试:

# 1. 创建 PAM 脚本
sudo vi /etc/pam.d/custom-auth.sh

#!/bin/bash
# custom-auth.sh - 简单的 PAM 执行模块

logger "PAM custom module: Login attempt by user $PAM_USER from $PAM_RHOST"
echo "$(date): Login attempt by $PAM_USER" >> /var/log/custom-auth.log

exit 0  # 返回成功(0 表示成功)

# 2. 设置执行权限
sudo chmod +x /etc/pam.d/custom-auth.sh

# 3. 在 /etc/pam.d/login 中使用(测试环境)
sudo vi /etc/pam.d/login

# 在文件开头添加
auth required pam_exec.so /etc/pam.d/custom-auth.sh

4. 实践练习

练习 1:基础 PAM 配置分析

  1. 查看你系统中 /etc/pam.d/system-auth(CentOS/RHEL)或 /etc/pam.d/common-auth(Ubuntu/Debian)的内容
  2. 解释每一行的作用
  3. 哪个控制标志最为严格?为什么?

预期输出

  • 能正确识别不同管理组的配置行
  • 理解 requiredsufficient 的区别
  • 能指出最常见的认证模块 pam_unix.so

练习 2:配置登录时间限制

配置 PAM 使得普通用户只能在工作时间(周一至周五,9:00-18:00)通过控制台登录。

要求

  1. 修改 /etc/pam.d/login 配置
  2. 使用 pam_time.so 模块
  3. 创建相应的时间配置文件

预期输出

  • 普通用户在工作时间外尝试登录会被拒绝
  • root 用户不受此限制
  • 使用 tail -f /var/log/auth.log 观察日志

练习 3:实现自定义登录信息记录

编写一个 PAM 脚本模块,实现以下功能:

  1. 记录每次成功的登录尝试
  2. 记录用户登录的终端和时间
  3. 将信息保存到 /var/log/user-logins.log

预期输出

2024-03-15 14:30:22 | user: admin | terminal: /dev/tty1 | service: login
2024-03-15 14:35:47 | user: john | terminal: /dev/pts/0 | service: sshd

5. 常见错误

错误 1:依赖顺序问题

# 错误配置:sufficient 在 required 之前
auth sufficient pam_ldap.so
auth required pam_unix.so

# 如果 LDAP 成功,直接返回成功,不会检查密码
# 修复:把 required 放在前面或使用 include

错误 2:模块路径错误

# 错误:模块不存在或路径不正确
auth required /usr/lib/security/pam_wrong.so

# 诊断方法:
find / -name "pam_*.so" | head  # 查找实际模块位置

错误 3:SELinux 干扰

# 自定义模块可能被 SELinux 阻止
# 检查 SELinux 日志
sudo ausearch -m avc -ts recent

# 临时设置宽容模式测试
sudo setenforce 0

错误 4:配置文件语法错误

# 常见错误:缺少冒号、参数格式错误
auth required:pam_tally2.so  # 错误:多了冒号

# 验证配置语法
sudo pamtester -v login testuser authenticate

错误 5:忘记备份

# 危险操作前一定要备份!
sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.backup.$(date +%Y%m%d)

# 如果 PAM 配置错误导致无法登录:
# 1. 使用救援模式启动
# 2. 挂载根文件系统
# 3. 恢复备份或注释掉问题行

6. 小结

关键要点回顾

  1. PAM 架构:模块化的认证框架,将认证逻辑与应用程序分离
  2. 四大管理组:auth(认证)、account(账户)、password(密码)、session(会话)
  3. 配置文件:位于 /etc/pam.d/,每个服务一个文件
  4. 控制标志required(必须成功)、requisite(立即失败)、sufficient(成功即停)、optional(不影响总体)
  5. 模块顺序:配置顺序很重要,从上到下依次执行
  6. 安全实践
    • 修改前必须备份配置文件
    • 在生产环境测试 PAM 更改要谨慎
    • 保留一个 root 登录会话作为备用

进阶思考

PAM 的模块化设计允许系统管理员灵活组合不同的认证方式,这是企业级 Linux 安全管理的基石。理解 PAM 不仅有助于系统配置,更是安全审计和故障排查的重要技能。

下一课预告:我们将学习"登录 Shell 与环境变量",了解用户登录后 Shell 如何初始化,以及环境变量如何影响程序行为。


扩展阅读

  • man pam.conf - PAM 配置文件格式详解
  • man pam.d - PAM 目录结构说明
  • /usr/share/doc/pam-*/ - PAM 模块文档
  • 《Linux PAM - 认证的艺术》(在线文档)

练习编辑器

rust
Loading...

继续学习

完成本课后,建议继续学习下一课「登录 Shell 与环境变量」 以巩固所学知识。