用户权限管理

用户权限

权限决定了用户(所有者、组成员、其他人)对文件或目录能执行哪些操作。使用 ls -l 命令查看:

-rwxr-xr-- 1 alice devs 4096 Jul 31 15:22 script.sh
drwxr-x--- 2 bob sales 4096 Jul 30 10:05 reports/
  • 第 1 位:- 表示普通文件,d 表示目录,l 表示符号链接,还有 c (字符设备)、b (块设备)、s (套接字)、p (命名管道) 等。
  • 后面 9 位:3 组(每组 3 位),分别代表:
    • 前3位所有者 (Owner/u) 的权限。
    • 中3位所属组 (Group/g) 的权限。
    • 后3位其他用户 (Others/o) 的权限。
  • 每组权限由三个字符表示:
    • r (Read):读取权限。
      • 文件:可以查看文件内容 (cat, less, vim 只读打开)。
      • 目录:可以列出目录内的文件名 (ls)。
    • w (Write):写入权限。
      • 文件:可以修改文件内容 (vim 编辑保存, echo >> 追加),删除文件本身需要父目录的写权限
      • 目录:可以在目录内创建、删除、重命名文件或子目录。这是目录最重要的写权限含义!
    • x (eXecute):执行/搜索权限。
      • 文件:可以作为程序或脚本运行该文件 (./script.sh)。对于脚本,通常还需要该文件的读权限(以读取脚本内容)。
      • 目录:可以进入 (cd into) 该目录,并且访问目录内的文件和子目录的元数据(即使你对目标文件本身没有权限)。没有 x 权限,即使有 r 权限也无法 ls 目录内容,也无法 cd 进去或访问其下的任何文件/子目录。
    • -:表示没有该权限。

权限管理

chmod (Change Mode)权限修改命令

# 使用语法
chmod 对象(u/g/o)赋值符(+/-/=)权限(r/w/x) 文件/目录

chmod符号模式

# 符号模式示例
chmod u+x file.txt # 给所有者添加执行权限。
chmod g-w file.txt #从组中移除写权限。
chmod o=r file.txt # 设置其他用户权限为只读(移除写和执行)。
chmod a+r file.txt # 给所有人添加读权限。
chmod g+s directory/ #给目录设置 SGID 位。
chmod o+t directory/ #给目录设置粘滞位。
chmod u+r,g-w,o+x file

chmod数字模式

# 数字模式示例
chmod 644 file.txt # rw-r--r--
chmod 1777 /tmp/ # rwxrwxrwt (粘滞位)
chmod 4755 /usr/bin/special # rwsr-xr-x (SUID)

chmod其他选项

为所有用户添加执行权限
chmod +x file		# 为ugo所有角色添加执行权限,不推荐使用
-R选项递归修改
# 创建dir文件夹,在dir下创建test1 test2 test3文件
# 查看权限 ls -l
# 接着使用
chmod -R 700 dir/
# 再次查看权限情况

image-20250801105706088

chown修改属主/组命令

  • 通常需要 root 权限。
  • 常用选项 -R: 递归修改目录及其下所有内容。

语法

chown newowner:newgroup filename	# 修改所有者和所属组
chown newowner filename # (仅改所有者)
chown :newgroup filename # (仅改组)

chown newowner.newgroup filename # 修改所有者和所属组
chown newowner filename # (仅改所有者)
chown .newgroup filename # (仅改组)
chown enterprise:enterprise ./dir/test1
chown enterprise.enterprise ./dir/test2

image-20250801110133489

chgrp修改文件/目录的所属组

功能被 chown :newgroup 包含,使用较少。可用 -R 递归。

语法

chgrp newgroup filename
chgrp root ./dir/test1

image-20250801110601940

ACL访问控制列表

传统 ugo/rwx 权限模型的主要局限

  1. 粒度太粗:
    • 只能定义三类角色: 所有者 (Owner/u)、所属组 (Group/g)、其他用户 (Others/o)。
    • 无法针对特定用户或特定组授权: 如果想让用户 Alice 和组 developers 有不同权限,但用户 Bob(不属于 developers 组)也需要访问,传统模型无法直接实现。必须创建新组,把所有需要访问的用户(Alice, Bob)加入该组,然后授权给这个组。这增加了管理负担,并且可能让组变得过大或不必要。
  2. 继承性弱(尤其对于目录):
    • 目录下新创建的文件/目录默认继承父目录的所属组(如果设置了 SGID 位)和权限模式(受 umask 影响)。
    • 但无法定义更精细的默认权限规则: 例如,无法指定“所有在此目录下新建的文件,都应额外赋予 qa 组读权限”或“所有在此目录下新建的子目录,都应允许 audit 用户访问”。这种需求在共享协作环境中非常常见。
  3. 权限类型有限:
    • 只有 r (读), w (写), x (执行/搜索) 三种基本权限,以及 SUID, SGID, Sticky 三种特殊权限。
    • 缺乏更细粒度的权限控制,例如“拒绝删除”(不同于写权限,写权限在目录上控制创建/删除)或更复杂的权限组合。

ACL 的优势

  1. 精细粒度控制: 突破“所有者-组-其他人”三元组的限制,可以精确指定任意用户或组的权限。
  2. 灵活的默认权限继承: 通过默认 ACL,可以定义目录下新建文件/目录自动继承的复杂权限规则,极大简化共享环境的管理。
  3. 更好的协作性: 轻松支持多用户、多组对同一资源的不同访问需求。
  4. 兼容性: ACL 是 POSIX 标准的一部分,兼容大多数现代 Unix-like 系统(Linux, BSD, macOS 等)。文件系统需要支持 ACL(如 ext4, XFS, Btrfs, ZFS 等通常默认支持或可启用)。
  5. 叠加在基本权限之上: ACL 是对传统 ugo/rwx 权限的补充和扩展,而不是完全替代。基本权限仍然有效,并且是 ACL 计算最终有效权限的基础(尤其是 mask 的作用)。

ACL语法

setfacl -m <用户/组>:<名称>:<权限> <文件/目录>
# -m 修改权限 -x 删除ACL -b 清空所有ACL
# <用户/组>:u(用户)、g(组)、o(其他人)。
# <名称>:用户名或组名(留空表示默认属主/组)。
# <权限>:r/w/x(可组合,如rw)。

ACL方案示例

# 设置目录基本权限和 ACL
setfacl -m u:bob:rwx /projectX # 单独给 bob 读写执行
setfacl -m u:auditor:r-x /projectX # 单独给 auditor 读和执行(进入)
setfacl -m d:u:auditor:r-x /projectX # 设置默认 ACL,让新建项自动继承 auditor 的 r-x
setfacl -m u:bob:- /projectX # 单独不赋予 bob 权限

查看ACL

命令:getfacl

getfacl /home/text.txt

ACL删除与恢复

setfacl -x g:hr /home/test.txt		# 删除一条ACL
setfacl -b /home/test.txt # 删除此文件所有ACL

chmod 644 /home/test.txt # 重新设置权限

ACL的递归设置

setfacl -R -m u:alice:rwx /data/		# 设置alice有对/data/目录下所有文件的rwx权限

注意

ACL优先级 > UGO优先级,当ACL与UGO冲突时以ACL为准

# 备份  
getfacl -R /path > acl_backup.txt
# 恢复
setfacl --restore=acl_backup.txt

特殊权限

特殊权限位

  1. SUID (Set User ID) s (在所有者执行位):
    • 当设置了 SUID 的程序被任何用户执行时,该程序在运行期间临时获得文件所有者的权限(通常是 root)。
    • 经典示例: /usr/bin/passwd。普通用户运行 passwd 修改自己的密码时,需要写入 /etc/shadow(只有 root 有写权限)。SUID 让 passwd 程序临时拥有 root 权限来完成写入。
    • 表示:如果所有者有 x,显示为 s (小写);如果所有者没 x,显示为 S (大写,无效/罕见)。
    • 风险: 滥用 SUID 是重大安全风险,需严格控制。
  2. SGID (Set Group ID) s (在所属组执行位):
    • 对于文件:效果类似 SUID,程序运行时临时获得文件所属组的权限。
    • 对于目录:在该目录下新创建的文件或子目录,其所属组会自动继承该目录的所属组,而不是创建者的主组。这对于需要多人协作共享文件的目录非常有用。
    • 表示:如果组有 x,显示为 s (小写);如果组没 x,显示为 S (大写,无效/罕见)。
  3. 粘滞位 (Sticky Bit) t (在其他用户执行位):
    • 几乎只用于目录(对文件作用在现代 Linux 中已废弃)。
    • 作用:在设置了粘滞位的目录下,用户只能删除或重命名自己拥有的文件/目录,即使该目录的写权限 (w) 是开放的(如 o+rwx)。
    • 经典示例: 系统的 /tmp 目录。所有用户都有 rwx 权限,可以创建临时文件。粘滞位 /tmp 防止用户 A 删除用户 B 的文件。
    • 表示:如果其他用户有 x,显示为 t (小写);如果其他用户没 x,显示为 T (大写,无效/罕见)。

文件属性chattr

chattr 是 Linux 中一个强大且底层的文件系统命令,用于更改文件或目录的扩展属性(Extended Attributes)。这些属性在标准的 rwx 权限和 ACL 之上,提供了更底层、更“强硬”的控制机制,直接影响文件系统如何对待该文件/目录,甚至 root 用户也无法轻易绕过

常用属性

以下是 chattr 最常用和重要的属性(字母区分大小写):

  1. i (Immutable - 不可变):
    • 效果: 文件不能被修改、删除、重命名、创建指向它的硬链接。即使是 root 用户也不行!也不能设置 setuid, setgid 位或修改扩展属性本身。
    • 用途: 保护极其重要的配置文件、二进制程序(如 /bin/ls)免受篡改或删除。是系统加固的关键一步。
    • 设置: sudo chattr +i /path/to/file
    • 取消: sudo chattr -i /path/to/file
  2. a (Append Only - 仅追加):
    • 效果: 文件只能以追加(Append) 模式打开进行写入。不能修改文件已有的内容,不能覆盖(truncate)文件,也不能删除或重命名文件。同样限制 root 用户。
    • 用途: 保护日志文件(如 /var/log/auth.log, /var/log/syslog)的完整性。攻击者或恶意进程无法擦除已有的日志记录,只能添加新记录。
    • 设置: sudo chattr +a /path/to/logfile.log
    • 取消: sudo chattr -a /path/to/logfile.log
  3. A (No Atime Updates - 不更新访问时间):
    • 效果: 当文件被读取(Read) 时,系统不会更新该文件的最后访问时间戳 (atime)。
    • 用途: 减少磁盘 I/O 操作,提升性能(尤其对频繁读取的文件,如数据库文件)。传统 HDD 受益更明显,SSD 上也能减少写入磨损。
    • 设置: sudo chattr +A /path/to/file
    • 取消: sudo chattr -A /path/to/file
  4. c (Compressed - 压缩):
    • 效果: 指示支持压缩的文件系统(如 btrfs)在写入磁盘时自动压缩该文件。读取时自动解压。
    • 用途: 节省磁盘空间。
    • 注意: 不是所有文件系统都支持。ext2/3/4 不支持此属性。
    • 设置: sudo chattr +c /path/to/file
    • 取消: sudo chattr -c /path/to/file
  5. C (No Copy-on-Write - 禁用写时复制):
    • 效果: 在支持写时复制(Copy-on-Write, CoW)的文件系统(如 btrfs, ZFS, XFS (某些配置下))上,禁用该文件/目录的 CoW 特性。
    • 用途: 对于需要最高性能且很少修改的数据库文件(如 MySQL 的 ibdata1),禁用 CoW 可以避免写操作带来的额外开销(复制块、更新元数据)。
    • 注意: 权衡性能和数据安全性/快照功能。禁用 CoW 后该文件将无法享受 CoW 带来的好处(快照一致性、防止数据损坏等)。
    • 设置: sudo chattr +C /path/to/file_or_dir
    • 取消: sudo chattr -C /path/to/file_or_dir
  6. S (Synchronous Updates - 同步更新):
    • 效果: 对该文件的修改会立即同步写入磁盘,而不是先写入内存缓存(Page Cache)。相当于每次 write() 系统调用后都隐式调用 fsync()fdatasync()
    • 用途: 确保在系统崩溃或掉电时,数据的修改不会丢失。用于对数据一致性要求极高的文件(如数据库事务日志)。
    • 代价: 严重降低 I/O 性能(因为磁盘写入比内存写入慢几个数量级)。
    • 设置: sudo chattr +S /path/to/file
    • 取消: sudo chattr -S /path/to/file
  7. d (No Dump - 不备份):
    • 效果: 在使用传统 dump 备份工具时,标记该文件/目录不需要备份
    • 用途: 排除不需要备份的临时文件或大型不重要的数据,节省备份时间和空间。
    • 注意: 现代备份工具(如 rsync, bacula, borg)通常不依赖此标志。
    • 设置: sudo chattr +d /path/to/file_or_dir
    • 取消: sudo chattr -d /path/to/file_or_dir
  8. u (Undelete - 允许恢复):
    • 效果: 当文件被删除时,其内容会被保存下来(如果文件系统支持)。理论上允许未来恢复被删除的内容。
    • 用途: 防止误删除。
    • 现状: 这个属性在现代主流 Linux 文件系统(如 ext4, XFS, btrfs)上基本被废弃且无效。 不应依赖此功能进行数据恢复。应使用版本控制、快照或专业备份方案。
    • 设置: sudo chattr +u /path/to/file (不推荐依赖)
    • 取消: sudo chattr -u /path/to/file

使用语法

chattr [ -RVf ] [ -v version ] [ mode ] files...
  • + 添加一个或多个属性。例如 +i
  • - 移除一个或多个属性。例如 -i
  • = 显式设置属性(移除未指定的属性)。例如 =iA 表示只设置 iA,移除其他所有属性。
  • -R 递归地修改目录及其下的所有内容。
  • -V 详细输出,显示操作过程。
  • -f 抑制大部分错误消息(不太常用)。
  • files... 要操作的一个或多个文件或目录路径。
查看属性
lsattr [ -RVadv ] [ files... ]
  • -R 递归列出目录内容。
  • -V 详细输出。
  • -a 列出所有文件,包括以 . 开头的隐藏文件。
  • -d 以目录方式列出目录本身(而不是目录的内容)。
  • -v 显示文件版本/生成号(如果文件系统支持)。

进程掩码umask

  1. umask (User File Creation Mask): 决定新建文件或目录时的默认权限
    • 它不是一个权限,而是一个掩码,指定了哪些权限不应该被赋予。
    • 默认值通常:root 是 0022,普通用户是 0002。(第一个 0 表示是 8 进制,后面的三位数字用 8 进制表示)
    • 计算新建文件权限:0666 - umask
    • 计算新建目录权限:0777 - umask
    • 例如 umask 0022
      • 新建文件:0666 - 0022 = 0644 (rw-r--r--)
      • 新建目录:0777 - 0022 = 0755 (rwxr-xr-x)
    • 命令 umask 查看当前值,umask 0027 设置新值(只在当前 shell 有效,要永久修改需写入 shell 配置文件如 .bashrc 或系统配置文件如 /etc/profile)。

实验验证

查看权限

ls -l		# 查看文件及权限

image-20250801165055751

chmod命令

chmod u+x,g-w,o=r practice.txt

image-20250801165404272

首先创建文件file1.txt

vim file1.txt		# 创建文件并填写以下内容

echo "hello zhouwu"
read -p "please your name?" name
echo "$name good"

image-20250801165709469

执行文件

[root@wickt 桌面]# ./file1.txt

image-20250801165805583

添加执行权限再执行

chmod u+x ./file1.txt
./file1.txt

image-20250801170043669

ACL设置

setfacl -m u:user1:rw ./file1.txt		# 赋予用户user1 rw权限
setfacl -m g:minato:rwx ./file1.txt # 赋予用户组minato rwx权限
getfacl ./file1.txt # 查看file1.txt文件的ACL

image-20250801170524981

删除acl

setfacl -x g:minato /tmp/file1.txt		# 删除一条ACL
setfacl -b /tmp/file1.txt # 删除此文件所有ACL

image-20250801190833362

SUID设置

practice.txt文件为root用户创建,普通用户没有执行权限

image-20250801191226258

为cat命令添加suid权限,测试普通用户user1是否有权限访问practice.txt文件

chmod u+s /usr/bin/cat

su - user1
cat /root/桌面/practice.txt
# chmod u-s /usr/bin/cat 删除权限

image-20250801191703999

chattr

# 先查看文件默认属性
lsattr /tmp/file1.txt

image-20250801192001611

chattr +i /tmp/file1.txt
lsattr /tmp/file1.txt

image-20250801192728643

# 尝试删除文件
rm -rf /tmp/file1.txt

# 最后删除权限
chattr -i /tmp/file1.txt

image-20250801193729586

Author: wickt42
Link: http://example.com/2025/08/01/linux用户权限管理/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.