前言

“最小权限原则"落地的第一站就是账号体系:日常用普通用户 + 按需 sudo,而不是人人 root。这篇把用户、组、sudo 的管理一次讲全。

一、用户与组的本质

一切都在这三个文件里:

/etc/passwd     # 用户账本
/etc/shadow     # 密码哈希(只有 root 可读)
/etc/group      # 组账本
# passwd 每行七段
zy:x:1000:1000::/home/zy:/bin/bash
│ │  │   │    │      │        └ 登录 shell
│ │  │   │    │      └ 家目录
│ │  │   │    └ 备注(GECOS)
│ │  │   └ 主组 GID
│ │  └ UID(<1000 多为系统账号)
│ └ 密码占位(真密码在 shadow)
└ 用户名

# 快速查某个用户
id zy
# uid=1000(zy) gid=1000(zy) groups=1000(zy),10(wheel),994(docker)

二、用户管理命令

# 创建(RHEL 系默认建同名主组)
useradd -m -s /bin/bash -c "运维-zy" alice     # -m 建家目录
useradd -r -s /sbin/nologin deploy             # -r 系统账号(跑服务用, 不能登录)

# 设置/改密码
passwd alice                                   # 交互式
echo "alice:Str0ngPass" | chpasswd             # 脚本式

# 修改属性
usermod -aG docker,wheel alice                 # 追加附加组(-aG 别写成 -G, 会覆盖!)
usermod -L alice                               # 锁定账号(禁登录)
usermod -U alice                               # 解锁
usermod -s /sbin/nologin alice                 # 换 shell(禁交互登录)

# 删除
userdel -r alice                               # -r 连家目录和邮箱一起删

# 查看登录情况
last | head
who / w                                        # 当前在线

给服务建运行用户的惯例:

useradd -r -s /sbin/nologin -d /opt/myapp myapp
# 之后 systemd unit 里 User=myapp, chown -R myapp:myapp /opt/myapp

三、组管理

groupadd developers
groupmod -n devs developers                    # 改名
groupdel devs

gpasswd -a alice developers                    # 加成员
gpasswd -d alice developers                    # 移除成员

# 临时切换主组(新建文件属组生效)
newgrp developers

# 组密码极少用; 现代用法基本是: 附加组 + sudo

组的典型玩法——目录共享(回顾权限篇):

groupadd devops
usermod -aG devops alice; usermod -aG devops bob
mkdir -p /data/share && chgrp devops /data/share
chmod 2770 /data/share         # SGID: 新文件自动继承 devops 组

四、sudo:受控的提权

su - 是"整个 root 身份交出去”,sudo 是"按规则放行特定命令并留审计日志"。

# 编辑 sudoers 永远用 visudo(保存前做语法检查, 防止把自己锁死!)
visudo
# 或子文件(推荐, 便于管理)
visudo -f /etc/sudoers.d/deploy

规则语法:

谁   在哪台主机=(以谁的身份)  可以跑什么命令

实用规则示例:

# wheel 组成员可全权 sudo(RHEL 默认存在)
%wheel  ALL=(ALL)       ALL

# 免密 sudo(自动化脚本常用, 但要评估风险)
zy      ALL=(ALL)       NOPASSWD: ALL

# 只允许跑特定命令
deploy  ALL=(root)      /usr/bin/systemctl restart myapp, \
                        /usr/bin/systemctl status myapp

# 只允许以 app 用户身份执行(不给 root!)
tester  ALL=(myapp)     NOPASSWD: /opt/myapp/bin/test.sh

# 组规则 + 排除法(慎用, 可被绕过, 尽量白名单)
%devs   ALL=(ALL)       ALL, !/usr/bin/su, !/usr/sbin/visudo

sudo 的高级用法:

sudo -l                          # 列出我当前能跑哪些命令
sudo -u myapp ./run.sh           # 以其他用户执行(不只 root)
sudo -i                          # 完整 root 登录环境(≈su -)
sudo !!                          # 以 sudo 重跑上一条命令(万能急救)

# 审计: 谁在什么时候跑了什么
journalctl -t sudo | tail
grep sudo /var/log/secure | tail

五、密码策略

chage -l alice                   # 查看策略
# 密码 90 天过期, 提前 7 天警告, 5 天内不能改第二次
chage -M 90 -W 7 -m 5 alice
chage -d 0 alice                 # 强制下次登录改密码
chage -E 2025-12-31 contractor   # 账号到期自动禁用(外包神器)

# 全局策略(login.defs)
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS 90/' /etc/login.defs

# 密码复杂度(pam pwquality)
# /etc/security/pwquality.conf
minlen   = 12
minclass = 3                     # 至少3类字符

六、账号健康巡检

# 1. 能登录的系统账号(危险! 应为空, 至少无 shell)
awk -F: '$3<1000 && $7!~/(nologin|false)/ {print $1, $7}' /etc/passwd

# 2. 空密码账号(必须为空!)
awk -F: '($2==""){print $1}' /etc/shadow

# 3. UID=0 的账号(应只有 root)
awk -F: '$3==0 {print $1}' /etc/passwd

# 4. 90天未登录的账号(僵尸候选)
lastlog -b 90 | grep -v "Never logged in" | awk 'NR>1 && $2!="" {print $1}'

# 5. sudoers 里的 NOPASSWD 盘点
grep -rn NOPASSWD /etc/sudoers /etc/sudoers.d/ 2>/dev/null

把这几条丢进巡检脚本(见我那篇 Bash 巡检),每周自动跑。

七、实战场景

给新同事开账号(标准动作):

USERNAME=alice
useradd -m -s /bin/bash $USERNAME
echo "$USERNAME:初始密码" | chpasswd
chage -d 0 $USERNAME                       # 首登强制改密
usermod -aG developers $USERNAME           # 业务组
# 需要提权时: visudo 加白名单, 而不是塞进 wheel

回收离职账号:

usermod -L alice                           # 1. 先锁定(立即失效)
usermod -s /sbin/nologin alice             # 2. 禁 shell(双保险)
crontab -r -u alice 2>/dev/null            # 3. 清定时任务
# 4. 归档家目录后删除(保留审计期数据)
tar -czf /backup/userdata/alice-$(date +%F).tar.gz /home/alice
userdel -r alice
grep -rn alice /etc/sudoers.d/             # 5. 清 sudoers 残留

小结

任务 命令
建用户 useradd -m -s /bin/bash
调组 usermod -aG(记得 -a)
授权 visudo -f /etc/sudoers.d/xx 白名单
审计 journalctl -t sudo
巡检 UID=0 / 空密码 / 可登录系统账号
服务账号 -r -s /sbin/nologin

本文是「Linux 基础」系列第 7 篇。