sudo 与 PAM¶
本文你会学到:
su与sudo的本质区别- sudo 的工作流程与密码缓存机制
/etc/sudoers配置文件的语法与最佳实践- 用
visudo安全编辑 sudoers - 针对单个命令、命令组进行精细授权
- 环境变量的继承与隔离(
env_keep、env_reset) - 日志审计与 sudoreplay 回放
- NOPASSWD 与免密 sudo 的场景应用
- PAM(可插拔认证模块)的基础概念
- sudo 与 PAM 协同工作的原理
sudo 的工作原理¶
为什么需要 sudo?¶
想象一下这个场景:你的团队有 5 个运维人员,都需要重启 nginx,但你不想把 root 密码告诉他们,因为 root 可以做任何事——包括误删系统文件。
sudo 解决的正是这个问题:按策略授权,让指定用户执行特定命令,使用自己的密码验证身份,操作全程留有审计日志。
su 与 sudo 的核心区别¶
su |
sudo |
|
|---|---|---|
| 验证密码 | 目标用户的密码(通常是 root 密码) | 自己的密码 |
| 效果 | 完全切换到目标用户身份 | 以目标用户身份执行单条命令 |
| 权限粒度 | 全或无 | 可精细控制到具体命令 |
| 审计日志 | 无(只记录切换行为) | 每条命令都有记录 |
sudo 的执行流程¶
当用户执行 sudo 时,系统按以下步骤处理:
- 在
/etc/sudoers中查找该用户是否有sudo权限 - 若有权限,提示用户输入**自己的密码**确认身份(root 执行
sudo不需要密码) - 密码正确后执行后续命令
- 若切换的身份与执行者相同,也不需要密码
sudo 缓存
首次执行 sudo 后,认证结果会缓存 5 分钟。在这段时间内再次执行 sudo 不需要重新输入密码。可以用 sudo -k 立即清除缓存。
配置 sudo:/etc/sudoers¶
永远用 visudo 编辑¶
直接用 vi 编辑 /etc/sudoers 很危险——一旦语法错误,所有用户都将无法使用 sudo,而你可能因此被锁在系统外。
visudo 在退出时会自动做语法检查,有错误会提示你修改,不会写入损坏的配置:
sudoers 语法格式¶
每一行的基本格式:
内置关键字 ALL 代表"任意"(任意主机、任意身份、任意命令)。
常见配置示例¶
命令必须使用绝对路径
/etc/sudoers 中的命令字段**必须填写绝对路径**,否则 visudo 会报语法错误。使用 which 命令名 可以查到绝对路径。
别名简化批量配置¶
当需要为多个用户、主机或命令配置相同规则时,别名可以大幅减少重复:
| sudoers 别名定义示例 | |
|---|---|
/etc/sudoers.d/ 目录¶
直接修改 /etc/sudoers 主文件有一定风险。推荐的做法是在 /etc/sudoers.d/ 目录下创建独立的配置文件,每个团队或应用对应一个文件,模块化管理、互不干扰:
Defaults 行:全局行为调整¶
| 常用 Defaults 配置 | |
|---|---|
sudo 常用命令¶
PAM 认证框架¶
为什么需要 PAM?¶
在 PAM 出现之前,每个程序都需要自己实现登录验证逻辑——login 一套、sshd 一套、su 一套,密码策略难以统一,更改认证方式需要重新编译程序。
PAM(Pluggable Authentication Modules,可插拔认证模块) 把认证逻辑从程序中剥离出来,抽象成一套统一的 API。程序只需调用 PAM API,具体用什么方式认证(密码、指纹、LDAP、双因素)由配置文件决定,程序本身不需要修改。
graph LR
A[应用程序\nssh / login / sudo] -->|调用 PAM API| B[PAM 框架]
B -->|读取配置| C[/etc/pam.d/服务名]
B --> D[pam_unix.so\n密码认证]
B --> E[pam_ldap.so\nLDAP 认证]
B --> F[pam_google_authenticator.so\n双因素认证]
D & E & F -->|返回结果| B
B -->|成功/失败| A
classDef app fill:transparent,stroke:#0288d1,color:#adbac7,stroke-width:2px
classDef pam fill:transparent,stroke:#388e3c,color:#adbac7,stroke-width:2px
classDef mod fill:transparent,stroke:#768390,color:#adbac7,stroke-width:1px
classDef conf fill:transparent,stroke:#f57c00,color:#adbac7,stroke-width:1px
class A app
class B pam
class C conf
class D,E,F mod
PAM 四种模块类型¶
PAM 把认证过程分为四个阶段,每个阶段使用对应类型的模块:
| 类型 | 英文全称 | 职责 |
|---|---|---|
auth |
authentication | 验证用户身份(如密码校验) |
account |
account | 检查账号状态(是否过期、是否有访问权限) |
password |
password | 处理密码修改(强度检查、更新密码) |
session |
session | 管理会话(登录/登出时的环境设置、日志记录) |
这四种类型通常有顺序:先验证身份(auth)→ 检查账号权限(account)→ 管理会话(session)→ 修改密码时才涉及(password)。
PAM 控制标志¶
控制标志决定某个模块的验证结果如何影响整体认证流程:
| 标志 | 含义 |
|---|---|
required |
必须成功;失败时继续检查其他模块(但最终会失败)。最常用,便于日志记录 |
requisite |
必须成功;失败时**立即终止**并返回失败,不再检查后续模块 |
sufficient |
成功时**立即终止**并返回成功(前提是之前没有 required 失败);失败时继续 |
optional |
结果通常不影响整体;只有在 required/sufficient 都不存在时才起决定作用 |
记忆技巧
required 和 requisite 都是失败就最终失败,区别是是否继续走流程。sufficient 和 requisite 是镜像关系:成功时 sufficient 立即终止,失败时 requisite 立即终止。
PAM 配置文件位置¶
每个服务在 /etc/pam.d/ 下对应一个同名配置文件:
每一行格式:验证类型 控制标志 模块路径 [模块参数]
| 典型 /etc/pam.d/sshd 配置(精简版) | |
|---|---|
配置中的 include 关键字表示引入另一个配置文件的内容:
常用 PAM 模块¶
| 模块 | 功能 |
|---|---|
pam_unix.so |
传统 /etc/shadow 密码认证,功能最全面(auth/account/password/session 都支持) |
pam_securetty.so |
限制 root 只能从 /etc/securetty 列出的终端登录(这就是为什么 root 不能 telnet) |
pam_nologin.so |
若 /etc/nologin 文件存在,拒绝所有普通用户登录 |
pam_pwquality.so |
密码复杂度检查(最小长度、字符类型要求等) |
pam_limits.so |
资源限制,即 ulimit 功能,配置文件为 /etc/security/limits.conf |
pam_access.so |
基于 /etc/security/access.conf 的细粒度访问控制 |
pam_faillock.so |
登录失败次数统计与账号锁定(RHEL 8+,推荐) |
pam_tally2.so |
登录失败计数与锁定(较旧系统) |
pam_env.so |
设置额外环境变量 |
pam_selinux.so |
认证期间临时关闭 SELinux,验证通过后再启用 |
pam_ldap.so / pam_sss.so |
LDAP / SSSD 集中认证 |
pam_google_authenticator.so |
Google Authenticator 两步验证 |
密码强度策略:pam_pwquality¶
配置密码复杂度¶
pam_pwquality.so 模块通过 /etc/security/pwquality.conf 配置密码策略:
| /etc/security/pwquality.conf | |
|---|---|
在 /etc/pam.d/system-auth(或 common-password)中启用:
登录失败锁定:pam_faillock¶
防止暴力破解¶
配置 /etc/security/faillock.conf:
| /etc/security/faillock.conf | |
|---|---|
常用管理命令:
资源限制:limits.conf¶
pam_limits.so 读取 /etc/security/limits.conf,为用户或组设置系统资源上限:
| /etc/security/limits.conf 示例 | |
|---|---|
修改后何时生效?
limits.conf 的修改对**已登录用户无效**,只对下次登录生效。这是因为 PAM 在程序启动时调用,不是持续监控。
发行版差异¶
sudo组名为sudo(而非wheel),新建用户加入sudo组即可使用sudo- PAM 密码策略包:
libpam-pwquality(需手动安装apt install libpam-pwquality) - 配置文件:
/etc/pam.d/common-password(而非system-auth) - 旧系统用
pam_tally2.so,新版(Ubuntu 22.04+)已切换到pam_faillock.so - PAM 通用配置分散在
/etc/pam.d/common-auth、common-account、common-password、common-session
sudo组名为wheel,CentOS 7+ 默认已在 sudoers 中启用%wheel行pam_faillock.so从 RHEL 8 起默认集成,开箱即用- PAM 通用配置集中在
/etc/pam.d/system-auth和/etc/pam.d/password-auth - 推荐使用
authselect管理 PAM 配置,避免直接编辑容易被工具覆盖的文件:
PAM 问题排查¶
遇到无法登录或认证异常时,PAM 的日志是第一现场:
日志中会出现类似 pam_unix(sshd:auth): authentication failure 或 pam_faillock: user alice locked 的信息,直接指向问题所在的模块。