共计 2644 个字符,预计需要花费 7 分钟才能阅读完成。
在 Linux/Unix 操作系统中,每个文件和目录对不同的用户组都能设置各自的权限。众所周知,Linux 中用户组分为三类:
- owner:文件(或目录。若未作特殊说明,下文文件均表示文件或目录的意思)拥有者。使用字符
u
表示。 - group:文件拥有者所在组,组内所有用户对于同一文件享有相同权限。使用字符
g
表示。 - other:除了文件拥有者和所在组外的其他所有用户。使用字符
o
表示。
若希望表示所有用户,可用a
来代替。
对于权限位来说,除了 rwx 外,执行 ls -l
有时还能看到 st 等符号,这些符号表示什么意思呢?本文一一说来。
执行 ls -l
返回的文件权限位如下图:
Linux 文件权限图
上图中权限位分为如下几类:
-
无任何权限。r
读权限,用户组对该文件可读。w
写权限,用户组该文件可写。x
可执行权限,若对象为文件,则该用户组可执行该文件;若对象为目录,则该用户可进入目录,否则报错 "Permission denied"。X
如果目标对象是目录,则为其添加可x
,使用户组可进入目录;若为文件则不增加可执行权限,维持文件权限位不变。s
设置 SUID 或 SGID 位。- 设置 SUID 后,无论谁执行文件,都会以文件拥有者的身份来执行,而非当前执行者的身份。
- 设置 SGID 后,在执行文件时会获得文件所有组的权限。
t
设置 sticky bit(粘滞位)。一般用来设置目录,设置粘滞位后该目录下的文件只有 owner 和 root 才能删除和重命令。一般情况下/tmp
目录会设置粘滞位,这样任何人都可以在/tmp
目录创建文件,但不可删除其他用户的文件。
文件权限位命令#
chmod#
chmod
用来修改文件权限,有两种模式能修改文件权限。
symbolic mode#
格式:chmod [ugoa][-+=][rwxXstugo] <file-name or directory-name>
,若同时设置多个用户组权限,使用 ,
分隔设置。
_注:[options]
表示该选项的值为 MARKDOWN_HASH93da65a9fd0004d9477aeac024e08e15MARKDOWNHASH
中的任意一个。
示例:
chmod u+s file
:设置 SUID;chmod g+s file
:设置 SUID;chmod o+t directory
:设置粘滞位。chmod u+s,g-w,o=r file
:设置 SUID,组用户去掉w
权限,other 组只保留r
权限。
可以注意到:若设置 SUID/SGID/粘滞位,对应 x
位会被代替:
- SUID 会代替 owner 用户组的
x
; - SGID 会代替 group 用户组的
x
; - 粘滞位会代替 other 用户组的
x
。
如果本来该位为x
则显示小写字母s
或t
。若原本为-
则显示大写字母S
或T
。
numeric mode#
格式:chmod <permission-number> <file-name or directory-name>
。
rwx
权限位对应的值如下:
- 读权限:4
- 写权限:2
- 可执行权限:1
故 rwx
的值有如下 8 种情况:
--- = 0
--x = 1
-w- = 2
-wx = 3
r-- = 4
r-x = 5
rw- = 6
rwx = 7
而 SUID/SGID/粘滞位对应的值如下:
- SUID bit: 4
- SGID bit: 2
- 粘滞位: 1
若需要设置 SUID/SGID/粘滞位,权限数字为 NNNN 的形式,如设置粘滞位:chmod 1777 /tmp
。
umask#
控制默认权限。在创建文件和目录时时,文件请求权限为 0666
,目录请求权限为 0777
,将这些权限减去 umask
值即为最终权限。执行 umask
可得到默认值:
- root 用户默认值为
0022
,故 root 用户创建的目录权限为0755
,文件权限为0644
; - 非 root 用户的默认值为
0002
,故非 root 用户创建的目录权限为0775
,文件权限为0664
。
ACL#
从 Linux 文件权限图中可以看到最后一位有时为 +
,有时为 .
。若为 +
表示设置了 ACL,若为 .
表示设置了 SELinux。
ACL(全称:Access Control List,访问控制列表) ,是 UGO 权限管理的一个补充,其允许给任何用户/用户组设置任何文件/目录的访问权限。
ACL 规则由一系列的 Access Entry 组成,Access Entry 定义了特定类别对文件拥有的操作权限,Access Entry 由如下三部分组成:
- type
类型。Entry type 有如下 6 种值:- ACL_USER_OBJ
- ACL_USER
- ACL_GROUP_OBJ
- ACL_GROUP
- ACL_MASK:ACL_MASK 只作用于 ACL_USER, ACL_GROUP_OBJ 和 ACL_GROUP,限制了三种 Access Entry 的最大权限,如对于 ACL_GROUP 而言,若 ACL_MASK 未设置,则使用 ACL_GROUP 设置的权限;若设置了 ACL_MASK,最大能拥有的权限是 ACL_MASK。
- ACL_OTHER
- qualifier
限定用户和用户组,可选。 - permissions
rwx
权限。
如下是 6 种类型各自的例子:
Entry Type | Text Form Example |
---|---|
ACL_USER_OBJ | user::rwx |
ACL_USER | user:name:rwx |
ACL_GROUP_OBJ | group::rwx |
ACL_GROUP | group:name:rwx |
ACL_MASK | mask::rwx |
ACL_OTHER | other::rwx |
开启 ACL#
通过 dumpe2fs
或 tune2fs
可查看硬盘是否开启了 ACL,如笔者 /
持载设备为 /dev/vda2
,查看 /
是否开启了 ACL,使用如下命令:
$ sudo tune2fs -l /dev/vda2 |grep "mount options"
Default mount options: user_xattr acl
若未开启,修改 /etc/fstab
增加 ACL 的 mount 选项重新持载下即可。
命令#
getfacl
查看 ACL。setfacl
设置 ACL。若对目录设置 default ACL,则该目录下的所有文件默认继承目录设置的 ACL。
SELinux#
若文件权限位最后一位显示 .
,说明表示该文件是在开启 SELinux 时创建的。
开启 SELinux#
sestatus
用来查看 SELinux。SELinux 状态有三种:
- Disabled:关闭状态;
- Permissve:宽容模式,只通过 Kernel Audit System 记录日志, 但不拦截访问;
- Enfocing:强制模式,记录日志的同时还会拦截访问。
通过 setenforce
临时修改 SELinux;修改 /etc/sysconfig/selinux 并重启永久修改 SELinux。