2. RHEL身份与权限模型
在RHEL中,权限治理的起点不是文件权限位,而是“你是谁、你属于谁、系统如何确认你的身份”。Linux把身份拆成三层:账户名(给人看)、UID/GID(给内核看)、认证与授权策略(给安全边界看)。理解这三层之间的映射关系,才能解释为什么“改了用户名权限没变”“加了组却不生效”“sudo能执行但PAM拒绝登录”等现象。
一、用户与UID:内核只认数字
RHEL中每个用户由 /etc/passwd 中的一行定义,字段依次为:用户名、密码占位符(通常为 x)、UID、主GID、注释、家目录、登录Shell。内核在权限判断时只使用UID,用户名只是给人和工具看的标签。因此,把两个账户改成同一个UID,内核会认为它们是同一个主体,这是权限治理中必须避免的“身份重叠”。
UID的分配有约定边界:0 是root;1–200 为系统静态账户;201–999 为系统动态账户(由安装包创建);普通用户通常从 1000 起。RHEL 7及以后默认使用 1000 作为第一个普通用户UID,可通过 /etc/login.defs 中的 UID_MIN、UID_MAX 调整。查看当前账户身份可用:
id alice
# uid=1001(alice) gid=1001(alice) groups=1001(alice),10(wheel)
getent passwd alice
# alice:x:1001:1001::/home/alice:/bin/bash
注意 id 输出中的 groups 是“当前进程实际生效的组集合”,它不一定等于 /etc/group 中该用户被写入的所有组。这一点是后面排查“组权限不生效”的关键。
二、组与GID:主组与附加组
组用于批量授权。每个用户有一个主组(primary group,记录在 /etc/passwd 第4字段),以及若干附加组(supplementary groups,记录在 /etc/group 的成员列表中)。新建文件时,文件属组默认取进程的有效GID,也就是主组;若目录设置了SGID位,则继承目录属组。
把用户加入 wheel 组是RHEL中常见的提权前置条件:
usermod -aG wheel alice
# -a 必须与 -G 同用,否则会覆盖原有附加组
groups alice
# alice : alice wheel
关键点:usermod -aG 修改的是账户数据库,已登录会话的进程组集合不会自动刷新。用户需要重新登录,或使用 newgrp wheel 开启一个以该组为有效组的新Shell,才能让新组在当前会话中生效。这是“加了组却仍无权限”的最常见原因。
三、影子文件:把口令哈希从passwd中分离
/etc/passwd 必须对所有用户可读,因此不能存放口令哈希。RHEL把哈希与口令老化信息放入 /etc/shadow,仅root可读。其字段为:用户名、加密口令、最后一次修改日期(自1970-01-01起的天数)、最小间隔、最大有效期、警告天数、宽限天数、账户失效日期、保留字段。
chage -l alice
# 最近一次密码修改时间、密码过期时间、账户过期时间等
passwd -S alice
# alice PS 2024-06-01 90 7 14 -1
# 状态 PS=已设密码,LK=锁定,NP=无密码
治理要点:! 或 * 开头的口令字段表示账户不可用密码登录;passwd -l 在哈希前加 ! 锁定,passwd -u 解锁。但锁定密码不等于禁止登录,若账户还配置了SSH公钥,仍可能登录,因此禁用账户应同时处理Shell、SSH密钥与PAM访问控制。
四、sudo机制:授权而非共享root
sudo的核心是“以另一个身份执行命令”,默认策略文件为 /etc/sudoers,并推荐在 /etc/sudoers.d/ 下放独立片段。一条典型规则:
# /etc/sudoers.d/ops
%wheel ALL=(ALL) ALL
alice ALL=(root) NOPASSWD: /usr/bin/systemctl restart httpd
字段含义:用户或组、允许登录的主机、可切换到的目标用户、可执行的命令。使用 visudo 或 visudo -f 编辑可做语法检查,避免写坏sudoers导致全员无法提权。sudo执行时会记录日志(默认 /var/log/secure),并默认要求输入用户自己的密码,而不是root密码——这正是“授权”与“共享口令”的本质区别。
五、PAM架构:认证、账户、会话、口令四类模块
PAM(Pluggable Authentication Modules)把认证逻辑从应用程序中解耦。应用程序(login、sshd、sudo、su等)调用 libpam,由 /etc/pam.d/ 下对应服务文件决定调用哪些模块。PAM处理分为四类:auth(认证身份)、account(账户是否有效、是否过期)、password(修改口令)、session(会话建立与拆除)。每行格式为:类型、控制标志、模块路径、模块参数。
控制标志决定模块结果如何影响整体:required 失败最终失败但继续执行后续模块;requisite 失败立即返回;sufficient 成功则满足该类型;optional 结果通常不影响整体。RHEL默认使用 system-auth 与 password-auth 作为公共堆栈,被各服务文件include。
# /etc/pam.d/system-auth 片段
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so
account required pam_unix.so
account required pam_access.so
password requisite pam_pwquality.so try_first_pass local_users_only
password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok
password required pam_deny.so
session required pam_limits.so
session required pam_unix.so
PAM的治理价值在于:口令复杂度、失败锁定、访问时间限制、资源限制都可以在PAM层统一施加,而不必修改每个应用。例如 pam_pwquality.so 控制口令强度,pam_faillock.so 实现多次失败锁定,pam_access.so 按 /etc/security/access.conf 限制来源。修改PAM后必须验证:保留一个已登录的root会话,另开终端测试目标服务,避免把自己锁在系统外。
六、身份到权限的完整链路
把上述对象串起来看:登录时PAM完成认证与账户检查,内核为进程分配UID/GID集合;访问文件时内核用UID/GID与文件属主、属组、other权限位比对;执行sudo时,sudo先通过PAM认证调用者,再按sudoers规则切换到目标UID执行。任何一环配置错误,都会表现为“权限不对”,但根因可能完全不同。
七、排查思路与治理要点
当出现权限异常时,按“身份—组—策略—日志”顺序定位,比直接改权限位更可靠。先用 id 确认当前进程的UID与组集合,再用 getent passwd/group 确认数据库中的定义,接着检查 /etc/sudoers.d/ 与 /etc/pam.d/ 是否命中,最后查 /var/log/secure 与 ausearch 看实际拒绝原因。常见误区包括:只改用户名不改UID导致身份重叠;用 usermod -G 覆盖了原有附加组;锁定密码却保留SSH公钥;在PAM中把 required 写成 sufficient 导致认证被绕过。
从治理角度看,应坚持最小权限:普通账户不进入 wheel,sudo规则精确到命令而非 ALL,系统账户Shell设为 /sbin/nologin,口令老化与失败锁定由PAM统一施加,所有提权行为留痕可审计。这样,用户、组、UID/GID、影子文件、sudo与PAM就不再是零散配置,而是一条可解释、可验证、可追溯的权限链路。