1. 文件属主 , 属组

1.1 chown

chown(change owner)用于修改文件或目录的所有者 , 也可顺带修改所属组。只有 root 用户或文件的当前所有者才能使用(普通用户只能把自己的文件改给别人所属组)。

  • 语法 : chown [OPTION]..[OWNER][:[GROUP]] FILE...

  • OPTIONS

    • -R /--recursive : 递归处理目录及其中所有文件

    • -f : 抑制大多数错误消息

    • -c : 仅在被实际修改时报告

    • -h : 不跟随软链接 , 直接修改软链接本身的属主(默认 chown 会跟随symlink 修改指向的文件)

    • -v : 显示每个被修改的文件

    • --reference=文件 : 把目标文件的属主属组直接改成和参考文件一模一样 , 没有条件过滤

    • --from=OLDUSER:OLDGROUP : 只有当文件当前属主 / 属组匹配 --from 指定的值时 , 才执行所有权修改 ; 不匹配则跳过 , 不作任何改动

  • 用法 :

    • OWNER :修改文件属主

    • OWNER:GROUP :同时修改文件属主与属组

    • :GROUP :单独修改文件属组

    命令中的冒号可用.替换

示例

# 1. 修改文件所有者
chown alice file.txt
​
# 2. 同时修改所有者和所属组
chown alice:developers file.txt
​
# 3. 只修改所属组(注意有冒号)
chown :developers file.txt
​
# 4. 递归修改整个目录
chown -R alice:developers /data/project/
​
# 5. 使用 UID:GID(数字形式)
chown 1000:1001 file.txt
​
# 6. 保持符号链接本身不变 , 修改链接指向的目标
chown -h alice symlink.txt
​
# 7. 不显示错误信息
chown -f alice file.txt
​
# 8. 显示修改过程(冗余模式)
chown -v alice file.txt
​
# 9. 修改时保留文件原有所有者/组的对应关系(参照参考文件)
chown --reference=ref.txt target.txt
​
# 10. 文件当前属主是 olduser , 才改成 newuser
chown --from=olduser newuser test.txt
​
# 11. 同时校验属主 + 属组 , 全部匹配才修改
chown --from=olduser:oldgrp newuser:newgrp /data/file
​
​
​

1.2 chgrp

chgrp(change group)用于修改文件或目录的所属组。功能上相当于 chown :组 的简化版 , 只动组、不动所有者。

  • 用法:

    • chgrp [OPTION]...GROUP FILE ...

    • chgrp [OPTION]... --reference=RFILE FILE ... :参考指定文件的所属组修改指定文件的所属组

  • OPTIONS

    • -R /--recursive : 递归处理目录及其中所有文件

    • -f : 抑制大多数错误消息

    • -c : 仅在被实际修改时报告

    • -h : 不跟随软链接 , 直接修改软链接本身的属主(默认 chown 会跟随symlink 修改指向的文件)

    • -v : 显示每个被修改的文件

    • --reference=文件 : 把目标文件的属组直接改成和参考文件一模一样 , 没有条件过滤

    • --from=OLDGROUP : 只有当文件当前属组匹配 --from 指定的值时 , 才执行所有权修改 ; 不匹配则跳过 , 不作任何改动

示例

# 1. 修改文件属组
chgrp developers test.txt
​
# 2. 递归修改目录下所有文件的属组
chgrp -R developers /data/project
​
# 3. 参考文件复制属组 
chgrp --reference=/etc/passwd myfile
# myfile 的属组和 /etc/passwd 的属组保持一致
​
​
# 4. --from 条件匹配(只当前属组匹配才改)
# 文件当前属组是oldgrp , 才改成developers
chgrp --from=oldgrp developers /data/file
​
​
# 5. 修改软链接本身 , 不改动源文件
chgrp -h developers linkfile
​
# 6. 使用 GID 数字(适合账号不同步场景) 
chgrp 1005 test.txt

2. 文件权限

2.1 权限基础

Linux 的文件权限保存在文件 inode 中 , 分为 身份 + 权限位。

三类身份 : 属主 (u)、属组 (g)、其他 (o) , 每一类都有独立的 rwx 权限。

ls -l test.txt
-rw-r--r-- 1 root root 123 Sep 20 10:00 test.txt

第 1 列 -rw-r--r-- 就是权限位 , 一共 10 位

 第1位 | 第2~4位 | 第5~7位 | 第8~10位
 文件类型 | 属主权限 | 属组权限 | 其他用户权限
​

  • 权限分类

    • r读权限 : 可以打开文件、目录读取查看

    • w 写权限 : 对文件目录可以编写更改

    • x 执行权限 : 对文件可执行(可执行文件)、对目录可查找该目录下的内容。

    • - 没有权限。

  • 文件目录权限

    • 文件

      读权限(r) : 表示只允许指定用户读取相应文件的内容 , 而禁止对它做任何的更改操作。将所访问的文件的内容作为输入的命令都需要有读的权限。例如cat、more等。

      写权限(w)表示允许指定用户打开并修改文件。例如命令vi、cp等。

      执行权限(x)表示允许指定用户将该文件作为一个程序执行。

    • 目录

      读权限(r) : 可以列出存储在该目录下的文件 , 即读目录内容列表。这一权限允许Shell使用文件扩展名列出相匹配的文件名。

      写权限(w): 允许用户从目录中删除或添加新的文件 , 通常只有文件主才有写权限。

      执行权限(x) : 允许用户在目录中查找 , 并能用cd命令将工作目录改到该目录。如果一个目录只有读权限 , 那么只能读取该目录下面的所有文件 , 不能读取文件的详细信息。即不能用ls -l 查看该目录下的文件的详细信息 , 只能看到文件名。

对于文件和目录而言有s特别标志位 , 在SUID , SGID中会讲解。

2.2 权限表示

在linux中针对文件 , 分别对应文件属主 , 属组以及其他用户的权限 , 每一种用户类型都用三位表示rwx , 分别表示读写执行权限。如果文件中对应权限没有 , 则直接用-表示 , 即-wx,--x...。同时对应的权限可以直接当做二进制数值 , 并将其用十进制表示出。权限数值规则 : r=4、w=2、x=1 ,三组权限分别求和。

权限组合

数值

说明

---

0

无任何权限

r--

4

只读

-w-

2

只写

-wx

3

写+执行

r-x

5

读+执行

rw-

6

读写(文件默认权限)

rwx

7

读写执行(目录默认权限)

常用标准权限:

  • 普通文件 : 644(属主读写 , 组/其他只读)

  • 目录/脚本 : 755(属主读写执行 , 组/其他读+执行)

  • 私密文件 : 600(仅属主读写)

2.3 umask

umask命令用来设置限制新建文件权限的掩码, 不修改已有文件权限。当新文件被创建时 , 其最初的权限由文件创建掩码决定。用户每次注册进入系统时 , umask命令都被执行 , 并自动设置掩码mode来限制新文件的权限。用户可以通过再次执行umask命令来改变默认值 , 新的权限将会把旧的覆盖掉。

通过umask命令可以配置linux文件的掩码值。默认umask为022。一般umask在~/.bashrc中修改。

umask 与最大权限相与 , 可以得到文件目录权限

文件最大权限(666):110110110  
umask           : 001100101  
文件权限        : 110010010   
umask中0表示不关心 , 不处理 , 1表示从最大权限中要去掉对应位置的权限

对于目录根据umask设置权限的方法 : 777-umask

对于文件666-umask 观察结果有偶数 , 最终结果便是直接算出来的值 , 如果是奇数 , 最终结果加1便是权限值

  • 语法: umask OPTIONS [mode]

  • OPTIONS

    • -p :输出结果为 umask 0022这样 一般用于写脚本 , umask -p >~/.bashrc

    • -S : 输出结果为u=rwx,g=rx,o=rx 在设置umask是可以直接设置成结果同样的新形式 , 这个结果表示文件default的权限值

2.4 chmod

chmod = change mode , Linux 核心权限命令 ,用于修改文件/目录的 rwx 访问权限。

  • 语法 : chmod [OPTION]... MODE[,MODE]... FILE...

  • 选项

    参数

    说明

    -R

    递归修改目录下所有子文件、子目录(高频 , 慎用)

    -v

    详细输出 , 打印每一个被处理的文件

    -c

    只打印权限发生变更的文件 , 无变化不输出

    -h

    不跟随软链接 , 直接修改软链接本身权限(默认会修改链接指向的源文件)

    --reference=FILE

    参考指定文件的权限 , 把目标文件改成和参考文件完全一样

  • MODE: 权限模式分为两种 , 数字(八进制)模式、符号模式

    • 数字(八进制)权限模式

      规则 : r=4 , w=2 , x=1 , u/g/o 三组分别求和。

      常用标准权限

      • 644 : 普通文件 , 属主 rw , 组和其他 r(网页、配置文件)

      • 755 : 目录 / 脚本 , 属主 rwx , 组和其他 rx

      • 600 : 密钥、私密配置 , 仅属主读写

      • 700 : 私密目录 , 仅属主访问

      chmod 644 test.txt                 # 文件设为644
      chmod 755 app.sh                   # 脚本设755
      chmod -R 755 /data/www             # 递归修改目录
      chmod 600 ~/.ssh/id_rsa            # 私钥文件
    • 符号模式

      修改一类用户的所有权限(u:表示属主;g:表示属组;o:表示其他用户)

      • 角色

        • u (user) : 属主

        • g (group) : 属组

        • o (other) : 其他用户

        • a (all) : u+g+o 全部。运行命令过程中如果不加角色, 同样表示all。例: chmod +rw filename表示对应文件所有角色都添加读写权限

        需要注意, 这里的角色可以混合一起使用类似ug

      • 操作符

        • + : 增加权限 , 原有权限保留

        • - : 删除权限

        • = : 覆盖设置 , 清空原有权限 , 只保留等号后面的

      chmod u+x app.sh          # 给属主增加执行权限
      chmod g-w,o-w test.txt    # 删除属组、其他人的写权限
      chmod a-x test.sh         # 所有人移除执行权限
      chmod u=rw,g=r,o= test.txt# 属主rw , 组r , 其他无权限
      chmod ug=rwx,o=r file     # 属主属组rwx , 其他人只读

执行权限 中 小写 x表示执行权限 , 大写 X表示条件式执行权限 。如果是普通文件 , 原本完全没有任何 x 权限 , +X 不会给它增加执行权限。chmod -R +x 递归的时候 , 会把所有日志、配置、文本文件全部加上执行位 , 不安全。+X 就是用来规避这个问题。

X 只会在下面两种情况 ,才添加执行x 权限 :

  1. 目标是目录

  2. 目标是文件 , 并且该文件的 u/g/o 任意一组已经拥有执行 x 权限

3. 特殊权限

Linux 除了基础的 rwx(读、写、执行) 普通权限外 , 还有 3 个特殊权限位 : SUID、SGID、Sticky Bit(粘滞位)。

基础权限是针对属主、属组、其他用户 ; 特殊权限是附加在权限高位的功能位 , 单独生效。

普通权限共 9 位 : 属主rwx 属组rwx 其他rwx 。额外 3 个特殊位(在属主、属组、其他的执行位上叠加)

特殊权限

数字值

字符标记位置

字符显示

SUID

4

属主执行位 x

s(有 x) / S(无 x)

SGID

2

属组执行位 x

s(有 x) / S(无 x)

Sticky Bit

1

其他用户执行位 x

t(有 x) / T(无 x)

数字权限格式 : 特殊位 + 普通三位 例:4755 → SUID + rwxr-xr-x ; 2775 → SGID + rwxrwxr-x ; 1777 → Sticky + rwxrwxrwx

3.1 SUID

SUID(Set User ID) : 继承所有者权限。文件执行时 , 临时以文件属主身份运行 , 而不是当前执行用户身份。

  • suid只能作用在二进制程序上 , 不能作用在scripts上

  • 执行suid权限的程序时 , 用户将继承此程序的所有者权限

  • 本权限仅在执行该程序的过程中有效(run-time)

  • 执行者对于该程序需要具有x的可执行权限 ;

SUID 程序如果存在漏洞 , 普通用户可提权到文件属主(尤其是root 属主的 SUID 程序) , 生产环境尽量不要自定义 SUID 文件。

字符显示

  • 属主位有 x:权限显示 rws(小写s)

  • 属主位没有 x:rwS (大写S , SUID 标记存在 , 但不能执行 , 无效)

配置SUID时,可以直接通过chmod命令配置,直接通过给属主添加s权限

chmod u+s filename
chmod 4660 filename  

文件权限中可以通过SUID,SGID,Stick位三者可以按照二进制方式组成并以十进制的方式表现出来,所以对应的4660中的4表示SUID

示例

passwd 属主是 root , 普通用户执行它时 , 临时拥有 root 权限 , 才可以修改 /etc/shadow(普通用户只读)。

ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ...

设置 / 取消 SUID

# 数字方式:4开头
chmod 4755 /bin/xxx
# 符号方式
chmod u+s /bin/xxx
# 取消SUID
chmod u-s /bin/xxx
​

3.2 SGID

SGID : 与SUID一样,继承所有组的权限 。~ 有两种场景:文件 / 目录 , 行为完全不同

  1. 对于二进制文件和SUID类似 , 作用在二进制程序上 , 执行sgid权限的程序时 , 此用户将继承此程序的所属组权限。同样需要文件本身有 x 权限。 显示 : 属组位 rws(小写s) ; 无 x 则 rwS

    chmod 2755 file
    chmod g+s file
    chmod g-s file

  2. 作用在目录上 , 在此目录新的文件的所属组 , 将自动继承目录的所属组

    mkdir /data/share
    chgrp dev /data/share
    chmod 2770 /data/share   # SGID + rwxrwx---
    #任何 dev 组用户在 /data/share创建文件 , 文件属组自动是dev。

3.3 Stick

这个位主要是针对other用户设置的,设置之后other 用户中只有文件的拥有者才能删除这个目录中对应的自己的文件文件。Sticky只能作用在目录上。只对other用户有效 , 对属主与属组以及root用户无效。这里只对目录有效, 对文件无效。粘滞位限制删除 , 不限制读写。别人依旧可以修改你的文件内容 , 只是不能删除。

chmod o+t dirname
chmod 1777 dirname

当文件目录中,如果没有执行权限 , 则在权限上面会变成大写的S、T ,由于这些特殊权限需要有执行权限。此时大写表示特殊权限失效。

示例

/tmp 全局可读写 , 但是 A 用户不能删除 B 用户在 /tmp 里的文件 , 靠的就是粘滞位。

ls -ld /tmp
# drwxrwxrwt root root ...

设置 / 取消

# 数字 1开头
chmod 1777 /mydir
# 符号方式
chmod o+t /mydir
chmod o-t /mydir
​

4. linux的隐藏属性

首先说明,这个隐藏属性主要是针对ext系列的文件系统设计的 , 主要为了增加系统的安全性,此功能已全部或部分扩展到其他的文件系统上面了,例如XFS , ReiserFS , JFS和OCFS2。

chattr 设置的是文件系统级别的隐藏属性 , 优先级高于普通权限 , root 也会被限制。 支持文件系统 : ext2/ext3/ext4 ; XFS 只支持部分属性(A,a,i,S) , btrfs 也部分支持。

4.1 chattr

使用chattr 为文件修改隐藏属性 ,

  • 语法 : chattr [ -RVf ] [ -v version ] [ mode ] files…

    • + : 在原有参数设定基础上 , 追加参数。

    • - : 在原有参数设定基础上 , 移除参数。

    • = : 更新为指定参数设定。

  • mode: 主要属性有以下几种:

    • A : 文件或目录的 atime (access time)不可被修改(modified), 可以有效预防例如手提电脑磁盘I/O错误的发生。

    • S : 硬盘I/O同步选项 , 功能类似sync。

    • a : 即append , 设定该参数后 , 只能向文件中添加数据, 而不能删除,多用于服务器日志文件安全 ,只有root才能设定这个属性。

    • c : 即compresse , 设定文件是否经压缩后再存储。读取时需要经过自动解压操作。

    • i : 设定文件不能被删除、改名、设定链接关系 , 同时不能写入或新增内容。i参数对于文件 系统的安全设置有很大帮助。

    • j : 即journal , 设定此参数使得当通过mount参数 : data=ordered 或者data=writeback挂 载的文件系统 , 文件在写入时会先被记录(在journal中)。如果filesystem被设定参数为data=journal , 则该参数自动失效。

    • s : 保密性地删除文件或目录 , 即硬盘空间被全部收回。

    • u : 与s相反 , 当设定为u时 , 数据内容其实还存在磁盘中 , 可以用于undeletion。

常用的两个属性有a,i

chattr +i /etc/resolv.conf   //此时无法修改/etc/resolv.conf文件
chattr -i /etc/resolv.conf   //删除文件的隐藏权限,现在可以删除和修改文件中的内容
chattr +a /etc/tesolv.conf   //此时只能追加文件内容,不能删除 , 不能改名
​
lsattr /etc/resolv.conf  //显示文件的隐藏权限
----i-------- /etc/resolv.conf

4.2 lsattr

lsattr = list attributes , 查看文件系统扩展隐藏属性 , 配套命令 chattr 修改属性。 属于 e2fsprogs 工具包 , 原生支持 ext2/ext3/ext4 ; XFS、Btrfs 仅支持部分属性。

区别 : ls -l 看传统 rwx/SUID/SGID ; lsattr 看文件系统底层隐藏标记。

  • 语法 : lsattr [选项] [文件/目录]

  • 选项

    参数

    说明

    典型场景

    -R

    递归 , 连同所有子目录内文件一起显示

    批量扫描目录树所有文件隐藏属性

    -a

    显示所有文件 , 包含.开头隐藏文件

    查看隐藏文件是否加了 i/a 锁

    -d

    只显示目录本身属性 , 不列出目录里面的文件

    查看目录是否设置了隐藏属性(极易踩坑)

    -v

    显示文件版本号(generation 号)

    文件系统底层调试

    -l

    长格式 , 输出属性完整英文名称 , 不是单字母缩写

    新手阅读

    -V

    显示 lsattr 程序自身版本

    查看工具版本

    不加 -d 直接 lsattr /data , 默认输出 /data 目录里面所有文件 , 而不是 /data 目录本身属性。

示例

# 1. 查看单个文件
lsattr /etc/passwd

# 2. 查看目录本身属性(一定要加 -d)
lsattr -d /data/share

# 3. 递归查看目录下所有文件 , 包含隐藏文件
lsattr -Ra /var/log

# 4. 长格式输出 , 看完整属性名
lsattr -l test.txt

# 5. 结合管道 , 查找系统带i不可变属性的文件(排查病毒/锁文件)
lsattr -R / 2>/dev/null | grep '----i'

配合chattr 测试

# 设置文件不可变
chattr +i test.txt
lsattr test.txt
# ----i---------e---- test.txt
​
# 取消不可变
chattr -i test.txt
lsattr test.txt
# -------------e---- test.txt
#e表示ext4 区段映射, 默认自带,不是手动设置的属性

5. 文件访问控制列表

ACL 是传统 UGO 权限 (rwx) 的扩展。传统权限只能设置 : 属主、属组、其他这三类身份 ;ACL 可以单独给任意用户 / 任意组分配独立权限 , 实现精细化授权。

查看文件系统是否开启了ACL功能。 可以直接通过使用dumpe2fs命令查看对应文件系统中挂载时是否默认有acl功能 , 如果没有可以直接通过mount -o acl ,给文件系统添加ACL功能。

通过使用setfacl以及getfacl这两个命令修改文件的扩展的ACL。

前置条件 : 文件系统支持 ACL(ext4/xfs 等) , 挂载选项开启acl ; 需要安装 acl 包 yum install acl / apt install acl

  • 两种 ACL 类型

    1. 访问 ACL(access ACL) : 作用在当前文件 / 目录本身的权限

    2. 默认 ACL(default ACL ,仅目录) :目录上设置 , 在这个目录里新建的文件 / 子目录会自动继承默认 ACL ; 已有老文件不会自动生效。

当文件配置了 ACL , ls -l 权限末尾会出现一个 + 号:

-rw-r--r--+ 1 root root ... test.txt
  • mask : mask 是权限最大上限 , 限制所有命名用户、命名组、文件属组的有效权限。

    mask 不影响文件属主、other 其他人。setfacl -m 修改 ACL 时 , 默认自动重新计算 mask ; 加 -n 参数才不自动更新 mask。

5.1 setfacl

setfacl = set file access control list , 用来设置 / 修改 / 删除文件与目录的 ACL 扩展权限 ; 配套查看命令 getfacl。 传统 UGO 权限只能控制 : 属主、属组、other 三类 ; ACL 可以对任意用户、任意用户组单独授权。

  • 语法 :

    • setfacl [options] u:[用户列表]:[rwx] 目录/文件名 # 对用户设置使用u

    • setfacl [options] g:[组列表]:[rwx] 目录/文件名 # 对组设置使用g

  • OPTIONS

    • -m : 设定ACL权限(modify)

    • -x : 删除指定的ACL权限 , 可以指定用户、组和文件来删除(remove)

    • -M : 写了ACL条目的文件 , 将从此文件中读取ACL条目 , 需要配合-m , 所以-M指定的是modify file 文件中写的内容就是u:wang:rwx。 这样的权限内容

    • -X : 写了ACL条目的文件 , 将从此文件中读取ACL条目 , 需要配合-x , 所以-X指定的是remove file

    • -b : 删除所有的ACL权限

    • -d : 设定默认ACL权限 , 只对目录有效 , 设置后子目录(文件)继承默认ACL , 只对未来文件 有效

    • -k : 删除默认ACL权限

    • -R : 递归设定ACL权限 ,只对目录有效 ,只对已有文件有效

    • -n : no mask , 不自动重新计算mask, 手动固定mask值

    • --restore : 从getfacl到处的备份文件恢复ACL

示例

给指定用户授权

# 给用户 tom 授予 test.txt 读写权限
setfacl -m u:tom:rw- test.txt
​
# 查看
getfacl test.txt
​

给指定用户组授权

# 给组 dev 授予读执行权限
setfacl -m g:dev:r-x test.txt

修改mask掩码上限。mask 是 ACL 命名用户 / 命名组的最大有效权限上限。不带 -n 使用 -m 时 , mask 会自动更新 ; 如果不想 mask 自动变化 , 加 -n。

# 手动设置mask为rw
setfacl -m m:rw- test.txt

录设置默认 ACL(多人共享目录核心)。default ACL 仅对之后新建的文件 / 子目录生效 ; 已有存量文件不会自动继承!

mkdir /data/share
# 设置默认ACL:后续新建文件自动给dev组rw权限
setfacl -d -m g:dev:rw- /data/share
# 同时给目录本身设置访问ACL(目录自身权限)
setfacl -m g:dev:rw- /data/share
​

递归授权(存量文件一次性批量加ACL)

setfacl -R -m u:tom:rwx /data/share

删除ACL条目

# 删除 tom 这一条ACL
setfacl -x u:tom test.txt
​
# 删除dev组ACL
setfacl -x g:dev test.txt
​
# 删除目录上所有默认ACL(default)
setfacl -k /data/share
​
# 清空文件所有ACL扩展规则 , 保留原生UGO权限
setfacl -b test.txt
​

ACL备份与恢复

# 备份:getfacl导出
getfacl -R /data/share > acl_back.txt
​
# 恢复:setfacl --restore
setfacl --restore=acl_back.txt
​

其他示例

mount -o acl  /idrectory  
getfacl file | directory  
setfacl -m u:wang:rwx file|directory   // 设置用户权限
setfacl -Rm g:sales:rwX directory    // 递归设置对应目录的组用户权限
setfacl -M file.acl file|direcory     // 通过文件设置对应的文件目录权限
setfacl -m g:salesgroup:rw file|directory     //  设置对应的组权限
setfacl -m d:u:wang:rx  directory   //  设置对应目录的用户权限  前面加d  表示默认权限 , 即在对应目录中新建文件目录同样拥有对应的用户权限
setfacl -x u:wang file|directory    //  删除对应用户的acl权限
setfacl -X file.acl directroy   //通过文件删除目录的ACl权限
setfacl -b file  //删除文件中所有的acl权限  
setfacl -k //删除文件的默认权限 
getfacl file1 | setfacl --set-file=- f2  //将file1的权限直接复制给file2
setfacl --set  u:rw,u:wang:rw,g::r,o::-  f2   //这个命令类似于重新覆盖原来的所有权限。

如果使用用户属于多个组 , 则累加权限

系统会默认从上往下读取权限 , 如果是组成员则累加权限

5.2 getfacl

getfacl = get file access control list, 用来查看文件/目录的ACL访问控制列表, 配套修改命令setfacl。

当文件配置ACL后, ls -l 的权限末尾会出现+。但ls只能提示有ACL,无法查看ACL具体条目, 必须用getacl。

  • 语法 : getfacl [选项] 文件/目录名

  • 选项

    参数

    说明

    -R

    递归查看目录及其内部所有文件、子目录的 ACL

    -c

    compact , 精简输出 , 去掉注释行(# 开头) , 只保留权限条目 , 脚本处理很常用

    -d

    只显示默认 ACL (default) , 不显示访问 ACL

    -p

    不把文件名转成绝对路径 , 保持原始路径

    -t

    表格格式输出 , 可读性更强

    -n

    显示 UID/GID 数字 , 而不是用户名、组名

输出示例:

# file: test.txt                  #文件名(注释行 , -c 参数会删掉这一类)
# owner: root                     #文件属主
# group: root                     #文件属组
user::rw-                         #空白冒号, 代表文件属主(UGO里的user)权限
user:zhangsan:r--                 #ACL条目: 单独给用户zhangsan只读权限
group::r--                        #空白冒号, 代表文件属组(UGO里的group)权限
group:dev:rw-                     #ACL条目: 单独给dev组读写权限
mask::rw-                         #掩码,ACL权限上限, 限制所有命名用户/命名组的最大有效权限,不影响属主和 other
other::r--                        #其他人权限(UGO的other)
​

如果目录设置了默认 ACL , 会多出 default: 开头条目:

default:user::rwx
default:group::r-x
default:group:dev:rw-
default:mask::rw-
default:other::r--
​

default: 就是默认 ACL , 在这个目录下新建的文件/子目录自动继承这套 ACL 规则 ; 对目录内已经存在的旧文件无效。

示例 :

查看单个文件ACL

getfacl test.txt

精简输出(去掉注释, 适合脚本)

getfacl -c test.txt

递归查看整个目录树ACL

getfacl -R /data/share

只查看默认ACL(default)

getfacl -d /data/share

输出UID/GID数字, 不解析名称

getfacl -n test.txt

表格形式展示

getfacl -t test.txt

5.3 mask

5.3.1 mask基础

mask 是 ACL 的权限掩码 / 最大有效权限上限。

mask只作用于三类主体:

  1. 命名用户(user:xxx:rwx , 不是文件属主 user::)

  2. 命名用户组(group:xxx:rwx , 不是文件属组 group::)

  3. 文件属组(group::)

mask 不影响 : 文件属主 user:: 和 other 其他人 o::

命名用户、命名组、文件属组 , 最终生效权限 = ACL 配置权限 和 mask 权限做按位与(&)。

举个例子 : ACL 配置rwx , mask 是r-- rwx & r-- = r-- → 最终只有读权限。

mask 本身是一条 ACL 条目 : mask::rw- 文件只要存在命名用户 / 命名组 ACL 条目 , 就会自动产生 mask ; 如果只有原生 UGO 权限 , 没有额外 ACL , getfacl看不到 mask 行。

[root@localhost app]# getfacl f1
# file: f1
# owner: root
# group: root
user::rw-
user:xiong:rw-   #effective:r--
group::r--
mask::r-
other::r--
​

mask这个值除了user:rw- 以及other::r--不会影响到之外其他均会受到影响 , mask值决定了中间这些人的最大权限。 默认每次设置文件的acl都会重置mask为给当前设置用户的值。

5.3.2 自动更新mask

当使用 setfacl -m 添加 / 修改 ACL 条目时 , 默认自动重新计算 mask, mask 会自动扩展到容纳所有 ACL 条目的最大权限。

示例:

# 给用户tom设置rwx权限
setfacl -m u:tom:rwx test.txt
getfacl test.txt
​
#输出
user::rw-
user:tom:rwx
group::r--
mask::rwx
other::r--
​

mask 自动变成rwx,刚好容纳 tom 的 rwx 权限。

再追加一条 ACL:

setfacl -m g:dev:rw- test.txt

此时所有命名条目最大权限是 rwx , mask 仍然保持 rwx。

5.3.3 禁止自动更新mask

setfacl -n(no mask recalculate) , 修改 ACL 时不会自动重算 mask , mask 保持原值 , 这是坑点!

演示:

# 先设置mask=r--,加上-n不自动更新
setfacl -n -m m:r-- test.txt
# 给tom设置rwx,加-n,mask不会自动扩容
setfacl -n -m u:tom:rwx test.txt
getfacl test.txt
​
​
#输出
user::rw-
user:tom:rwx
group::r--
mask::r--
other::r--
​

配置给 tom 是rwx , 但是 mask=r-- , tom 实际权限只有 r--。

5.3.4 手动修改mask

# 直接修改mask为rw
setfacl -m m:rw- test.txt
# 只修改mask,不改动其他ACL规则
​
setfacl -m mask::r f1 
​

5.3.5 mask和默认ACL(default mask)

目录设置默认 ACL 时 , 也会有 default:mask::。 default mask : 控制未来新建文件的 mask 默认值。新建文件继承 default mask ,同样会限制新建文件里面命名用户 / 命名组的权限。

setfacl -d -m g:dev:rwx /data/share
getfacl /data/share
# default:mask::rwx

5.4 备份还原ACL

有些工具在复制文件时会丢失acl ,备份以及还原ACl的方法

主要的文件操作命令cp 和mv都支持ACl , 只是cp命令需要加上-p参数 , 但是tar等常见的备份工具是不会保留目录和文件的ACL信息的

getfacl -R /tmp/dir1 > acl.txt  
setfacl -R -b/tmp/dir1  
setfacl -R --set-file=acl.txt /tmp/dir1  
setfacl --restore acl.txt 
getfcal -R /tmp/dir1

在这个命令中第三条以及第四条均是回复ACl的操作 , 任选一条就好了, 但是--restore 这条命令在运行时 , 在相对路径上执行的 , 所以对于使用者需要在复制目录的前一个目录执行此命令


参考链接

linux命令大全:umask

博客园-骏马金龙:第3章 Linux上文件的权限管理

熊熊