Linux中的特殊权限和文件属性
Linux 中的特殊权限和文件属性管理,包括传统的特殊权限位、ACL
(Access Control Lists) 以及更底层的文件属性(chattr
和 lsattr
)。这些功能提供了比基本 ugo/rwx
权限更细粒度的文件访问控制。
1. 特殊权限位 (SUID, SGID, Sticky Bit)
除了我们熟知的用户 (User)、组 (Group) 和其他 (Others) 的读 (Read)、写 (Write)、执行 (Execute) 权限 (rwx
),Linux 文件系统还提供三种特殊的权限位,它们有独特的作用:
1.1 SUID (Set User ID)
符号表示:
s
位于所有者执行位 (u+x
) 的位置。数字表示: 八进制权限的最高位,例如
4755
。作用: 当一个可执行文件设置了 SUID 位后,任何用户执行该文件时,其进程的有效用户 ID 会暂时变为该文件的所有者 ID。
典型应用:
passwd
命令:该命令通常属于root
用户,并设置了 SUID 位。普通用户执行passwd
时,进程会暂时拥有root
权限,从而能够修改/etc/shadow
(只有root
有权限写入),但仅限于修改当前用户的密码。
风险: SUID 位赋予了普通用户执行特定程序时暂时提升权限的能力。如果带有 SUID 位的程序本身存在安全漏洞,攻击者可能会利用这个漏洞来获取更高权限(提权)。因此,应谨慎设置 SUID 位,并仅对绝对信任且无漏洞的程序使用。
查看:
1
2
3ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 80096 Nov 2 2023 /usr/bin/passwd
# 注意 's' 替代了所有者 'x'设置/取消:
1
2
3chmod u+s <file> # 设置 SUID
chmod 4755 <file> # 设置 SUID 并同时设置 rwxr-xr-x
chmod u-s <file> # 取消 SUID
1.2 SGID (Set Group ID)
符号表示:
s
位于组执行位 (g+x
) 的位置。数字表示: 八进制权限的最高位,例如
2755
。作用:
对文件: 当一个可执行文件设置了 SGID 位后,任何用户执行该文件时,其进程的有效组 ID 会暂时变为该文件的所属组 ID。
对目录: 这是更常见的用法。当一个目录设置了 SGID 位后,在该目录下创建的所有新的文件和子目录都会自动继承父目录的组 ID,而不是创建者用户的默认组 ID。
典型应用:
- 共享目录: 在团队协作中,创建一个共享目录,并设置 SGID。这样,所有成员在该目录中创建的文件都会自动属于团队的共享组,便于权限管理。
查看:
1
2
3ls -l /usr/bin/wall
# -rwxr-sr-x 1 root tty 24032 Feb 14 2023 /usr/bin/wall
# 注意 's' 替代了组 'x'1
2
3ls -ld /tmp/my_shared_dir
# drwxrwsr-x 2 user1 shared_group 4096 Jul 24 09:00 /tmp/my_shared_dir
# 注意 's' 替代了组 'x'设置/取消:
1
2
3chmod g+s <file_or_dir> # 设置 SGID
chmod 2775 <dir> # 设置 SGID 并同时设置 rwxrwxr-x
chmod g-s <file_or_dir> # 取消 SGID
1.3 Sticky Bit (粘滞位)
符号表示:
t
位于其他用户执行位 (o+x
) 的位置。数字表示: 八进制权限的最高位,例如
1777
。作用: 仅对目录有效。 当一个目录设置了 Sticky Bit 后,只有该目录的所有者、该目录下文件的所有者或 root 用户才能删除或重命名该目录下的文件,即使其他用户对该目录有写权限。
典型应用:
/tmp
目录:这是一个全球可写的临时目录,但为了防止用户删除其他用户的临时文件,它设置了 Sticky Bit。
查看:
1
2
3ls -ld /tmp
# drwxrwxrwt 21 root root 4096 Jul 24 09:05 /tmp
# 注意 't' 替代了其他 'x'设置/取消:
1
2
3chmod o+t <dir> # 设置 Sticky Bit
chmod 1777 <dir> # 设置 Sticky Bit 并同时设置 rwxrwxrwx
chmod o-t <dir> # 取消 Sticky Bit
2. ACL (Access Control Lists)
ACL (Access Control Lists) 是一种比传统的 ugo/rwx
权限更灵活、更细粒度的文件权限管理机制。它允许您为特定用户或特定组设置权限,而不受文件所有者、文件所属组和其他用户的限制。
2.1 核心概念
细粒度控制: 可以为任意数量的用户或组设置权限。
额外权限: 在
ugo/rwx
之外提供额外的权限规则。Mask (遮罩): ACL 中的一个重要概念,它定义了赋予组和其他用户的最大有效权限。任何通过 ACL 赋予用户或组的权限,都不能超过 Mask 定义的权限。
2.2 常用命令
getfacl
: 用于查看文件或目录的 ACL 权限。1
2
3
4
5
6
7
8
9
10getfacl <file_or_dir>
# 示例输出:
# # file: my_document.txt
# # owner: user1
# # group: group1
# user::rw-
# user:user2:r-- # 为 user2 添加了读权限
# group::r--
# mask::r-- # Mask 决定了 user2 和 group 的最大有效权限
# other::---setfacl
: 用于设置文件或目录的 ACL 权限。设置特定用户权限:
1
2setfacl -m u:user2:rwx <file> # 给 user2 对文件读写执行权限
setfacl -m u:user3:rw <dir> # 给 user3 对目录读写权限设置特定组权限:
1
setfacl -m g:group2:r-x <file> # 给 group2 对文件读执行权限
移除特定用户/组权限:
1
2setfacl -x u:user2 <file> # 移除 user2 的 ACL 权限
setfacl -x g:group2 <file> # 移除 group2 的 ACL 权限设置默认 ACL (针对目录): 目录的默认 ACL 会继承给在该目录中新创建的文件和子目录。
1
setfacl -m d:u:user4:rwx <dir> # 设置目录的默认 ACL,user4 将在新建文件时获得 rwx
清除所有 ACL 权限:
1
setfacl -b <file_or_dir> # 移除所有扩展 ACL 条目,只保留 ugo/rwx
重新计算 Mask: 当设置 ACL 权限时,Mask 会自动更新。如果手动修改了 Mask,可以使用
setfacl -nm <file_or_dir>
来重新计算。
2.3 ACL 注意事项
文件系统支持: ACL 需要底层文件系统(如 ext4, XFS)的支持,并且在挂载时需要启用 ACL 选项(通常是默认启用)。
权限显示: 当文件或目录拥有 ACL 权限时,
ls -l
命令会在传统权限字符串的末尾显示一个+
符号,例如-rw-r--r--+
。优先级: ACL 权限的优先级高于传统的
ugo/rwx
权限。Mask 的影响: 理解 Mask 很重要。如果 Mask 的权限低于您为某个用户/组设置的 ACL 权限,那么该用户/组实际生效的权限将是两者权限的交集。
- 例如:
user:user2:rwx
,但mask::r--
,则user2
实际只有读权限。
- 例如:
3. 文件属性 (chattr
, lsattr
)
除了传统的权限和 ACL,Linux 文件系统(主要是 ext2/3/4)还提供了一组更底层的文件属性,这些属性可以改变文件的行为,甚至限制 root
用户的操作。这些属性是文件系统级别的,与权限模型独立。
3.1 lsattr
:查看文件属性
命令:
lsattr [options] <file_or_dir>
作用: 列出文件或目录的扩展文件属性。
常用选项:
-a
:显示所有文件,包括隐藏文件。-R
:递归显示子目录。
示例:
1
2
3
4lsattr my_important_file.txt
# -----a---------- my_important_file.txt # 'a' 表示只能追加
lsattr /etc/passwd
# --------------e-- /etc/passwd # 'e' 表示使用 extents
3.2 chattr
:修改文件属性
命令:
chattr [operator][attributes] <file_or_dir>
作用: 修改文件或目录的扩展文件属性。
操作符:
+
:添加属性。-
:移除属性。=
:设置属性(覆盖现有属性)。
常用属性 (字母表示):
a
(append only): 只允许追加。文件只能以追加模式打开进行写入,不能覆盖或删除现有内容。即使是root
用户也不能删除或修改文件,只能向文件末尾追加数据。sudo chattr +a /var/log/my_app.log
:日志文件只允许追加。
i
(immutable): 不可更改。文件不能被删除、重命名、链接或写入。即使是root
用户也无法修改此文件,除非先移除i
属性。这是最强大的文件保护属性之一。sudo chattr +i /etc/passwd
:使passwd
文件不可更改,防止意外或恶意修改。
d
(no dump):该文件在dump
程序备份时不进行备份。c
(compressed):自动对文件进行压缩/解压缩(文件系统级别)。不常用。A
(no atime update):访问文件时,不更新文件的访问时间 (atime
)。提高性能,减少磁盘写入。S
(synchronous update):文件内容同步写入磁盘,而不是延迟写入。通常由sync
命令或O_SYNC
标志实现。u
(undeletable):该文件被删除时,其内容会被保留,以便后续恢复。不常用,且需要文件系统支持。e
(extents):文件使用 extents 进行存储。现代 ext4 文件系统默认启用,表示文件以连续块的形式存储,提高性能。不能手动设置或取消。
设置/取消示例:
1
2
3
4
5sudo chattr +i /etc/resolv.conf # 设置文件不可修改
sudo chattr -i /etc/resolv.conf # 取消文件不可修改属性
sudo chattr +a /var/log/messages # 设置文件只允许追加
sudo chattr -a /var/log/messages # 取消文件只允许追加属性
3.3 chattr
注意事项
仅限于特定文件系统:
chattr
和lsattr
主要适用于 ext2/3/4 文件系统。对于 XFS、Btrfs 等文件系统,它们可能不支持所有这些属性,或者有自己的实现方式。超级用户权限: 更改
a
和i
属性通常需要root
权限。谨慎使用
i
属性: 对关键系统文件设置i
属性可以有效防止篡改,但如果忘记取消,即使是root
也无法修改或删除,这可能会在系统维护时造成麻烦。不是替代方案: 文件属性与传统权限、ACL 协同工作,而不是替代它们。它们提供了不同层次的访问控制。
4. getattr
系统调用
getattr
(get attributes) 并不是一个用户可以直接执行的命令行工具,而是一个 Linux 内核系统调用的通用概念,它用于获取文件或目录的属性信息。
当您在命令行中运行像 ls -l
、stat
、getfacl
、lsattr
等命令时,它们底层都会通过不同的系统调用(包括 stat()
, lstat()
, fstat()
, getxattr()
, ioctl()
等)来间接地调用 getattr
相关的函数,以获取文件的各种元数据,如:
文件类型 (常规文件、目录、符号链接等)
文件大小
文件权限 (ugo/rwx)
所有者 UID 和 GID
访问时间 (atime)、修改时间 (mtime)、更改时间 (ctime)
inode 号
硬链接数量
文件属性 (如
chattr
设置的属性)SELinux 上下文 (通过
getxattr
扩展属性获取)
它们都是通过与内核进行 getattr
类的系统调用来读取文件元数据的。
掌握这些特殊的权限和文件属性管理工具,将使您能够更精确、更安全地控制 Linux 系统上的文件访问,从而提高系统的整体安全性。在实际生产环境中,它们是进行系统加固和故障排除的强大武器。
你提的问题非常好,它触及了 Linux 权限管理中两个容易混淆但本质不同的概念:ACL 的 Mask 和 **umask
**。
它们虽然都叫 “mask” (遮罩),但作用的层次和机制完全不同。
ACL 的 Mask
ACL 的 Mask 是 ACL (Access Control Lists) 特有的一个概念。它的作用是:
限制 ACL 中“命名用户 (named user)”和“命名组 (named group)”以及“文件所属组 (owning group)”的有效权限。
它定义了这些 ACL 条目能够拥有的最大权限。如果某个命名用户或命名组被授予的 ACL 权限超过了 Mask 的权限,那么最终生效的权限将是两者权限的**交集 (bitwise AND)**。
ACL Mask 的权限通常显示在
getfacl
命令的输出中,以mask::
开头。它的主要目的是为了兼容传统的
ugo/rwx
权限,确保旧的工具在处理带有 ACL 的文件时,仍能看到一个“合理”的权限集(通常是文件所属组的权限)。当一个文件拥有 ACL 时,ls -l
命令显示的组权限实际上就是这个 ACL Mask 的权限。
简而言之:ACL Mask 是 ACL 内部的一个权限上限,它“遮盖”或“限制”了通过 ACL 赋予特定用户或组的权限。
umask
umask
(user file-creation mode mask) 则是用于设置新创建文件和目录的默认权限的。它的作用是:
剥离 (mask out) 默认权限中不希望授予的那些权限位。
它通常以八进制数表示,例如
022
。这个数字代表的是要“关闭”的权限位。对于文件,默认的创建权限通常是
666
(rw-rw-rw-);对于目录,默认是777
(rwxrwxrwx)。umask
的值会从这些默认权限中减去(或者说是进行位操作的“与非”运算),从而得到最终的新文件/目录权限。例如,如果
umask
是022
:文件:
666 - 022 = 644
(rw-r–r–)目录:
777 - 022 = 755
(rwxr-xr-x)
umask
是一个进程属性,它会从父进程继承给子进程。你可以在 shell 中通过umask
命令查看或设置它。
简而言之:umask
是在文件或目录创建时,用于确定其初始权限的一个“默认权限剥离器”。
区别总结
特性 | ACL 的 Mask | umask |
---|---|---|
作用对象 | 已存在文件的 ACL 权限 | 新创建文件和目录的默认权限 |
功能 | 限制 ACL 条目的最大有效权限 | 定义新文件/目录的初始权限 |
表现形式 | 在 getfacl 输出中显示,且影响 ls -l 的组权限显示 | 通常是一个三位或四位的八进制数,用于剥离权限 |
优先级 | 作用于 ACL 权限内部 | 在文件创建时,影响文件原始权限的设定 |