跳转到内容
搜索 RunEntLinux 文档

仅搜索 RunEntLinux 通用文档,各发行版文档使用各自的搜索入口。

    浏览当前文档目录

    文件权限与 ACL

    适用于 CentOS Stream 9 & 10 / AlmaLinux 9.x & 10.x / Rocky Linux 9.x & 10.x

    Linux 文件权限是系统安全的基石。每个文件和目录都有一套权限规则,控制谁可以读取、写入和执行它们。当基本权限无法满足需求时,ACL(访问控制列表)可以提供更精细的控制。

    • 理解 rwx 权限模型
    • 使用 chmod 修改权限(符号模式和八进制模式)
    • 使用 chown 和 chgrp 修改属主和属组
    • SUID、SGID 和 Sticky Bit 特殊权限
    • 使用 ACL 实现精细权限控制
    • 理解和配置 umask
    • 一台已安装 EL 9.x 或 10.x 的系统(本页命令在两代上通用)
    • 拥有 sudo 权限的用户账户
    • 了解用户和组管理的基本概念
    查看文件权限详情
    $ ls -l /etc/nginx/nginx.conf
    -rw-r--r--. 1 root root 2488 Mar 24 10:00 /etc/nginx/nginx.conf

    输出各部分含义:

    -rw-r--r--. 1 root root 2488 Mar 24 10:00 nginx.conf
    │├──┤├──┤├──┤ │ │ │ │ │ │
    │ │ │ │ │ │ │ │ │ └─ 文件名
    │ │ │ │ │ │ │ │ └─ 修改时间
    │ │ │ │ │ │ │ └─ 文件大小
    │ │ │ │ │ │ └─ 属组
    │ │ │ │ │ └─ 属主
    │ │ │ │ └─ 硬链接数
    │ │ │ └─ 其他用户权限 (other)
    │ │ └─ 属组权限 (group)
    │ └─ 属主权限 (owner)
    └─ 文件类型(- 普通文件,d 目录,l 符号链接)
    权限字符对文件的含义对目录的含义
    读r读取文件内容列出目录内容
    写w修改文件内容在目录中创建/删除文件
    执行x执行文件(脚本/程序)进入目录(cd)

    符号模式使用 u(属主)、g(属组)、o(其他)、a(所有)配合 +(添加)、-(移除)、=(设置)来修改权限。

    给属主添加执行权限
    $ chmod u+x script.sh
    移除其他用户的写权限
    $ chmod o-w file.txt
    给属组添加读写权限
    $ chmod g+rw shared.doc
    设置属主读写执行,属组和其他只读
    $ chmod u=rwx,g=r,o=r script.sh
    给所有用户添加执行权限
    $ chmod a+x script.sh

    每个权限位对应一个数值:

    权限值
    r4
    w2
    x1
    -0

    将属主、属组、其他用户的权限值分别相加:

    数字权限说明
    7rwx读 + 写 + 执行
    6rw-读 + 写
    5r-x读 + 执行
    4r--只读
    3-wx写 + 执行
    2-w-只写
    1--x只执行
    0---无权限
    设置权限为 755(属主 rwx,属组 r-x,其他 r-x)
    $ chmod 755 script.sh
    设置权限为 644(属主 rw-,属组 r--,其他 r--)
    $ chmod 644 config.conf
    设置权限为 700(属主 rwx,其他人无权限)
    $ chmod 700 private-dir/
    递归修改目录及其内容的权限
    $ chmod -R 755 /var/www/html/
    目录设为 755,文件设为 644(推荐做法)
    $ find /var/www/html/ -type d -exec chmod 755 {} +
    $ find /var/www/html/ -type f -exec chmod 644 {} +
    修改文件的属主
    $ sudo chown webuser /var/www/html/index.html
    同时修改属主和属组
    $ sudo chown webuser:webgroup /var/www/html/index.html
    递归修改目录的属主和属组
    $ sudo chown -R webuser:webgroup /var/www/html/
    修改文件的属组
    $ sudo chgrp developers project-file.txt
    递归修改目录的属组
    $ sudo chgrp -R developers /opt/project/

    除了基本的 rwx 权限,Linux 还有三个特殊权限位。

    当可执行文件设置了 SUID 位后,任何用户执行该文件时,都会以文件属主的身份运行(而不是执行者自身)。

    查看 SUID 的经典示例:passwd 命令
    $ ls -l /usr/bin/passwd
    -rwsr-xr-x. 1 root root 32648 ... /usr/bin/passwd

    属主权限中的 s 就是 SUID 标志。普通用户执行 passwd 时,进程以 root 身份运行,因此能够修改 /etc/shadow。

    设置 SUID(八进制前缀 4)
    $ sudo chmod u+s /path/to/program
    $ sudo chmod 4755 /path/to/program
    查找系统中所有设置了 SUID 的文件
    $ sudo find / -perm -4000 -type f 2>/dev/null

    对文件:执行时以文件属组身份运行。

    对目录:在目录中创建的新文件/子目录会自动继承该目录的属组,而不是创建者的主组。这对于团队协作目录非常有用。

    设置 SGID(八进制前缀 2)
    $ sudo chmod g+s /opt/shared-project/
    $ sudo chmod 2775 /opt/shared-project/
    验证 SGID 效果
    $ ls -ld /opt/shared-project/
    drwxrwsr-x. 2 root developers 4096 ... /opt/shared-project/

    属组权限中的 s 就是 SGID 标志。

    对目录设置 Sticky Bit 后,目录中的文件只能被文件的属主或 root 删除,即使其他用户对目录有写权限。最典型的例子是 /tmp。

    查看 /tmp 的 Sticky Bit
    $ ls -ld /tmp
    drwxrwxrwt. 15 root root 4096 ... /tmp

    其他用户权限中的 t 就是 Sticky Bit 标志。

    设置 Sticky Bit(八进制前缀 1)
    $ sudo chmod +t /opt/shared-uploads/
    $ sudo chmod 1777 /opt/shared-uploads/
    权限八进制符号对文件对目录
    SUID4u+s以属主身份执行(无特殊效果)
    SGID2g+s以属组身份执行新文件继承目录的属组
    Sticky1+t(无特殊效果)只有属主能删除文件
    1. 创建共享目录

      创建目录
      $ sudo mkdir /opt/team-share
    2. 设置属主和属组

      设置为 developers 组所有
      $ sudo chown root:developers /opt/team-share
    3. 设置权限和 SGID

      设置 SGID 确保新文件继承组
      $ sudo chmod 2775 /opt/team-share
    4. 验证

      确认权限设置正确
      $ ls -ld /opt/team-share
      drwxrwsr-x. 2 root developers 4096 ... /opt/team-share

      现在,developers 组的任何成员在该目录下创建的文件都会自动属于 developers 组。

    5. 测试

      以 developers 组成员身份创建文件
      $ touch /opt/team-share/test.txt
      $ ls -l /opt/team-share/test.txt
      -rw-rw-r--. 1 zhangsan developers 0 ... test.txt

    umask 决定了新创建文件和目录的默认权限。新文件的权限 = 基础权限 - umask 值。

    • 文件的基础权限:666(不含执行位)
    • 目录的基础权限:777
    查看当前 umask
    $ umask
    0022
    以符号形式查看
    $ umask -S
    u=rwx,g=rx,o=rx

    umask 0022 的效果:

    基础权限umask实际权限
    文件666022644 (rw-r—r—)
    目录777022755 (rwxr-xr-x)
    临时修改 umask(仅当前会话)
    $ umask 027

    umask 027 的效果:

    基础权限umask实际权限
    文件666027640 (rw-r-----)
    目录777027750 (rwxr-x---)
    永久修改用户的 umask
    $ echo "umask 027" >> ~/.bashrc

    当基本的 owner/group/other 权限模型无法满足需求时,ACL 可以为特定的用户或组设置独立的权限。

    查看文件的 ACL
    $ getfacl /opt/team-share/config.txt

    输出示例(无额外 ACL):

    opt/team-share/config.txt
    # owner: zhangsan
    # group: developers
    user::rw-
    group::rw-
    other::r--
    给特定用户添加读写权限
    $ sudo setfacl -m u:lisi:rw /opt/team-share/config.txt
    给特定组添加只读权限
    $ sudo setfacl -m g:qa:r /opt/team-share/config.txt
    查看设置后的 ACL
    $ getfacl /opt/team-share/config.txt

    输出示例:

    opt/team-share/config.txt
    # owner: zhangsan
    # group: developers
    user::rw-
    user:lisi:rw-
    group::rw-
    group:qa:r--
    mask::rw-
    other::r--
    设置用户 ACL
    $ sudo setfacl -m u:用户名:权限 文件路径
    设置组 ACL
    $ sudo setfacl -m g:组名:权限 文件路径
    删除特定用户的 ACL
    $ sudo setfacl -x u:lisi /opt/team-share/config.txt
    删除特定组的 ACL
    $ sudo setfacl -x g:qa /opt/team-share/config.txt
    删除文件的所有 ACL
    $ sudo setfacl -b /opt/team-share/config.txt
    递归设置目录的 ACL
    $ sudo setfacl -R -m u:lisi:rwx /opt/team-share/

    默认 ACL 可以让目录中新创建的文件自动继承 ACL 规则:

    设置默认 ACL
    $ sudo setfacl -d -m u:lisi:rw /opt/team-share/
    $ sudo setfacl -d -m g:qa:r /opt/team-share/
    查看默认 ACL
    $ getfacl /opt/team-share/

    输出示例:

    # file: opt/team-share/
    # owner: root
    # group: developers
    # flags: -s-
    user::rwx
    group::rwx
    other::r-x
    default:user::rwx
    default:user:lisi:rw-
    default:group::rwx
    default:group:qa:r--
    default:mask::rwx
    default:other::r-x

    现在在该目录中创建的新文件会自动包含对 lisi 和 qa 组的 ACL 规则。

    mask 定义了 ACL 中用户和组能获得的最大权限。即使你设置了某个用户的权限为 rwx,如果 mask 是 r--,该用户实际有效权限也只有 r--。

    设置 mask
    $ sudo setfacl -m m::rx /opt/team-share/config.txt

    假设有以下需求:

    • 项目目录 /opt/webapp 属于 webdev 组
    • webdev 组的成员有完整读写权限
    • qa 组只能读取不能修改
    • 用户 deployer 有完整权限用于部署
    • 新创建的文件自动继承这些规则
    1. 创建目录和组

      创建目录和组
      $ sudo mkdir -p /opt/webapp
      $ sudo groupadd webdev
      $ sudo groupadd qa
    2. 设置基本权限

      设置属主、属组和 SGID
      $ sudo chown root:webdev /opt/webapp
      $ sudo chmod 2770 /opt/webapp
    3. 设置 ACL

      qa 组只读权限
      $ sudo setfacl -m g:qa:rx /opt/webapp
      deployer 用户完整权限
      $ sudo setfacl -m u:deployer:rwx /opt/webapp
    4. 设置默认 ACL(对新建文件生效)

      设置默认 ACL
      $ sudo setfacl -d -m g:webdev:rwx /opt/webapp
      $ sudo setfacl -d -m g:qa:rx /opt/webapp
      $ sudo setfacl -d -m u:deployer:rwx /opt/webapp
    5. 验证

      查看完整的 ACL 设置
      $ getfacl /opt/webapp

    ACL 是对基本权限的扩展。当两者同时存在时:

    • 文件属主的权限仍由 user:: 控制
    • 其他用户的权限受 ACL 规则和 mask 共同影响
    • chmod 修改组权限时会影响 mask 值

    文件属主已经是 root,为什么普通用户还能读取

    Section titled “文件属主已经是 root,为什么普通用户还能读取”

    因为 other(其他用户)的权限允许读取。例如权限 644 意味着所有用户都可以读取。

    如何检查为什么某个用户无法访问文件

    Section titled “如何检查为什么某个用户无法访问文件”
    检查文件权限和 ACL
    $ ls -la /path/to/file
    $ getfacl /path/to/file
    检查目录链上每一级的权限
    $ namei -l /path/to/file

    namei -l 会显示路径中每一级目录的权限,帮助你找到哪一级阻止了访问。

    备份 ACL 到文件
    $ getfacl -R /opt/webapp > acl-backup.txt
    从备份恢复 ACL
    $ sudo setfacl --restore=acl-backup.txt