4、用户与权限管理

Linux 系统的安全模型建立在“用户—组—权限”三层体系之上。用户是访问控制的实体,组是权限分配的集合,而权限则定义了实体对文件或目录的可执行操作边界。在计算机四级考试与真实运维场景中,用户与权限管理不仅是命令的记忆,更是对 Linux 安全策略设计思路的检验。本章将围绕用户/组管理、密码策略、sudo 机制、ACL 访问控制列表及特殊权限五大核心模块展开,结合命令实操与案例复盘,帮助您建立系统化的权限管理知识框架。

Linux 用户与权限管理核心架构 用户/组管理 • useradd / usermod • groupadd / groupmod • /etc/passwd, /etc/shadow • UID/GID 分配规则 密码策略 • 老化周期 /etc/login.defs • chage 命令管理 • PAM pwquality 模块 • 复杂度与过期策略 sudo 机制 • /etc/sudoers 配置 • visudo 安全编辑 • 最小权限授权 • 日志审计 /var/log/secure ACL 访问控制 • setfacl / getfacl • 用户/组附加权限 • mask 有效权限掩码 • 默认 ACL 继承 特殊权限 • SUID (4xxx) 临时提权 • SGID (2xxx) 组继承 • Sticky (1xxx) 防删除 • chmod u+s / g+s / o+t 安全 五大模块协同工作:用户/组是基础,密码策略是入口防线,sudo 控制提权,ACL 细化授权,特殊权限应对特定场景

4.1 用户与组管理:从命令到底层文件

4.1.1 核心原理:用户与组的映射关系

Linux 系统中,用户账号信息存储于 /etc/passwd,密码密文存储于 /etc/shadow,组信息存储于 /etc/group。每个用户通过唯一的 UID(用户标识号)被内核识别,而组通过 GID(组标识号)进行权限聚合。用户与组之间是多对多的关系:一个用户可以属于多个组,其中“初始组”在创建时指定,“附加组”通过 usermod -G 追加。理解这一映射关系是权限管理的基础,因为文件权限中的“属主、属组、其他”三个维度正是基于 UID 和 GID 进行匹配的。

4.1.2 操作流程:用户与组的生命周期管理

操作类型命令示例关键参数说明底层文件变更
创建用户useradd -m -G wheel -s /bin/bash alice-m 创建家目录;-G 附加组;-s 指定 shell/etc/passwd、/etc/shadow、/etc/group、/home/alice
修改用户usermod -L alice(锁定)-L 锁定;-U 解锁;-aG 追加组/etc/shadow 中密码字段前加 !
删除用户userdel -r alice-r 同时删除家目录和邮件池移除上述文件中的相关记录
创建组groupadd -g 5000 devteam-g 指定 GID,避免自动分配冲突/etc/group、/etc/gshadow
修改组groupmod -n newname devteam-n 重命名组/etc/group 中组名变更
经验提示:生产环境中创建用户时,建议使用 useradd -D 查看默认值,并通过 /etc/login.defs 预设 UID 范围(通常 1000-60000)、密码过期天数等参数。对于服务账号(如 nginx、mysql),应使用 -M 不创建家目录,并设置 -s /sbin/nologin 禁止登录,降低安全风险。

4.1.3 案例拆解:批量创建项目组用户

场景:某公司新成立“数据平台”项目组,需要为 5 名工程师创建账号,统一加入 data_team 组,并要求所有用户使用 bash shell、家目录位于 /home 下。

# 1. 创建组(指定 GID 避免冲突)
groupadd -g 5200 data_team

# 2. 批量创建用户并加入组
for user in zhangsan lisi wangwu zhaoliu sunqi; do
    useradd -m -G data_team -s /bin/bash "$user"
    echo "$user:InitialPass123" | chpasswd   # 设置初始密码
    chage -d 0 "$user"   # 强制首次登录修改密码
done

# 3. 验证
grep data_team /etc/group
id zhangsan

复盘:通过 chage -d 0 强制首次登录改密,避免初始密码长期有效;使用 chpasswd 批量设置密码比交互式 passwd 更高效。若需临时禁用某用户,使用 usermod -L 而非删除,保留数据便于后续审计。

4.1.4 常见误区与总结

  • 误区一:直接编辑 /etc/passwd 修改用户信息。正确做法是使用 usermod,因为直接编辑容易导致文件格式错误或缓存不一致。
  • 误区二:混淆 useradd 与 adduser。在 CentOS/RHEL 中 adduser 是 useradd 的符号链接;在 Debian/Ubuntu 中 adduser 是交互式脚本,行为不同。
  • 误区三:忽略 UID 复用风险。删除用户后若立即创建新用户,系统可能复用原 UID,导致旧文件属主变为新用户,造成权限泄露。

4.2 密码策略:入口安全的第一道防线

4.2.1 核心原理:影子密码与老化机制

现代 Linux 使用 /etc/shadow 存储加密密码,字段以冒号分隔,共 9 个字段:用户名、加密密码、最后一次修改时间、最小修改间隔、最大有效天数、警告天数、宽限天数、失效日期、保留字段。密码策略的核心在于通过 chage 命令和 /etc/login.defs 文件控制密码的生命周期,防止密码长期不变带来的暴力破解风险。

4.2.2 操作流程:制定并实施密码策略

  1. 设置全局默认值:编辑 /etc/login.defs,设置 PASS_MAX_DAYS 90、PASS_MIN_DAYS 7、PASS_WARN_AGE 14。
  2. 配置复杂度要求:通过 PAM 模块 pam_pwquality.so,在 /etc/pam.d/system-auth 中设置 minlen=12、dcredit=-1(至少一个数字)、ucredit=-1(至少一个大写字母)。
  3. 对单个用户实施策略:使用 chage -M 90 -m 7 -W 14 alice 设置最大有效天数、最小间隔和警告天数。
  4. 查看策略:chage -l alice 显示当前用户的密码老化信息。
风险提示:密码策略过严会导致用户将密码写在便签上或频繁重置;过松则形同虚设。建议结合企业安全等级,采用“长度优先 + 复杂度辅助”的策略,例如最小长度 14 位,不强制要求特殊字符,但禁止包含用户名或常见字典词。

4.2.3 案例拆解:等保三级密码策略落地

背景:某政务系统需满足等保三级要求,密码策略必须包含:90 天更换、复杂度四级、连续失败 5 次锁定账号 30 分钟。

# 1. 修改 /etc/login.defs
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs
sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS 7/' /etc/login.defs

# 2. 配置 PAM 密码复杂度
echo "password requisite pam_pwquality.so try_first_pass local_users_only retry=3 minlen=14 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1" >> /etc/pam.d/system-auth

# 3. 配置账号锁定策略(/etc/pam.d/system-auth 中添加)
echo "auth required pam_faillock.so preauth audit silent deny=5 unlock_time=1800" >> /etc/pam.d/system-auth
echo "auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=1800" >> /etc/pam.d/system-auth

结果验证:使用弱密码 password123 测试,系统拒绝并提示复杂度不足;连续输错 5 次密码后,账号被锁定 30 分钟,pam_faillock 记录于 /var/log/faillock。

4.2.4 常见误区与总结

  • 误区一:仅修改 /etc/login.defs 而不重启服务。实际上该文件在用户下次登录时自动生效,无需重启。
  • 误区二:忽略 chage -d 0 的强制改密效果。该命令将“最后一次修改时间”设为 0,系统判定密码已过期,强制用户下次登录修改。
  • 误区三:PAM 配置顺序错误导致无法登录。修改 PAM 前务必备份原文件,并通过 pam_tally2 或 pam_faillock 测试验证。

4.3 sudo 机制:精细化提权管理

4.3.1 核心原理:从 su 到 sudo 的演进

su 命令需要目标用户密码,且切换后拥有完全权限,难以审计;sudo 则基于 /etc/sudoers 策略,允许授权用户以特定身份执行特定命令,并记录日志。sudo 的核心优势在于:最小权限分配(只授予必要命令)、可审计性(所有执行记录在案)、无需共享 root 密码。

4.3.2 操作流程:配置 sudo 策略

# 1. 使用 visudo 编辑(语法检查)
visudo

# 2. 配置示例
# 允许 alice 以 root 身份执行所有命令
alice ALL=(ALL) ALL

# 允许 devops 组执行系统管理命令,无需密码
%devops ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/yum

# 允许 bob 仅能重启 Apache
bob ALL=(root) /usr/bin/systemctl restart httpd

# 3. 验证配置
sudo -l -U alice
配置项含义示例
用户/组授权对象,组前加 %%wheel 表示 wheel 组
主机列表允许执行的主机ALL 表示所有主机
身份切换以哪个用户身份执行(ALL) 可切换为任何用户
命令列表允许执行的命令路径/usr/bin/systemctl
标签NOPASSWD、NOEXEC 等NOPASSWD: 免密执行

4.3.3 案例拆解:运维人员 sudo 权限分级

场景:某互联网公司运维团队分为初级、高级、DBA 三个角色,需要分别授予不同级别的 sudo 权限。

# 定义命令别名
Cmnd_Alias SERVICE_CMDS = /usr/bin/systemctl, /usr/sbin/service
Cmnd_Alias PKG_CMDS = /usr/bin/yum, /usr/bin/dnf
Cmnd_Alias DB_CMDS = /usr/bin/mysql, /usr/bin/mysqldump

# 初级运维:只能查看服务状态和日志
junior_ops ALL=(ALL) /usr/bin/systemctl status *, /usr/bin/tail /var/log/messages

# 高级运维:管理服务、安装软件包
%senior_ops ALL=(ALL) SERVICE_CMDS, PKG_CMDS

# DBA:数据库操作,禁止其他 root 权限
dba_team ALL=(root) DB_CMDS, /usr/bin/mysqladmin

复盘:通过命令别名提高可读性;使用通配符 * 时需注意安全风险(如 systemctl status * 可能被利用读取敏感文件),建议使用 sudoedit 或精确命令路径。所有 sudo 操作记录在 /var/log/secure,定期审计可发现异常提权行为。

4.3.4 常见误区与总结

  • 误区一:直接编辑 /etc/sudoers 而非使用 visudo。语法错误可能导致 sudo 完全失效,visudo 提供语法检查。
  • 误区二:授予 ALL=(ALL) ALL 给普通用户。这等同于赋予 root 权限,违背最小权限原则。
  • 误区三:忽略 sudo 日志审计。应定期检查 /var/log/secure 中的 sudo 记录,发现异常命令执行及时响应。

4.4 ACL 访问控制列表:超越传统权限的精细控制

4.4.1 核心原理:ACL 的扩展能力

传统权限仅支持“属主、属组、其他”三类,无法满足“多个特定用户或组对同一文件有不同权限”的需求。ACL(Access Control List)在传统权限之上扩展了访问控制条目,允许为任意用户或组单独设置权限。ACL 通过 setfacl 和 getfacl 管理,其底层在文件扩展属性中存储 ACL 条目。

4.4.2 操作流程:ACL 的配置与验证

# 1. 为文件添加用户 ACL
setfacl -m u:alice:rwx /data/project

# 2. 为文件添加组 ACL
setfacl -m g:devteam:r-x /data/project

# 3. 设置默认 ACL(目录继承)
setfacl -m d:u:alice:rwx /data/project

# 4. 查看 ACL
getfacl /data/project

# 5. 移除 ACL
setfacl -x u:alice /data/project
关键概念:mask 是 ACL 的有效权限掩码,它限制了所有命名用户、命名组和默认 ACL 的最大权限。例如,若 mask 为 r-x,即使 alice 的 ACL 为 rwx,其实际有效权限也是 r-x。使用 setfacl -m m::rx 可调整 mask。

4.4.3 案例拆解:共享目录的协作权限设计

背景:研发部门需要共享 /srv/project 目录,要求:项目经理拥有完全控制权;开发人员可读写但不可删除他人文件;测试人员只读;外部顾问仅可访问 docs 子目录。

# 1. 创建目录结构
mkdir -p /srv/project/{src,docs,releases}

# 2. 设置传统权限(属主 root,属组 devteam)
chown root:devteam /srv/project
chmod 770 /srv/project

# 3. 设置 ACL
setfacl -m u:pm:rwx /srv/project
setfacl -m g:devteam:rwx /srv/project
setfacl -m g:testers:r-x /srv/project
setfacl -m u:consultant:r-x /srv/project/docs

# 4. 设置默认 ACL 确保新文件继承
setfacl -m d:u:pm:rwx /srv/project
setfacl -m d:g:devteam:rwx /srv/project
setfacl -m d:g:testers:r-x /srv/project

# 5. 验证
getfacl /srv/project

复盘:ACL 解决了传统权限无法实现的“多用户不同权限”问题。但需注意:ACL 会增加文件系统开销,且 NFS 等网络文件系统需开启 ACL 支持。此外,tar 备份时需使用 --acls 选项保留 ACL 信息。

4.4.4 常见误区与总结

  • 误区一:认为 ACL 可以完全替代传统权限。实际上 ACL 是传统权限的补充,两者协同工作。
  • 误区二:忽略 mask 的影响。当使用 chmod 修改文件权限时,可能会意外改变 mask 值,导致 ACL 权限“失效”。
  • 误区三:在根文件系统未开启 ACL 支持时使用。现代 Linux 默认支持,但挂载时可加 acl 选项确保。

4.5 特殊权限:SUID、SGID 与 Sticky Bit

4.5.1 核心原理:特殊权限的语义

特殊权限数值表示符号表示作用对象核心效果
SUID4u+s可执行文件执行者临时获得文件属主的权限
SGID2g+s可执行文件/目录文件:执行者获得属组权限;目录:新文件继承属组
Sticky Bit1o+t目录仅文件属主、目录属主或 root 可删除文件

4.5.2 操作流程:设置与验证特殊权限

# 设置 SUID(例如 /usr/bin/passwd)
chmod u+s /usr/bin/myapp
chmod 4755 /usr/bin/myapp

# 设置 SGID(目录继承组)
chmod g+s /srv/shared
chmod 2770 /srv/shared

# 设置 Sticky Bit(例如 /tmp)
chmod o+t /tmp
chmod 1777 /tmp

# 验证
ls -l /usr/bin/myapp   # 显示 -rwsr-xr-x
ls -ld /srv/shared     # 显示 drwxrws---
ls -ld /tmp            # 显示 drwxrwxrwt

4.5.3 案例拆解:SGID 实现团队目录自动继承

场景:开发团队需要共享 /srv/dev 目录,所有新创建的文件必须自动属于 devteam 组,且组内成员可互相编辑。

# 1. 创建目录并设置 SGID
mkdir /srv/dev
chown root:devteam /srv/dev
chmod 2770 /srv/dev

# 2. 验证 SGID 效果
touch /srv/dev/testfile
ls -l /srv/dev/testfile   # 显示 -rw-r--r-- 1 root devteam

# 3. 结合 ACL 实现更细粒度控制
setfacl -m d:g:devteam:rwx /srv/dev

复盘:SGID 目录确保新文件自动继承属组,避免了每次创建后手动 chgrp 的繁琐操作。但需注意:SGID 对脚本文件无效(脚本执行时 SUID/SGID 位被忽略),仅对二进制可执行文件有效。

4.5.4 常见误区与总结

  • 误区一:对 shell 脚本设置 SUID。Linux 内核出于安全考虑,会忽略脚本文件的 SUID/SGID 位。
  • 误区二:在目录上设置 SUID。SUID 对目录无意义,应使用 SGID 实现组继承。
  • 误区三:忽视 Sticky Bit 的适用范围。Sticky Bit 仅对目录有效,对文件设置无实际作用。
安全警示:SUID 文件是提权攻击的高危目标。运维人员应定期使用 find / -perm -4000 -type f 扫描系统中的 SUID 文件,确认每个 SUID 文件的必要性。对于不再需要的 SUID 权限,及时使用 chmod u-s 移除。

4.6 综合实战:企业权限管理方案设计

背景:某金融科技公司新上线一个交易系统,服务器为 CentOS 9,需要设计一套完整的用户与权限管理方案,满足以下需求:开发人员可部署代码但不可修改配置;运维人员可管理服务但不能查看交易数据;审计人员只读所有日志;外包人员仅可访问测试环境。

方案设计:

  1. 用户与组规划:创建 developers、ops、auditors、vendors 四个组,对应不同角色。
  2. 目录权限设计:
    • /srv/app:属主 root,属组 developers,权限 2750(SGID),开发人员可读写执行。
    • /srv/app/config:属主 root,属组 ops,权限 750,仅运维可修改。
    • /srv/logs:属主 root,属组 auditors,权限 750,审计人员可读。
    • /srv/test:属主 root,属组 vendors,权限 1770(Sticky),外包人员可写但不可删除他人文件。
  3. sudo 策略:运维组可执行 systemctl 和日志查看命令;开发组仅可执行 git 部署命令;审计组无 sudo 权限。
  4. 密码策略:所有用户 90 天改密,复杂度四级,连续失败 5 次锁定 30 分钟。
  5. ACL 补充:允许特定审计员读取交易日志目录,但不授予整个 logs 目录权限。

实施步骤:

# 创建组和用户
groupadd developers && groupadd ops && groupadd auditors && groupadd vendors
useradd -G developers -s /bin/bash dev1
useradd -G ops -s /bin/bash op1
useradd -G auditors -s /bin/bash audit1
useradd -G vendors -s /bin/bash vendor1

# 设置目录权限
mkdir -p /srv/{app,logs,test}
chown root:developers /srv/app && chmod 2750 /srv/app
chown root:ops /srv/app/config && chmod 750 /srv/app/config
chown root:auditors /srv/logs && chmod 750 /srv/logs
chown root:vendors /srv/test && chmod 1770 /srv/test

# 配置 sudo
echo "%ops ALL=(ALL) /usr/bin/systemctl, /usr/bin/tail" >> /etc/sudoers.d/ops
echo "%developers ALL=(ALL) /usr/bin/git" >> /etc/sudoers.d/dev

# 设置 ACL
setfacl -m u:audit1:r-x /srv/logs/trading

# 密码策略
chage -M 90 -m 7 -W 14 dev1

复盘与风险:该方案