12. Rocky Linux 文件权限管理
在 一章中,我们讨论了如何查看文件的权限,并对权限做了简单介绍。通过本章,我们一起回顾下这方面的知识,并对权限进行更深入的讨论。
12.1 普通权限介绍
在 Linux 中,一切皆文件。ls -l 命令可以列出文件权限的相关信息:
[root@rocky08-host ~]# ls -l /usr/bin/bash
-rwxr-xr-x. 1 root root 1150576 10月 9 2021 /usr/bin/bash
[root@rocky08-host ~]# ls -l /etc/passwd
-rw-r--r--. 1 root root 1684 4月 23 08:43 /etc/passwd
[root@rocky08-host ~]# ls -l /etc/shadow
----------. 1 root root 1062 4月 23 08:43 /etc/shadow
[root@rocky08-host ~]# ls -ld /tmp/
drwxrwxrwt. 4 root root 4096 4月 27 15:16 /tmp/
以 /usr/bin/bash
文件的权限为例,我们先回顾权限的结构:
-rwxr-xr-x.
它包含五个块,每块内容如下:
Block 1 | Block 2 | Block 3 | Block 4 | Block 5 |
---|---|---|---|---|
- | rwx | r-x | r-x | . |
权限结构的知识基础且重要。Block 1 表示文件可能具有特殊权限。如果它是普通文件,则没有特殊权限,就如本例,显示为 -
:
-
-:表示普通文件;
-
d:表示目录;
-
l:表示符号链接文件;
-
s:为不同用户或组提供执行文件的权限,称为 setuid 或 setgid;
-
t:仅对目录设置的特殊权限,只有所有者或 root 用户才能删除或重命名在该目录下创建的目录或文件,称为 sticky bit。
Block 2 表示了文件所属用户的权限,由三个字符表示:
-
r:读权限; -
w:写权限; -
x:执行权限。如果是目录, x
表示所属用户可以进入该目录。
Block 3 表示属组的权限,由读写执行 (rwx) 三部分组成,在本示例中,属组缺少 w
权限。
Block 4 表示其他用户的权限,也由读写执行 (rwx) 三部分组成,在本示例中,同样缺少 w
权限。
Block 5 表示有 SELinux 上下文应用于该文件。
Linux 提供了 chmod 命令,用来修改文件权限。我们创建一个新文件,来演示该命令的用法:
[root@rocky08-host ~]# touch aiops.txt
[root@rocky08-host ~]# ls -l aiops.txt
-rw-r--r--. 1 root root 0 4月 27 16:10 aiops.txt
文件创建后,所有者是当前用户,属组是当前用户的主组,并且新创建的文件已经分配了默认权限。默认权限由 umask 定义。在 Linux 中,新创建文件的默认权限如下:
-
User:读和写 -
Group:读 -
Others:读
使用 chmod 修改权限,需要我们指定三个字符:
-
第一个字符,定义修改权限会影响到谁: -
u:User -
g:Group -
o:Others -
第二个字符表示增加或删除权限: -
+:添加权限 -
-:移除权限 -
第三个字符指定权限: -
r:读 -
w:写 -
x:执行
因此,我们为组添加写权限,可以执行以下命令:
[root@rocky08-host ~]# chmod g+w aiops.txt
[root@rocky08-host ~]# ls -l aiops.txt
-rw-rw-r--. 1 root root 0 4月 27 16:10 aiops.txt
删除其他用户的读权限,可以执行以下命令:
[root@rocky08-host ~]# chmod o-r aiops.txt
[root@rocky08-host ~]# ls -l aiops.txt
-rw-rw----. 1 root root 0 4月 27 16:10 aiops.txt
权限是以四位 0 到 7 的八进制数字存储的,每个权限对应一个 0 到 7 的数字:
字符 | 八进制 | 描述 |
---|---|---|
-rwx-r-x-r-- | 0754 | User:读、写、执行;Group:读、执行;Others:读 |
-rw-r----- | 0640 | User:读、写;Group:读;Others:无 |
-r-------- | 0400 | User:读;Group:无;Others:无 |
-
无权限:0 -
执行:2^0=1 -
写:2^1=2 -
读:2^2=4
rwx = 4 + 2 + 1 = 7
rw- = 4 + 2 =6
r-- = 4
--- = 0
我们可以通过数字配置权限:
[root@rocky08-host ~]# chmod 0755 aiops.txt
[root@rocky08-host ~]# ls -l aiops.txt
-rwxr-xr-x. 1 root root 0 4月 27 16:10 aiops.txt
[root@rocky08-host ~]# chmod 0640 aiops.txt
[root@rocky08-host ~]# ls -l aiops.txt
-rw-r-----. 1 root root 0 4月 27 16:10 aiops.txt
[root@rocky08-host ~]# chmod 0600 aiops.txt
[root@rocky08-host ~]# ls -l aiops.txt
-rw-------. 1 root root 0 4月 27 16:10 aiops.txt
12.2 umask 介绍
如前所述,权限的默认值是由 umask 设置的:
[root@rocky08-host ~]# umask
0022
所有新创建的文件都没有执行权限。
当 umask 为 “0022”,也就是 Linux 的默认值时,不会对 Groups 和 Others 分配写权限。
虽然不建议修改 umask 的值,但我们可以试一试,了解它是如何工作的。从权限最大的 umask (0000) 开始,它会默认为新创建的文件分配所有的读写权限:
[root@rocky08-host ~]# umask 0000
[root@rocky08-host ~]# touch aiops2.txt
[root@rocky08-host ~]# ls -l aiops2.txt
-rw-rw-rw-. 1 root root 0 4月 27 16:48 aiops2.txt
现在我们对 Groups 和 Others 分配最严格 (最小) 的权限:
[root@rocky08-host ~]# umask 0066
[root@rocky08-host ~]# touch aiops3.txt
[root@rocky08-host ~]# ls -l aiops3.txt
-rw-------. 1 root root 0 4月 27 16:49 aiops3.txt
umask 0066 和 0077 的效果是相同的:
[root@rocky08-host ~]# umask 0077
[root@rocky08-host ~]# touch aiops4.txt
[root@rocky08-host ~]# ls -l aiops4.txt
-rw-------. 1 root root 0 4月 27 16:49 aiops4.txt
如果使用大于 7 的数字,则会报错,因为它是一组八进制数:
[root@rocky08-host ~]# umask 0088
-bash: umask: 0088: octal number out of range
做完了这些测试,别忘记把 umask 改回系统默认值:
[root@rocky08-host ~]# umask 0022
12.3 修改文件所有权
chown 和 chgrp 命令可以修改文件或目录的所有权。为了演示这两个命令,我们进入 /var/tmp/
目录,并在其中创建 football 和 basketball 两个目录:
[root@rocky08-host ~]# cd /var/tmp/
[root@rocky08-host tmp]# mkdir basketball football
[root@rocky08-host tmp]# ls -l
total 8
drwxr-xr-x. 2 root root 4096 Apr 27 17:06 basketball
drwxr-xr-x. 2 root root 4096 Apr 27 17:06 football
接下来创建 football 和 basketball 组:
[root@rocky08-host tmp]# groupadd basketball
[root@rocky08-host tmp]# groupadd football
有了目录和组,使用 chgrp 命令修改目录的属组:
[root@rocky08-host tmp]# chgrp basketball basketball/
[root@rocky08-host tmp]# chgrp football football/
[root@rocky08-host tmp]# ls -l
total 8
drwxr-xr-x. 2 root basketball 4096 Apr 27 17:06 basketball
drwxr-xr-x. 2 root football 4096 Apr 27 17:06 football
再创建两个用户:curry 和 messi,并把它们分别添加到 basketball 和 football 组中:
[root@rocky08-host tmp]# useradd curry
[root@rocky08-host tmp]# useradd messi
[root@rocky08-host tmp]# usermod -aG basketball curry
[root@rocky08-host tmp]# usermod -aG football messi
[root@rocky08-host tmp]# groups curry
curry : curry basketball
[root@rocky08-host tmp]# groups messi
messi : messi football
现在,我们在它们的属组目录中创建个人目录:
[root@rocky08-host tmp]# mkdir basketball/personal-curry
[root@rocky08-host tmp]# ls -l basketball/
total 4
drwxr-xr-x. 2 root root 4096 Apr 27 17:17 personal-curry
[root@rocky08-host tmp]# mkdir football/personal-messi
[root@rocky08-host tmp]# ls -l football/
total 4
drwxr-xr-x. 2 root root 4096 Apr 27 17:17 personal-messi
使用 chown 修改目录的所有者:
[root@rocky08-host tmp]# chown curry basketball/personal-curry/
[root@rocky08-host tmp]# ls -l basketball/
total 4
drwxr-xr-x. 2 curry root 4096 Apr 27 17:17 personal-curry
[root@rocky08-host tmp]# chgrp curry basketball/personal-curry/
[root@rocky08-host tmp]# ls -l basketball/
total 4
drwxr-xr-x. 2 curry curry 4096 Apr 27 17:17 personal-curry
chown 命令也可以同时修改所有者和属组:
[root@rocky08-host tmp]# chown messi:messi football/personal-messi/
[root@rocky08-host tmp]# ls -l football/
total 4
drwxr-xr-x. 2 messi messi 4096 Apr 27 17:17 personal-messi
如果要修改目录中的所有文件和目录所有权 ,可以使用 chown -R 命令递归修改。我们复制一些文件来演示这个操作:
[root@rocky08-host tmp]# cp -rv /usr/share/doc/ansible football/personal-messi/
'/usr/share/doc/ansible' -> 'football/personal-messi/ansible'
'/usr/share/doc/ansible/CHANGELOG-v2.9.rst' -> 'football/personal-messi/ansible/CHANGELOG-v2.9.rst'
'/usr/share/doc/ansible/PKG-INFO' -> 'football/personal-messi/ansible/PKG-INFO'
'/usr/share/doc/ansible/README.rst' -> 'football/personal-messi/ansible/README.rst'
[root@rocky08-host tmp]# ls -l football/personal-messi/
total 4
drwxr-xr-x. 2 root root 4096 Apr 27 17:24 ansible
[root@rocky08-host tmp]# ls -l football/personal-messi/ansible/
total 288
-rw-r--r--. 1 root root 277187 Apr 27 17:24 CHANGELOG-v2.9.rst
-rw-r--r--. 1 root root 7724 Apr 27 17:24 PKG-INFO
-rw-r--r--. 1 root root 5175 Apr 27 17:24 README.rst
[root@rocky08-host tmp]# chown -R messi:messi football/personal-messi/ansible/
[root@rocky08-host tmp]# ls -l football/personal-messi/ansible/
total 288
-rw-r--r--. 1 messi messi 277187 Apr 27 17:24 CHANGELOG-v2.9.rst
-rw-r--r--. 1 messi messi 7724 Apr 27 17:24 PKG-INFO
-rw-r--r--. 1 messi messi 5175 Apr 27 17:24 README.rst
12.4 特殊权限
在讨论权限结构时,我们提到过可应用于文件和目录的特殊权限。在本节中,我们对它们进行详细讨论。首先是 suid (Set-UID) 和 sgid (Set-GID)。
12.4.1 suid
Set-UID 应用于文件和目录:
-
Set-UID 权限应用于文件:应用于可执行文件,其他用户能够以该文件所有者的权限执行它。 -
Set-UID 权限应用于目录:没有影响。
我们来查看一个带有 Set-UID 权限的可执行文件:
[root@rocky08-host ~]# ls -l /usr/bin/passwd
-rwsr-xr-x. 1 root root 33544 Mar 15 2021 /usr/bin/passwd
passwd 命令需要 root 权限来修改 /etc/shadow
文件中的 Hash 值。
chmod u+s 命令用于添加 Set-UID 权限:
[root@rocky08-host ~]# touch suidtest
[root@rocky08-host ~]# ls -l suidtest
-rw-r--r--. 1 root root 0 Apr 27 17:39 suidtest
[root@rocky08-host ~]# chmod u+s suidtest
[root@rocky08-host ~]# ls -l suidtest
-rwSr--r--. 1 root root 0 Apr 27 17:39 suidtest
谨慎以 root 身份为文件分配 suid 权限,因为如果该文件对其他用户有写权限,那么任何用户都能修改文件内容,并以 root 用户的身份执行该文件。
12.4.2 sgid
Set-GID 应用于文件和目录:
-
Set-GID 权限应用于文件:应用于可执行文件,其他用户将以该文件属组的权限执行它。 -
Set-GID 权限应用于目录:在该目录下创建的新文件的属组将继承该目录的属组。
我们来查看一个带有 Set-GID 权限的可执行文件:
[root@rocky08-host ~]# ls -l /usr/bin/write
-rwxr-sr-x. 1 root tty 21272 Oct 14 2021 /usr/bin/write
可以使用 chmod g+s 命令为属组添加 Set-GID 权限:
[root@rocky08-host ~]# touch sgidtest
[root@rocky08-host ~]# chmod g+s sgidtest
[root@rocky08-host ~]# ls -l sgidtest
-rw-r-Sr--. 1 root root 0 Apr 27 18:02 sgidtest
我们再演示目录的 Set-GID:
[root@rocky08-host ~]# cd /var/tmp/
[root@rocky08-host tmp]# ls -l
total 8
drwxr-xr-x. 3 root basketball 4096 Apr 27 17:17 basketball
drwxr-xr-x. 3 root football 4096 Apr 27 17:17 football
[root@rocky08-host tmp]# chmod g+s basketball
[root@rocky08-host tmp]# ls -l
total 8
drwxr-sr-x. 3 root basketball 4096 Apr 27 17:17 basketball
drwxr-xr-x. 3 root football 4096 Apr 27 17:17 football
[root@rocky08-host tmp]# touch basketball/cba
[root@rocky08-host tmp]# ls -l basketball/cba
-rw-r--r--. 1 root basketball 0 Apr 27 18:07 basketball/cba
[root@rocky08-host tmp]# touch football/csl
[root@rocky08-host tmp]# ls -l football/csl
-rw-r--r--. 1 root root 0 Apr 27 18:09 football/csl
可以看到,在对目录应用 Set-GID 后,它们显示了组的 s
权限。另外,当在设置了 Set-GID 的目录中创建新文件时,文件的属组与父目录的属组是一样的。通过这种方式,我们能够确保正确分配了组权限。
12.4.3 sticky bit
最后一个要讨论的特殊权限是 sticky bit。它的作用很简单,且只对目录有影响:当用户在一个有 sticky bit 权限的目录中创建文件时,只有该用户或 root 用户可以编辑或删除该文件。
我们来看一个例子:
[root@rocky08-host tmp]# ls -ld /tmp/
drwxrwxrwt. 4 root root 4096 Apr 27 18:12 /tmp/
使用 chmod o+t 命令添加 stick bit 权限:
[root@rocky08-host ~]# cd /var/tmp/
[root@rocky08-host tmp]# ls -l
total 8
drwxr-sr-x. 3 root basketball 4096 Apr 27 18:07 basketball
drwxr-xr-x. 3 root football 4096 Apr 27 18:09 football
[root@rocky08-host tmp]# chmod o+t basketball
[root@rocky08-host tmp]# ls -l
total 8
drwxr-sr-t. 3 root basketball 4096 Apr 27 18:07 basketball
drwxr-xr-x. 3 root football 4096 Apr 27 18:09 football
我们把 messi 用户加入 basketball 组,并授予 basketball 组对 /var/tmp/basketball
目录的写权限。然后我们使用 curry 用户在 basketball 目录中创建一个文件,并尝试用 messi 用户删除该文件:
[root@rocky08-host tmp]# usermod -aG basketball messi
[root@rocky08-host tmp]# chmod g+w basketball
[root@rocky08-host tmp]# ls -l
total 8
drwxrwsr-t. 3 root basketball 4096 Apr 27 18:07 basketball
drwxr-xr-x. 3 root football 4096 Apr 27 18:09 football
[root@rocky08-host tmp]# su - curry
[curry@rocky08-host ~]$ cd /var/tmp/basketball/
[curry@rocky08-host basketball]$ touch stickbittest
[curry@rocky08-host basketball]$ exit
logout
[root@rocky08-host tmp]# su - messi
[messi@rocky08-host ~]$ cd /var/tmp/basketball/
[messi@rocky08-host basketball]$ ls -l stickbittest
-rw-rw-r--. 1 curry basketball 0 Apr 27 18:19 stickbittest
[messi@rocky08-host basketball]$ rm -f stickbittest
rm: cannot remove 'stickbittest': Operation not permitted
特殊权限的数值为:suid=4;sgid=2;sticky bit=1。
这些是 Linux 中权限管理的基础知识,熟悉本章内容,有助你规避系统的安全问题。