Linux 中的特殊权限文件属性管理,包括传统的特殊权限位、ACL (Access Control Lists) 以及更底层的文件属性(chattrlsattr)。这些功能提供了比基本 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
    3
    ls -l /usr/bin/passwd
    # -rwsr-xr-x 1 root root 80096 Nov 2 2023 /usr/bin/passwd
    # 注意 's' 替代了所有者 'x'
  • 设置/取消:

    1
    2
    3
    chmod 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

  • 作用:

    1. 对文件: 当一个可执行文件设置了 SGID 位后,任何用户执行该文件时,其进程的有效组 ID 会暂时变为该文件的所属组 ID。

    2. 对目录: 这是更常见的用法。当一个目录设置了 SGID 位后,在该目录下创建的所有新的文件和子目录都会自动继承父目录的组 ID,而不是创建者用户的默认组 ID。

  • 典型应用:

    • 共享目录: 在团队协作中,创建一个共享目录,并设置 SGID。这样,所有成员在该目录中创建的文件都会自动属于团队的共享组,便于权限管理。
  • 查看:

    1
    2
    3
    ls -l /usr/bin/wall
    # -rwxr-sr-x 1 root tty 24032 Feb 14 2023 /usr/bin/wall
    # 注意 's' 替代了组 'x'
    1
    2
    3
    ls -ld /tmp/my_shared_dir
    # drwxrwsr-x 2 user1 shared_group 4096 Jul 24 09:00 /tmp/my_shared_dir
    # 注意 's' 替代了组 'x'
  • 设置/取消:

    1
    2
    3
    chmod 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
    3
    ls -ld /tmp
    # drwxrwxrwt 21 root root 4096 Jul 24 09:05 /tmp
    # 注意 't' 替代了其他 'x'
  • 设置/取消:

    1
    2
    3
    chmod 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
    10
    getfacl <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
      2
      setfacl -m u:user2:rwx <file> # 给 user2 对文件读写执行权限
      setfacl -m u:user3:rw <dir> # 给 user3 对目录读写权限
    • 设置特定组权限:

      1
      setfacl -m g:group2:r-x <file> # 给 group2 对文件读执行权限
    • 移除特定用户/组权限:

      1
      2
      setfacl -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
    4
    lsattr 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
    5
    sudo 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 注意事项

  • 仅限于特定文件系统: chattrlsattr 主要适用于 ext2/3/4 文件系统。对于 XFS、Btrfs 等文件系统,它们可能不支持所有这些属性,或者有自己的实现方式。

  • 超级用户权限: 更改 ai 属性通常需要 root 权限。

  • 谨慎使用 i 属性: 对关键系统文件设置 i 属性可以有效防止篡改,但如果忘记取消,即使是 root 也无法修改或删除,这可能会在系统维护时造成麻烦。

  • 不是替代方案: 文件属性与传统权限、ACL 协同工作,而不是替代它们。它们提供了不同层次的访问控制。


4. getattr 系统调用

getattr (get attributes) 并不是一个用户可以直接执行的命令行工具,而是一个 Linux 内核系统调用的通用概念,它用于获取文件或目录的属性信息

当您在命令行中运行像 ls -lstatgetfacllsattr 等命令时,它们底层都会通过不同的系统调用(包括 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 的 MaskACL (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 的值会从这些默认权限中减去(或者说是进行位操作的“与非”运算),从而得到最终的新文件/目录权限。

    • 例如,如果 umask022

      • 文件:666 - 022 = 644 (rw-r–r–)

      • 目录:777 - 022 = 755 (rwxr-xr-x)

  • umask 是一个进程属性,它会从父进程继承给子进程。你可以在 shell 中通过 umask 命令查看或设置它。

简而言之:umask 是在文件或目录创建时,用于确定其初始权限的一个“默认权限剥离器”。

区别总结

特性ACL 的 Maskumask
作用对象已存在文件的 ACL 权限新创建文件和目录的默认权限
功能限制 ACL 条目的最大有效权限定义新文件/目录的初始权限
表现形式getfacl 输出中显示,且影响 ls -l 的组权限显示通常是一个三位或四位的八进制数,用于剥离权限
优先级作用于 ACL 权限内部在文件创建时,影响文件原始权限的设定