Skip to content

用户与权限 ​

Linux 是多用户系统,权限模型是安全的基石。80% 的安全事故源于权限配置不当。本篇覆盖从用户管理到 ACL 的完整知识链。

用户管理三板斧 ​

useradd — 创建用户 ​

bash
# 最简单的方式(使用默认值)
sudo useradd bob

# 生产环境推荐写法
sudo useradd -m -s /bin/bash -G sudo,devops bob
# -m: 自动创建家目录 /home/bob
# -s: 指定 shell
# -G: 加入附加组

# 创建后设置密码
sudo passwd bob

创建用户时,系统做了三件事:在 /etc/passwd 写一行记录、在 /etc/shadow 写密码哈希、创建家目录 /home/bob(如果有 -m)。

/etc/passwd 格式 ​

bash
# 每行一条用户记录,冒号分隔 7 个字段
bob:x:1001:1001:Bob Smith,,,:/home/bob:/bin/bash
#  ↑  ↑  ↑    ↑     ↑              ↑         ↑
# 用户名 密码  UID   GID  注释(全名)  家目录    登录shell

现代系统中密码位填 x,实际密码存在 /etc/shadow(只有 root 可读)。

usermod — 修改用户 ​

bash
sudo usermod -aG docker bob      # 追加用户到 docker 组(注意 -a!)
sudo usermod -s /bin/zsh bob     # 改 shell
sudo usermod -L bob              # 锁定用户(禁止登录)
sudo usermod -U bob              # 解锁

usermod -G 不加 -a 会清空其他组

usermod -G docker bob 会把 bob 从原来所有附加组中移除,只保留 docker 组。正确的追加写法是 usermod -aG。多少运维半夜加班就是因为少了这个 -a。

userdel — 删除用户 ​

bash
sudo userdel bob           # 只删用户,不删家目录
sudo userdel -r bob        # 连家目录和邮件一起删

组管理 ​

组是权限管理的核心概念——不要逐个用户赋权,而是把用户加入组,给组赋权。

bash
sudo groupadd devops                      # 创建组
sudo groupmod -n developers devops        # 重命名组
sudo groupdel devops                      # 删除组(确保无用户以此为 primary group)

# 查看用户所属组
groups bob
id bob           # 更详细,显示 uid/gid 和所有组

/etc/group 格式:

devops:x:1002:bob,alice,charlie
# 组名  密码  GID  成员列表(逗号分隔)

sudo 配置 ​

基本授权 ​

bash
sudo visudo    # 永远用 visudo 编辑 sudoers,它会做语法检查

在 /etc/sudoers 中添加:

# 用户 bob 可以做任何事
bob ALL=(ALL:ALL) ALL

# devops 组成员可以做任何事(推荐做法)
%devops ALL=(ALL:ALL) ALL

# 无需密码就能 sudo(方便但不太安全)
bob ALL=(ALL:ALL) NOPASSWD: ALL

# 只允许执行特定命令
bob ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx

/etc/sudoers.d/ 分片管理 ​

bash
# 不要把规则全堆在 sudoers 里,用分片文件更清晰
sudo visudo -f /etc/sudoers.d/devops

写入:

# 开发组权限
%devops ALL=(ALL) /usr/bin/systemctl restart app-*
%devops ALL=(ALL) /usr/bin/journalctl

visudo 的重要性

直接 vim /etc/sudoers 如果写错语法,sudo 会完全不可用——包括 root 的 sudo。唯一恢复方法是重启进单用户模式。visudo 会在保存前检查语法,错了会提示而不保存。

chmod / chown / chgrp ​

chmod 数字法(推荐) ​

bash
# r=4  w=2  x=1  →  三个数字分别对应 所有者-所属组-其他人
chmod 755 script.sh      # rwxr-xr-x(可执行脚本或目录)
chmod 644 file.txt       # rw-r--r--(普通文件)
chmod 600 id_rsa         # rw-------(私钥,其他人完全不可见)
chmod 700 ~/private      # rwx------(私有目录)
chmod 750 /project       # rwxr-x---(项目目录,同组可进)

chmod 符号法 ​

bash
chmod u+x script.sh        # 所有者加执行
chmod g-w file.txt         # 组去掉写
chmod o= file.txt          # 清空其他人所有权限
chmod a+r document.pdf     # 所有人可读
chmod u=rwx,g=rx,o= /opt/app  # 组合设置

chown / chgrp ​

bash
chown bob:devops file.txt      # 同时改所有者和组
chown -R www-data:www-data /var/www/app  # 递归修改
chgrp devops /shared           # 只改组

特殊权限:SUID / SGID / Sticky Bit ​

位数字效果
SUID4文件以所有者身份执行(典型:/usr/bin/passwd)
SGID2文件以所属组身份执行;目录:新文件继承目录的组
Sticky1目录中只有文件所有者才能删除自己的文件(典型:/tmp)
bash
# 查看特殊权限
ls -l /usr/bin/passwd
# -rwsr-xr-x ... /usr/bin/passwd   ← s 在所有者 x 位 = SUID

ls -ld /tmp
# drwxrwxrwt ... /tmp              ← t 在其他人 x 位 = Sticky

# 设置 SGID 目录(团队协作利器)
mkdir /shared/project
chmod 2770 /shared/project         # SGID + rwxrws---
chown :devops /shared/project      # 目录属于 devops 组
# 之后任何人在此目录创建的文件都会自动归属 devops 组

SUID 的安全风险

SUID 程序以文件所有者身份运行。如果 root 所有者的程序有 SUID 且有漏洞,攻击者就能提权到 root。定期审计:find / -perm -4000 -type f 2>/dev/null。

ACL(访问控制列表) ​

传统 rwx 权限只有所有者-组-其他人三层,太粗糙。ACL 可以给任意用户/组单独设权限。

bash
# 安装(通常已预装)
sudo apt install acl          # Debian/Ubuntu
sudo yum install acl          # RHEL/Rocky

# 给用户 bob 单独加读权限(不影响 owner/group/other)
setfacl -m u:bob:rx /project/data

# 给 devops 组加读写权限
setfacl -m g:devops:rwx /project/data

# 查看 ACL(有 + 号的文件/目录已设 ACL)
getfacl /project/data
# 输出会显示 user::group::other:: 以及额外的 user:bob: 条目

# 递归设置
setfacl -R -m u:alice:rwx /project/

# 设置默认 ACL(目录中新创建的文件自动继承)
setfacl -m d:g:devops:rwx /project/data

# 删除某条 ACL
setfacl -x u:bob /project/data

# 清空所有 ACL
setfacl -b /project/data

umask — 新文件默认权限 ​

bash
umask           # 查看当前值,通常是 0022
umask 027       # 设置为 027

# 理解:新文件权限 = 666 - umask(文件)/ 777 - umask(目录)
# umask=022 → 文件 644(rw-r--r--), 目录 755(rwxr-xr-x)
# umask=027 → 文件 640(rw-r-----), 目录 750(rwxr-x---),更安全

写入 /etc/profile 或 ~/.bashrc 永久生效。

实战场景 ​

场景一:搭建团队开发服务器 ​

bash
# 1. 创建开发组
sudo groupadd devteam

# 2. 创建项目目录
sudo mkdir -p /opt/projects/webapp
sudo chown root:devteam /opt/projects/webapp
sudo chmod 2770 /opt/projects/webapp     # SGID + 组 rwx

# 3. 设默认 ACL(新文件自动给 devteam 组 rw 权限)
sudo setfacl -m d:g:devteam:rwx /opt/projects/webapp

# 4. 把开发者加入组
sudo usermod -aG devteam alice
sudo usermod -aG devteam bob
# 用户需要重新登录后组生效

场景二:禁止普通用户 su 到 root ​

bash
# 创建 wheel 组(RHEL系)或 sudo 组(Debian系)
# 修改 /etc/pam.d/su,取消注释:
auth required pam_wheel.so use_uid

# 只有 wheel 组成员才能 su
sudo usermod -aG wheel trusted_user

场景三:创建只读审计用户 ​

bash
sudo useradd -m -s /bin/bash auditor
# 不给 sudo 权限,家目录设 700
sudo chmod 700 /home/auditor
# 需要看的日志目录给组读权限
sudo setfacl -m u:auditor:rx /var/log/app

常见坑与排故 ​

坑 1:不小心 chown -R 了根目录 ​

bash
# 灾难:chown -R user:user /
# 恢复:抢救关键服务权限(以下仅为应急,不一定能完全恢复)
# 关键目录必须有正确的 owner
sudo chown root:root /
sudo chown root:root /etc /var /tmp /opt
# 注意:/usr 下文件所有者复杂(root/man/libwww等),不能简单 chown -R root!
# 最好从备份恢复 /usr,或参考同版本干净系统的权限表

生产环境操作前这 3 件事

  1. 先在测试环境跑一遍
  2. pwd 确认当前目录不是 /
  3. 重要目录先备份权限列表:getfacl -R /关键目录 > acl_backup.txt

坑 2:SSH 密钥权限不对 ​

bash
# ssh 对私钥权限极其严格,必须是 600
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# 差一点都不行,ssh 会直接拒绝

坑 3:改了权限组没生效 ​

bash
# 用户加入组后需重新登录
# 或当前会话中用以下命令刷新(不影响已运行的进程)
newgrp devops          # 新开一个子 shell
# 或
exec su -l $USER       # 重新登录当前 shell

生产环境经验 ​

  • 最小权限原则:能 750 就别 755,能 640 就别 644
  • 用户即角色:不要共用账号,每个运维有自己的账号,通过 sudo 日志审计
  • sudo 日志:/var/log/auth.log(Debian)或 /var/log/secure(RHEL)记录所有 sudo 操作
  • 定期审计:find / -perm -4000 -o -perm -2000 -type f 检查 SUID/SGID 程序
  • 文件权限基准:web 目录 750,配置文件 640,私钥 600,日志 640

🎯 本章要点 ​

  • usermod -G 不加 -a 会清空原附加组(应写 -aG)
  • SSH 私钥权限必须是 600,否则拒绝连接
  • 团队开发用 SGID+ACL+组成员,别用 chmod 777
  • 定期审计 SUID 程序:find / -perm -4000 -type f
加载练习题中...