vlambda博客
学习文章列表

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 = 7rw- = 4 + 2 =6r-- = 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 ~]# umask0022

所有新创建的文件都没有执行权限。

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 -ltotal 8drwxr-xr-x. 2 root root 4096 Apr 27 17:06 basketballdrwxr-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 -ltotal 8drwxr-xr-x. 2 root basketball 4096 Apr 27 17:06 basketballdrwxr-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 currycurry : curry basketball[root@rocky08-host tmp]# groups messimessi : messi football

现在,我们在它们的属组目录中创建个人目录:

[root@rocky08-host tmp]# mkdir basketball/personal-curry[root@rocky08-host tmp]# ls -l basketball/total 4drwxr-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 4drwxr-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 4drwxr-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 4drwxr-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 4drwxr-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 4drwxr-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 -ltotal 8drwxr-xr-x. 3 root basketball 4096 Apr 27 17:17 basketballdrwxr-xr-x. 3 root football 4096 Apr 27 17:17 football[root@rocky08-host tmp]# chmod g+s basketball[root@rocky08-host tmp]# ls -ltotal 8drwxr-sr-x. 3 root basketball 4096 Apr 27 17:17 basketballdrwxr-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 -ltotal 8drwxr-sr-x. 3 root basketball 4096 Apr 27 18:07 basketballdrwxr-xr-x. 3 root football 4096 Apr 27 18:09 football[root@rocky08-host tmp]# chmod o+t basketball[root@rocky08-host tmp]# ls -ltotal 8drwxr-sr-t. 3 root basketball 4096 Apr 27 18:07 basketballdrwxr-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 -ltotal 8drwxrwsr-t. 3 root basketball 4096 Apr 27 18:07 basketballdrwxr-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]$ exitlogout[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 stickbittestrm: cannot remove 'stickbittest': Operation not permitted

特殊权限的数值为:suid=4;sgid=2;sticky bit=1。

这些是 Linux 中权限管理的基础知识,熟悉本章内容,有助你规避系统的安全问题。