1.7 用户与权限管理

预计阅读时间:21 分钟

📖 目录

学习目标

学完本章后,你将能够:

  • 创建、修改和删除用户与用户组
  • 理解 rwx 权限模型的三类身份(Owner / Group / Other)及其八进制表示
  • 熟练使用 chmodchown 管理文件权限与归属
  • 理解并正确使用 SUID、SGID、Sticky Bit 三种特殊权限
  • 通过 sudo、ACL 和 capabilities 实现细粒度的权限控制

前置知识

核心知识

  • 用户与用户组——Linux 是多用户系统,每个用户有唯一 UID,每个组有唯一 GID
  • rwx 权限——读(r=4)、写(w=2)、执行(x=1)构成 Unix 权限模型的基石
  • chmod / chown——修改文件权限和所有权的核心工具
  • SUID / SGID / Sticky Bit——三种特殊权限位,控制进程执行身份和目录删除行为
  • sudo——允许普通用户以 root 或其他用户身份执行命令
  • ACL——访问控制列表,突破传统 Owner/Group/Other 三类限制
  • umask——控制新建文件和目录的默认权限
  • Linux capabilities——将 root 权限拆分为细粒度的能力单元

知识关联

  • 前置知识1.4:基本文件操作命令ls -l 已经展示了权限字段,本章将完整解释其含义;1.5:文件系统结构 的 FHS 帮助理解为什么 /etc/shadow 必须限制访问
  • 后续影响2.4:进程管理 的 Shell 脚本中会频繁使用 sudo 和权限检查;5.1:Linux 安全加固 安全加固建立在本章的权限基础之上
  • 配套技术5.6:SELinux 与 AppArmor 的 SELinux/AppArmor 是强制访问控制(MAC),本章的 rwx 是自主访问控制(DAC),两者互补
  • 在整个体系中的位置:权限管理是 Linux 安全模型的第一道防线——理解它才能安全地操作系统和部署服务

原理讲解

1. 用户与用户组管理

Linux 是一个多用户操作系统。每个用户拥有唯一的 UID(User ID),每个用户组拥有唯一的 GID(Group ID)。系统通过 /etc/passwd(用户信息)、/etc/shadow(密码哈希)、/etc/group(组信息)三个文件管理这些身份。

配置文件作用权限要求
/etc/passwd存储用户名、UID、GID、主目录、默认 Shell所有用户可读
/etc/shadow存储加密密码和密码策略(过期时间等)仅 root 可读
/etc/group存储组名、GID、组成员列表所有用户可读
# 查看当前用户信息
whoami                           # 当前用户名
id                               # 当前用户的 UID、GID、所属组
# 输出: uid=1000(alice) gid=1000(alice) groups=1000(alice),27(sudo)

# 查看某个用户的信息
id bob                           # 指定用户的 UID/GID/组
# 输出: uid=1001(bob) gid=1001(bob) groups=1001(bob)

# 查看 /etc/passwd 的格式
cat /etc/passwd | head -5
# 输出: root:x:0:0:root:/root:/bin/bash
# 输出: daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
# 输出: bin:x:2:2:bin:/bin:/usr/sbin/nologin
# 输出: sys:x:3:3:sys:/dev:/usr/sbin/nologin
# 输出: alice:x:1000:1000:Alice Chen:/home/alice:/bin/bash
# 字段含义: 用户名:密码占位:UID:GID:描述:主目录:Shell

useradd——创建用户

# 基本创建(自动分配 UID、创建主目录)
sudo useradd alice                # 创建用户 alice
# 注意:裸 useradd 不创建家目录、默认 shell 为 /bin/sh,
# 生产环境建议显式指定:sudo useradd -m -s /bin/bash alice

# 指定参数创建
sudo useradd -m -s /bin/zsh -g developers -G docker bob
# -m: 创建主目录 /home/bob
# -s: 指定登录 Shell 为 zsh
# -g: 主组设为 developers
# -G: 附加组加入 docker
# -c: 添加描述信息
# -e: 指定账户过期日期 (YYYY-MM-DD)

# 创建系统用户(无主目录,UID < 1000)
sudo useradd -r -s /usr/sbin/nologin svc_nginx
# 服务账户常用于运行 Web 服务器等后台进程

# 为新用户设置密码
sudo passwd alice
# 交互式输入密码,会显示: "All authentication tokens updated successfully"

# 查看创建结果
id alice
# 输出: uid=1002(alice) gid=1002(alice) groups=1002(alice)

usermod——修改用户

# 修改用户 Shell
sudo usermod -s /bin/zsh alice     # 将 alice 的 Shell 改为 zsh

# 将用户加入附加组(-a 表示追加,不加 -a 会覆盖所有附加组!)
sudo usermod -aG docker alice      # 将 alice 加入 docker 组
sudo usermod -aG sudo,wheel alice  # 同时加入 sudo 和 wheel 组

# 锁定/解锁账户
sudo usermod -L alice              # 锁定账户(在密码前加 !)
sudo usermod -U alice              # 解锁账户

# 修改主目录并迁移文件
sudo usermod -d /home/newdir -m alice  # -m 自动移动旧目录内容

# 设置账户过期日期
sudo usermod -e 2026-12-31 alice  # 账户在 2026 年底过期

userdel——删除用户

# 仅删除用户(保留主目录)
sudo userdel alice

# 删除用户及其主目录、邮件
sudo userdel -r alice
# -r 会删除 /home/alice 和 /var/mail/alice

# 查看删除结果
grep alice /etc/passwd             # 无输出表示已删除
ls /home/alice                     # 2> /dev/null; 如果无 -r 则目录仍在

groupadd / groupmod / groupdel

# 创建组
sudo groupadd developers           # 创建新组
sudo groupadd -g 2000 devops       # 指定 GID 创建组

# 修改组名
sudo groupmod -n newname oldname   # 将 oldname 改为 newname

# 将用户加入组(直接编辑 /etc/group 或用 usermod)
sudo usermod -aG developers alice  # 推荐方式

# 删除组
sudo groupdel developers           # 组内无成员时才能删除

# 查看组信息
getent group developers
# 输出: developers:x:1003:alice,bob
💡 主组 vs 附加组 每个用户有且仅有一个主组(/etc/passwd 中的 GID),同时可以属于多个附加组。ls -l 显示的组属主是主组;文件访问时,系统会检查用户是否在文件的组权限对应的组中(附加组也生效)。

2. rwx 权限模型

Linux 文件权限由三组 rwx 构成,分别对应 Owner(属主)、Group(属组)和 Other(其他人)。

权限位文件含义目录含义八进制值
r(读)可以读取文件内容可以列出目录内容(ls4
w(写)可以修改文件内容可以在目录中创建/删除文件2
x(执行)可以将文件作为程序运行可以进入目录(cd1
# 查看权限
ls -l /etc/passwd
# 输出: -rw-r--r-- 1 root root 2847 Jul 30 10:00 /etc/passwd
#        ─┬───┬───┬───┬──┬──┬──┬──┬──┬──┬──┬──┬──
#         │   O   G   O     U  G     size  name
#         类型  Other Group Other      Owner Group
#        - = 普通文件, d = 目录, l = 符号链接

# 解读权限字符串
# - rw- r-- r--
#   │  │   │   └── Other:  r-- (4)  只读
#   │  │   └────── Group:  r-- (4)  只读
#   │  └────────── Owner:  rw- (6)  读写
#   └───────────── 类型:   - (普通文件)

# 八进制计算
# Owner=rw- = 4+2+0 = 6
# Group=r-- = 4+0+0 = 4
# Other=r-- = 4+0+0 = 4
# 完整权限 = 644

# 目录权限示例
ls -ld /tmp
# 输出: drwxrwxrwt 10 root root 4096 Jul 30 10:00 /tmp
# d=目录, rwx=Owner(7), rwx=Group(7), rwt=Other(7+t)
# t = Sticky Bit(后面讲解)
📝 目录权限的特殊性 对目录而言,w 权限不意味着"修改目录内容",而是"在目录中创建和删除文件"。一个目录可能包含你拥有的文件,但如果你没有目录的 w 权限,你就无法删除它们(即使你拥有这些文件)。x 权限对目录意味着"可以进入"——没有 x,你连 cd 进去都不行。

3. chmod 与 chown

chmod——修改文件权限

chmod 有两种语法:符号模式(Symbolic Mode)和数字模式(Numeric Mode)。

# ==================== 符号模式 ====================
# 格式: chmod [who][operator][permission] file
# who: u(Owner), g(Group), o(Other), a(All)
# operator: +(添加), -(移除), =(精确设置)

chmod u+x script.sh              # 给 Owner 添加执行权限
chmod g+w file.txt               # 给 Group 添加写权限
chmod o-rwx sensitive.conf       # 移除 Other 的所有权限
chmod a+r public.txt             # 给所有人添加读权限
chmod u=rwx,g=rx,o= file.sh     # 精确设置: Owner=rwx, Group=rx, Other=无

# 递归修改目录
chmod -R 755 /var/www/html       # 递归设置目录及所有子项
chmod -R u+w ~/project           # 递归给 Owner 添加写权限

# ==================== 数字模式 ====================
# 格式: chmod NNN file (N = 0-7 的八进制数)

chmod 644 document.txt           # Owner=rw-, Group=r--, Other=r--
chmod 755 script.sh              # Owner=rwx, Group=rx, Other=rx
chmod 700 ~/.ssh                 # Owner=rwx, Group=无, Other=无
chmod 600 ~/.ssh/id_rsa          # 私钥: 仅 Owner 可读写
chmod 666 shared.txt             # 所有人都可读写(不推荐)
chmod 000 locked.dat             # 所有人都无权限(文件被"锁住")

# 设置特殊权限(四位八进制)
chmod 4755 program               # 设置 SUID (4xxx)
chmod 2755 shared_dir            # 设置 SGID (2xxx)
chmod 1777 /tmp                  # 设置 Sticky Bit (1xxx)

chown——修改文件归属

# 修改属主
sudo chown alice file.txt         # 将 file.txt 的 Owner 改为 alice

# 同时修改属主和属组
sudo chown alice:developers file.txt

# 递归修改目录
sudo chown -R alice:alice ~/project

# 只修改属组(也可用 chgrp)
sudo chgrp developers file.txt
sudo chgrp -R developers ~/project

# 批量修改(结合 find)
sudo find /var/www -type f -exec chown www-data:www-data {} \;
⚠️ 警告:递归 chown 的风险 sudo chown -R root:root / 会把整个系统文件的属主改成 root——这看起来"安全",但实际上会破坏大量系统文件的正确归属(如 /home 下的用户目录)。永远不要对根目录或系统目录执行递归 chown。

4. SUID / SGID / Sticky Bit

三种特殊权限位位于 rwx 权限组的执行位上,有重要的安全含义。

特殊权限八进制值作用于效果
SUID4可执行文件执行时以文件 Owner(通常是 root)身份运行
SGID2可执行文件 / 目录文件:以文件 Group 身份运行;目录:新建文件继承目录的 Group
Sticky Bit1目录目录中的文件只能被 Owner 或 root 删除
# 查看 SUID 程序
find / -perm -4000 -type f 2>/dev/null
# 输出示例:
# /usr/bin/passwd        ← 修改密码需要 root 权限
# /usr/bin/sudo          ← sudo 需要 root 权限启动
# /usr/bin/su            ← 切换用户需要 root 权限
# /usr/bin/newgrp        ← 切换组需要 root 权限

# passwd 命令为什么需要 SUID?
ls -l /usr/bin/passwd
# 输出: -rwsr-xr-x 1 root root 68208 Jul 14 10:00 /usr/bin/passwd
#                     ^^^ 注意这里的 s 而不是 x
# 普通用户执行 passwd 时,进程以 root 身份运行
# 这样才能修改 /etc/shadow(只有 root 可写)

# 设置 SUID
chmod u+s /usr/local/bin/myutil   # 符号模式
chmod 4755 /usr/local/bin/myutil  # 数字模式

# 设置 SGID(对目录)
chmod 2775 /shared/project        # 新建文件自动继承 project 组

# 查找 SGID 文件
find / -perm -2000 -type f 2>/dev/null

# Sticky Bit(/tmp 目录的标准配置)
ls -ld /tmp
# 输出: drwxrwxrwt 10 root root 4096 Jul 30 10:00 /tmp
#                                 ^^^^ t = Sticky Bit
# 效果: 任何用户都可以在 /tmp 创建文件
#        但只有文件的 Owner 才能删除自己的文件
#        无法删除别人创建的文件
⚠️ SUID 的安全风险 SUID 程序以 root 身份运行,如果程序存在漏洞(如缓冲区溢出),攻击者可以获取 root 权限。生产环境中应定期用 find / -perm -4000 审计 SUID 文件,移除不必要的 SUID 设置。5.1:Linux 安全加固 安全加固章节将详细讨论这一话题。

5. sudo 与 /etc/sudoers 配置

sudo(SuperUser DO)允许授权用户以 root 或其他用户身份执行特定命令,是替代直接 root 登录的最佳实践。

# 基本用法
sudo ls /root                    # 以 root 身份执行 ls
sudo -u alice cat /home/alice/file  # 以 alice 身份执行命令
sudo -i                          # 切换到 root 用户(验证当前用户密码)
sudo su -                        # 同上,另一种写法

# 查看 sudo 权限
sudo -l                          # 列出当前用户的 sudo 权限
# 输出示例:
# User alice may run the following commands on this host:
#     (ALL : ALL) ALL

/etc/sudoers 文件定义了谁可以执行什么命令。永远不要直接编辑此文件,应使用 visudo 命令——它会在保存时检查语法错误,防止因配置错误导致所有用户失去 sudo 权限。

# 使用 visudo 编辑(推荐)
sudo visudo                      # 编辑 /etc/sudoers
sudo visudo -f /etc/sudoers.d/custom  # 编辑额外配置文件

# /etc/sudoers 格式
# 用户 主机=(可切换用户) 命令
root    ALL=(ALL:ALL)       ALL          # root 可执行任何命令
alice   ALL=(ALL:ALL)       ALL          # alice 可执行任何命令(等同于 root)
bob     ALL=(ALL)           /usr/bin/systemctl restart nginx, /usr/bin/tail -f /var/log/*  # bob 只能重启 nginx 和看日志

# 组授权(%开头)
%sudo  ALL=(ALL:ALL)       ALL          # sudo 组的所有成员可执行任何命令
%dev   ALL=(ALL)           NOPASSWD: ALL  # dev 组免密码执行所有命令

# 常见配置片段(通常放在 /etc/sudoers.d/ 下)
echo "alice ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/alice
# alice 可以执行任何 sudo 命令且不需要输入密码
💡 sudoers.d 目录 许多发行版支持在 /etc/sudoers.d/ 目录下放置独立的配置文件。这样每个用户或服务一个文件,便于管理和版本控制。文件名不含 . 后缀,权限必须是 0440

为什么官方推荐用 sudo 而不是 su?

su(switch user)和 sudo 都能获取 root 权限,但 sudo 有三个关键优势:

  • 最小权限原则:sudo 可以精确控制"谁可以执行哪些命令",而 su 一旦获得 root 密码就拥有完全控制权。sudoers 配置可以限制用户只能重启 nginx 或查看日志,不能做其他操作
  • 审计日志:sudo 默认在 /var/log/auth.log(Debian/Ubuntu)或 /var/log/secure(RHEL/CentOS)中记录"谁在何时以 root 身份执行了什么命令"。su 不记录这些信息。在安全合规要求较高的环境中,审计日志是必须的
  • 无需共享 root 密码:sudo 允许管理员为每个用户设置独立的认证(用户自己的密码),而 su 需要共享 root 密码。密码共享增加了泄露风险,且无法追踪具体是谁执行了操作

权限检查的内核流程——当你执行 ls -l file.txt 时发生了什么?

当一个进程请求访问文件时,内核按以下顺序检查权限:

  1. 检查进程的有效 UID(EUID):如果 EUID=0(root),直接放行,跳过后续检查
  2. 检查进程的补充组列表:如果进程属于文件的属组(Supplementary Groups),则使用组权限位
  3. 三级匹配:内核依次检查:
    • 如果进程 EUID == 文件 Owner UID → 使用 User 权限位
    • 否则如果进程 EUID 或任一补充组 GID == 文件 Group GID → 使用 Group 权限位
    • 否则 → 使用 Other 权限位
  4. 检查请求的操作是否被允许:根据权限位判断请求的操作(读/写/执行)是否被授权
  5. 检查 ACL(如果文件有 ACL):如果传统权限位拒绝了访问,但文件设置了 ACL,内核会进一步检查 ACL 规则

整个检查过程在内核态完成,一次文件访问可能触发数十次权限检查,但得益于位运算的高效性,性能开销几乎可以忽略。

6. ACL 访问控制列表

传统 Unix 权限只有 Owner/Group/Other 三类,无法实现"A 用户可读写,B 用户只读,C 用户无权限"这样的精细控制。ACL(Access Control List)突破了这一限制。

# 查看文件的 ACL
getfacl /shared/report.txt
# 输出:
# # file: shared/report.txt
# # owner: alice
# # group: developers
# user::rwx
# user:bob:rw-              ← bob 有读写权限
# user:carol:r--            ← carol 只读
# group::r-x                ← developers 组可读可执行
# mask::rwx                 ← 有效权限掩码
# other::---                ← 其他人无权限

# 设置 ACL
setfacl -m u:bob:rw /shared/report.txt     # 给 bob 添加读写权限
setfacl -m u:carol:r /shared/report.txt    # 给 carol 添加只读权限
setfacl -m g:developers:rx /shared/        # 给 developers 组设置权限

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

# 设置默认 ACL(对目录中新创建的文件自动生效)
setfacl -d -m u:alice:rwx /shared/project  # 默认 ACL
setfacl -d -m g:developers:rx /shared/project

# 删除 ACL
setfacl -x u:bob /shared/report.txt        # 删除 bob 的 ACL
setfacl -b /shared/report.txt              # 删除所有 ACL
ACL 操作命令说明
查看getfacl file显示文件的完整 ACL 规则
添加/修改setfacl -m u:user:perm file为指定用户设置权限
删除setfacl -x u:user file移除指定用户的 ACL 条目
清空setfacl -b file移除所有 ACL 规则
默认 ACLsetfacl -d -m g:grp:perm dir新文件自动继承此 ACL

7. umask 默认权限

umask 定义了创建文件和目录时从默认权限中移除的权限。它不"设置"权限,而是"遮罩"权限。

# 查看当前 umask
umask
# 输出: 0022

# 目录的默认权限 = 777 - umask
# 文件的默认权限 = 666 - umask(文件默认没有执行权限)
# 0022 → 目录 = 755, 文件 = 644

# 修改 umask
umask 027                        # 目录=750, 文件=640
umask 077                        # 目录=700, 文件=600(最严格)
umask 000                        # 目录=777, 文件=666(最宽松,不推荐)

# 设置永久 umask
echo "umask 022" >> ~/.bashrc    # 写入 Shell 配置

# 演示 umask 效果
cd /tmp && umask 022
touch testfile && mkdir testdir
ls -l testfile testdir
# 输出: -rw-r--r-- 1 alice alice 0 ... testfile    (666-022=644)
# 输出: drwxr-xr-x 2 alice alice 4096 ... testdir  (777-022=755)

umask 077
touch privatefile && mkdir privatedir
ls -l privatefile privatedir
# 输出: -rw------- 1 alice alice 0 ... privatefile  (666-077=600)
# 输出: drwx------ 2 alice alice 4096 ... privatedir (777-077=700)
umask 值文件默认权限目录默认权限适用场景
022644 (rw-r--r--)755 (rwxr-xr-x)大多数系统默认值
027640 (rw-r-----)750 (rwxr-x---)安全要求较高的环境
077600 (rw-------)700 (rwx------)私有目录、敏感数据
002664 (rw-rw-r--)775 (rwxrwxr-x)协作环境(同组可写)

8. Linux Capabilities

传统的 Unix 权限模型中,进程要么是 root(拥有所有权限),要么不是。Linux Capabilities 将 root 的特权拆分为独立的能力单元(如 CAP_NET_BIND_SERVICE 允许绑定 1024 以下端口),实现更精细的控制。

# 查看进程的 capabilities
capsh --print
# 输出示例:
# Current: = cap_chown,cap_dac_override,cap_fowner,cap_kill,cap_setgid,...
# Bounding set = cap_chown,cap_dac_override,cap_fowner,...

# 查看文件的 capabilities
getcap /usr/bin/ping
# 输出: /usr/bin/ping cap_net_raw=ep

# 给文件设置 capability
sudo setcap cap_net_bind_service=+ep /usr/local/bin/myapp
# myapp 现在可以绑定 1024 以下端口,无需 root 权限

# 移除 capability
sudo setcap -r /usr/local/bin/myapp

# 常用 capabilities
# CAP_NET_BIND_SERVICE  绑定 < 1024 端口
# CAP_NET_RAW           使用原始套接字(ping)
# CAP_SYS_ADMIN         大量系统管理操作
# CAP_SYS_PTRACE        调试其他进程
# CAP_DAC_OVERRIDE      绕过文件权限检查
# CAP_FOWNER            绕过 Owner 检查

# 用 capabilities 替代 SUID 的示例
# 旧方式: chmod u+s /usr/local/bin/portbind (整个进程以 root 运行)
# 新方式: setcap cap_net_bind_service=+ep /usr/local/bin/portbind
#         (进程只获得绑定低端口的能力,不是完整 root)
📝 capabilities 的安全优势 传统的 SUID 让程序获得完整 root 权限——即使程序只需要绑定一个低端口。Capabilities 遵循最小权限原则:只授予必要的能力。这大大降低了漏洞利用的风险。现代 Linux 系统(如 systemd 服务)广泛使用 capabilities 替代 SUID。

示例代码

# 综合实战:搭建一个安全的 Web 项目目录

# 1. 创建用户和组
sudo groupadd webteam
sudo useradd -m -G webteam -s /bin/bash alice
sudo useradd -m -G webteam -s /bin/bash bob
sudo useradd -r -s /usr/sbin/nologin svc_nginx

# 2. 创建项目目录
sudo mkdir -p /var/www/myapp
sudo chown root:webteam /var/www/myapp
sudo chmod 2775 /var/www/myapp     # SGID: 新文件继承 webteam 组

# 3. 设置默认 ACL(新文件自动继承权限)
sudo setfacl -d -m g:webteam:rwX /var/www/myapp
sudo setfacl -d -m o::--- /var/www/myapp

# 4. 验证设置
getfacl /var/www/myapp
# 输出:
# # file: var/www/myapp
# # owner: root
# # group: webteam
# # flags: -s-
# user::rwx
# group::rwx
# other::---
# default:user::rwx
# default:group::rwx
# default:group:webteam:rwX
# default:mask::rwx
# default:other::---

# 5. 测试:alice 和 bob 创建的文件
su - alice -c "touch /var/www/myapp/alice.txt"
su - bob -c "touch /var/www/myapp/bob.txt"
ls -la /var/www/myapp/
# 输出: -rw-rw----+ 1 alice webteam ... alice.txt
# 输出: -rw-rw----+ 1 bob   webteam ... bob.txt
# 两个文件都继承了 webteam 组!

# 6. sudo 配置(让 webteam 成员可以重启 nginx)
echo "%webteam ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx" \
  | sudo tee /etc/sudoers.d/webteam
sudo chmod 0440 /etc/sudoers.d/webteam
# 综合实战:查看系统所有特殊权限文件
echo "=== SUID 文件 ==="
find / -perm -4000 -type f 2>/dev/null

echo "=== SGID 文件 ==="
find / -perm -2000 -type f 2>/dev/null

echo "=== Sticky Bit 目录 ==="
find / -perm -1000 -type d 2>/dev/null

echo "=== 具有 ACL 的文件 ==="
getfacl -R /home 2>/dev/null | grep -B1 "user:"

echo "=== 所有 capabilities 文件 ==="
find / -exec getcap {} + 2>/dev/null | head -20
# 综合实战:umask 实验
# 创建测试环境
mkdir -p /tmp/umask_test && cd /tmp/umask_test

# 不同 umask 下创建文件和目录
for mask in 000 002 022 027 077; do
    umask $mask
    mkdir -p dir_$mask
    touch file_$mask
    echo "umask=$mask → dir=$(stat -c %A dir_$mask) file=$(stat -c %A file_$mask)"
done
# 输出:
# umask=000 → dir=drwxrwxrwx file=-rw-rw-rw-
# umask=002 → dir=drwxrwxr-x file=-rw-rw-r--
# umask=022 → dir=drwxr-xr-x file=-rw-r--r--
# umask=027 → dir=drwxr-x--- file=-rw-r-----
# umask=077 → dir=drwx------ file=-rw-------

# 清理
cd / && rm -rf /tmp/umask_test

常见错误

错误/问题原因解决方案
Permission denied当前用户对文件或目录没有所需权限ls -l 检查权限,用 chmod 调整,或用 sudo 提权
sudo: alice is not in the sudoers file用户未被授权 sudo 权限以 root 执行 usermod -aG sudo alice,或编辑 /etc/sudoers 添加规则
chmod: changing permissions of 'file': Operation not permitted不是文件的 Owner 且没有 root 权限sudo chmodsudo chown 先修改归属
cannot remove 'file': Operation not permitted(在 Sticky Bit 目录下)文件不属于当前用户,目录有 Sticky Bit只有文件 Owner 或 root 可删除。确认文件归属或联系管理员
chown: changing ownership: Operation not permitted只有 root 可以 chown(普通用户连自己的文件都不能改属主)sudo chown,或理解为什么 Linux 不允许普通用户转移文件所有权
# 排查示例:Permission denied 的完整诊断流程

# 1. 查看文件权限
ls -l /var/log/syslog
# 输出: -rw-r----- 1 root adm 12345 ... /var/log/syslog

# 2. 查看当前用户和组
whoami && groups
# 输出: alice, alice docker webteam

# 3. 检查是否有 ACL
getfacl /var/log/syslog
# 查看是否有针对 alice 或 alice 所在组的 ACL 条目

# 4. 尝试用 sudo
sudo cat /var/log/syslog          # root 可以读取

# 5. 如果需要持续访问,让管理员加入 adm 组
sudo usermod -aG adm alice        # 需要 root 执行

最佳实践

#建议说明
1永远不要直接登录 root使用普通用户 + sudo 执行管理任务。sudo 有日志审计(/var/log/auth.log),可以追溯谁在何时执行了什么操作。
2遵循最小权限原则只授予用户完成工作所需的最低权限。用 capabilities 替代 SUID,用 ACL 替代"所有人可读写"的偷懒做法。
3使用 visudo 编辑 sudoers直接编辑 /etc/sudoers 可能因语法错误导致所有 sudo 权限丢失。visudo 会在保存时检查语法,且支持 sudoers.d 目录模块化配置。
4限制 SUID/SGID 文件定期审计系统中的 SUID/SGID 文件(find / -perm -4000),移除不必要的特殊权限。
5为服务创建专用账户不要用 root 运行 Nginx、MySQL 等服务。创建专用系统用户(useradd -r -s /usr/sbin/nologin),限制其权限范围。

练习题

  1. (概念)解释 chmod 751 file 中每个数字代表什么权限?对文件和目录分别意味着什么?
  2. (实操)创建一个用户 testuser,将其加入 sudo 组,验证该用户可以执行 sudo ls /root
  3. (实操)创建一个共享目录 /tmp/shared,要求:所有用户都可以在里面创建文件,但只能删除自己的文件。设置完成后用两个不同用户测试。
  4. (探究 🔍)find / -perm -4000 2>/dev/null 列出系统中所有 SUID 文件,找出哪些 SUID 程序你认为是不安全的,并说明原因。
点击查看答案
  1. 751 = Owner: rwx(7), Group: r-x(5), Other: --x(1)。对文件:Owner 可读写执行,Group 可读和执行,Other 只能执行(不能读取内容)。对目录:Owner 可列出/进入/创建,Group 可列出和进入,Other 只能进入(不能列出目录内容)。
  2. sudo useradd -m -G sudo testusersudo passwd testusersu - testusersudo ls /root。如果 sudoers 配置了 %sudo ALL=(ALL:ALL) ALL,则 sudo 组成员可执行任何 sudo 命令。
  3. sudo mkdir /tmp/shared && sudo chmod 1777 /tmp/shared。Sticky Bit(1)确保只有文件的 Owner 才能删除自己的文件。验证:su - user1 -c "touch /tmp/shared/a"su - user2 -c "rm /tmp/shared/a" → 会报 "Operation not permitted"。
  4. SUID 程序以 root 身份运行,如果存在漏洞可被利用获取 root 权限。不安全的例子:自定义的 SUID shell 脚本(容易被注入)、/usr/bin/pkexec(CVE-2021-4034 漏洞)。应审计每个 SUID 文件是否真正需要 root 权限。

学习检查点

学完本章后,请检验自己是否掌握以下内容:

检查项自测问题验证方法
概念理解能用自己的话解释用户、组、权限、sudo 之间的关系尝试向他人讲解
命令操作能不查文档使用 useradd、usermod、chmod、chown 管理用户和权限在终端实际执行
原理掌握能说出 SUID、SGID、Sticky Bit 的作用和风险画出权限位图
故障排查能独立排查 sudo 权限配置错误导致的命令失败模拟故障并修复
最佳实践能说明为什么应该用普通用户+sudo 而不是直接用 root对比不同操作方式

本章总结

Linux 的权限模型是系统安全的基石。本章从用户与用户组管理(useradd/usermod/userdel)出发,讲解了 rwx 权限模型的三类身份和八进制表示,介绍了 chmod/chown 的符号模式与数字模式,深入分析了 SUID/SGID/Sticky Bit 三种特殊权限的原理与风险。在此基础上,你学会了用 sudo 授权普通用户、用 ACL 实现细粒度访问控制、用 umask 控制默认权限、用 capabilities 替代粗粒度的 root 授权。

速查表

概念一句话定义
useradd创建新用户(-m 创建主目录,-G 添加附加组)
usermod修改用户属性(-aG 追加组,-s 改 Shell)
rwx读(4)/写(2)/执行(1) 三类权限,分 Owner/Group/Other
chmod修改文件权限(符号模式 u+x 或数字模式 755
chown修改文件属主和属组(chown user:group file
SUID (4)执行文件时以 Owner 身份运行进程
SGID (2)目录:新文件继承目录的 Group;文件:以 Group 身份运行
Sticky Bit (1)目录中的文件只能被 Owner 删除
sudo以其他用户身份执行命令(需配置 /etc/sudoers)
ACL访问控制列表,为特定用户/组设置独立权限
umask遮罩默认权限(022→文件644,目录755)
capabilities将 root 权限拆分为独立能力单元(如 CAP_NET_BIND_SERVICE)

下一步:进入 1.8:软件包管理「软件包管理」,学习在 Linux 中安装、更新和卸载软件。

延伸阅读

常见问题

chmod 644 和 755 代表什么?
三个数字分别代表文件所有者(user)、所属组(group)和其他人(others)的权限。644 = rw-r--r--(所有者可读写,其他人只读)适用于普通文件。755 = rwxr-xr-x 适用于目录和可执行文件。r=4, w=2, x=1,每个数字是三个权值之和。
sudo 执行命令显示"不在 sudoers 文件中"怎么办?
需要用 root 用户将当前用户加入 sudo 组。先用 su - 切换到 root,然后运行 usermod -aG sudo 用户名(Debian/Ubuntu)或 usermod -aG wheel 用户名(RHEL/CentOS),退出重新登录生效。或者用 visudo 命令直接编辑 /etc/sudoers 文件。
SUID 权限有什么安全风险?
SUID(Set User ID)使普通用户运行程序时临时获得文件所有者的权限。典型的如 /usr/bin/passwd 需要 root 权限修改密码文件。滥用 SUID 是提权攻击的常见入口,应定期用 find / -perm -4000 查找所有 SUID 文件,审查不必要的条目。
↑ 回到顶部