Linux 权限 101

了解如何控制用户对文件的访问权限是一项基本的系统管理技能。
156 位读者喜欢这篇文章。
Top 5 Linux pain points in 2017

Internet Archive Book Images。由 Opensource.com 修改。CC BY-SA 4.0

了解 Linux 权限以及如何控制哪些用户可以访问文件是系统管理的一项基本技能。

本文将介绍标准的 Linux 文件系统权限,深入探讨特殊权限,并以使用 umask 解释默认权限结束。

理解 ls 命令的输出

在我们讨论如何修改权限之前,我们需要知道如何查看它们。带有长列表参数 (-l) 的 ls 命令为我们提供了有关文件的很多信息。

$ ls -lAh
total 20K
-rwxr-xr--+ 1 root root    0 Mar  4 19:39 file1
-rw-rw-rw-. 1 root root    0 Mar  4 19:39 file10
-rwxrwxr--+ 1 root root    0 Mar  4 19:39 file2
-rw-rw-rw-. 1 root root    0 Mar  4 19:39 file8
-rw-rw-rw-. 1 root root    0 Mar  4 19:39 file9
drwxrwxrwx. 2 root root 4.0K Mar  4 20:04 testdir

为了理解这意味着什么,让我们将关于权限的输出分解为各个部分。这样可以更容易地单独引用每个部分。

查看上面输出中最后一行的每个组成部分

drwxrwxrwx. 2 root root 4.0K Mar  4 20:04 testdir
第 1 部分 第 2 部分 第 3 部分 第 4 部分 第 5 部分 第 6 部分 第 7 部分
d rwx rwx rwx  . root root

第 1 部分(左侧)显示了文件类型。

d 目录
- 普通文件
l 软链接

lsinfo 页面 包含不同文件类型的完整列表。

每个文件都有三种访问模式

  • 所有者
  • 群组
  • 所有其他用户

第 2、3 和 4 部分分别指用户、组和“其他用户”的权限。每个部分都可以包含 r(读取)、w(写入)和 x(可执行)权限的组合。

每个权限还被分配一个数值,这在谈论权限的八进制表示时非常重要。

权限 八进制值
读取 4
写入 2
执行 1

第 5 部分详细说明了任何其他访问方法,例如 SELinux 或文件访问控制列表 (FACL)。

方法 字符
没有其他方法  -
SELinux  .
FACL  +
任何方法的组合  +

第 6 和第 7 部分分别是所有者和组的名称。

使用 chown 和 chmod

chown 命令

chown(更改所有权)命令用于更改文件的用户和组所有权。

要将文件 foo 的用户和组所有权都更改为 root,我们可以使用以下命令

$ chown root:root foo
$ chown root: foo

运行命令时,用户后面跟一个冒号 (:) 会同时设置用户和组所有权。

要仅将文件 foo 的用户所有权设置为 root 用户,请输入

$ chown root foo

要仅更改文件 foo 的组所有权,请在组前面加上冒号

$ chown :root foo

chmod 命令

chmod(更改模式)命令控制文件所有者、组和所有其他既不是所有者也不是与该文件关联的组成员的用户的权限。

chmod 命令可以使用八进制(例如,755、644 等)和符号(例如,u+rwx、g-rwx、o=rw)格式设置权限。

八进制表示法为 read 分配 4 个“点”,为 write 分配 2 个点,为 execute 分配 1 个点。 如果我们想为用户分配 read 权限,我们将 4 分配给第一个位置,但如果我们想添加 write 权限,我们必须添加 2。如果我们想添加 execute,那么我们添加 1。 我们对每种权限类型都这样做:所有者、组和其他人。

例如,如果我们想为文件所有者分配 readwriteexecute,但仅为组成员和所有其他用户分配 readexecute,我们将使用八进制格式的 755。 这意味着所有者拥有所有权限位 (4+2+1),但组和其他人只有 4 和 1 (4+1)。

分解为:4+2+1=7; 4+1=5; 和 4+1=5。

如果我们想为文件所有者分配 readwrite,但仅为组成员和所有其他用户分配 read,我们可以按如下方式使用 chmod

$ chmod 644 foo_file

在下面的示例中,我们在不同的分组中使用符号表示法。 请注意,字母 ugo 代表 usergroupother。 我们将 ugo+-= 结合使用来添加、删除或设置权限位。

要将 execute 位添加到所有权权限集

$ chmod u+x foo_file

要从组成员中删除 readwriteexecute

$ chmod g-rwx foo_file

要将所有其他用户的权限设置为 readwrite

$ chmod o=rw

特殊位:设置 UID、设置 GID 和粘滞位

除了标准权限之外,还有一些特殊权限位,它们具有一些有用的好处。

设置用户 ID (suid)

在文件上设置 suid 后,操作将以文件所有者的身份执行,而不是运行文件的用户。 一个 很好的例子passwd 命令。 它需要设置 suid 位,以便更改密码以 root 权限运行。

$ ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10  2014 /bin/passwd

设置 suid 位的示例如下

$ chmod u+s /bin/foo_file_name

设置组 ID (sgid)

sgid 位类似于 suid 位,因为操作是在目录的组所有权下完成的,而不是在运行命令的用户下完成的。

使用 sgid 的一个例子是,如果多个用户在同一个目录下工作,并且在该目录中创建的每个文件都需要具有相同的组权限。 下面的示例创建了一个名为 collab_dir 的目录,设置了 sgid 位,并将组所有权更改为 webdev

$ mkdir collab_dir
$ chmod g+s collab_dir
$ chown :webdev collab_dir

现在,在目录中创建的任何文件都将具有 webdev 的组所有权,而不是创建文件的用户。

$ cd collab_dir
$ touch file-sgid
$ ls -lah file-sgid
-rw-r--r--. 1 root webdev 0 Jun 12 06:04 file-sgid

“粘滞”位

粘滞位表示只有文件的所有者才能删除该文件,即使组权限允许这样做。 此设置通常在公共或协作目录(例如 /tmp)中最有意义。 在下面的示例中,所有其他用户 权限集中 execute 列中的 t 表示已应用粘滞位。

$ ls -ld /tmp
drwxrwxrwt. 8 root root 4096 Jun 12 06:07 /tmp/

请记住,这不会阻止某人编辑该文件; 它只是阻止他们删除目录的内容。

我们使用以下命令设置粘滞位

$ chmod o+t foo_dir

您自己尝试在一个目录上设置粘滞位,并为其提供完整的组权限,以便多个用户可以读取、写入和执行该目录,因为他们在同一个组中。

从那里,以每个用户身份创建文件,然后尝试以其他用户身份删除它们。

如果一切配置正确,一个用户应该无法从其他用户那里删除用户。

请注意,也可以使用八进制格式设置这些位,其中 SUID=4,SGID=2,粘滞位=1。

$ chmod 4744
$ chmod 2644
$ chmod 1755

大写还是小写?

如果您正在设置特殊位,并且看到大写 ST 而不是小写(如我们到目前为止所看到的),那是因为底层执行位不存在。 为了演示,以下示例创建一个设置了粘滞位的文件。 然后我们可以添加/删除执行位来演示大小写更改。

$ touch file cap-ST-demo
$ chmod 1755 cap-ST-demo
$ ls -l cap-ST-demo
-rwxr-xr-t. 1 root root 0 Jun 12 06:16 cap-ST-demo

$ chmod o-x cap-X-demo
$ ls -l cap-X-demo
-rwxr-xr-T. 1 root root 0 Jun 12 06:16 cap-ST-demo

有条件地设置执行位

到目前为止,我们使用小写 x 设置了 execute 位,它可以在不提出任何问题的情况下进行设置。 我们还有另一个选择:使用大写 X 而不是小写将仅在权限组中已存在时才设置 execute 位。 这是一个很难解释的概念,但下面的演示将有助于说明它。 请注意,在此处尝试将 execute 位添加到组权限后,它不会被应用。

$ touch cap-X-file
$ ls -l cap-X-file
-rw-r--r--. 1 root root 0 Jun 12 06:31 cap-X-file
$ chmod g+X cap-X-file
$ ls -l cap-X-file
-rw-r--r--. 1 root root 0 Jun 12 06:31 cap-X-file

在这个类似的示例中,我们首先使用小写 x 将执行位添加到组权限,然后使用大写 X 为所有其他用户添加权限。 这次,大写 X 设置了权限。

$ touch cap-X-file
$ ls -l cap-X-file
-rw-r--r--. 1 root root 0 Jun 12 06:31 cap-X-file
$ chmod g+x cap-X-file
$ ls -l cap-X-file
-rw-r-xr--. 1 root root 0 Jun 12 06:31 cap-X-file
$ chmod g+x cap-X-file
$ chmod o+X cap-X-file
ls -l cap-X-file
-rw-r-xr-x. 1 root root 0 Jun 12 06:31 cap-X-file

理解 umask

umask 会屏蔽(或“阻止”)默认权限集中的位,以便定义文件或目录的权限。 例如,umask 输出中的 2 表示它正在阻止文件中的 write 位,至少默认情况下是这样。

不带任何参数使用 umask 命令可以让我们查看当前的 umask 设置。 有四列:第一列保留给特殊的 suid、sgid 或粘滞位,其余三列代表所有者、组和其他权限。

$ umask
0022

为了理解这意味着什么,我们可以使用 -S 执行 umask(如下所示)以获得屏蔽位的结果。 例如,由于第三列中的 2 值,write 位从组和其他部分中屏蔽掉; 只能为这些部分分配 readexecute

$ umask -S
u=rwx,g=rx,o=rx

要查看文件和目录的默认权限集是什么,让我们将 umask 设置为全零。 这意味着我们在创建文件时没有屏蔽任何位。

$ umask 000
$ umask -S
u=rwx,g=rwx,o=rwx

$ touch file-umask-000
$ ls -l file-umask-000
-rw-rw-rw-. 1 root root 0 Jul 17 22:03 file-umask-000

现在,当我们创建一个文件时,我们看到所有部分的默认权限都是 read (4) 和 write (2),这相当于八进制表示法中的 666。

我们可以对目录执行相同的操作,并看到其默认权限为 777。 我们需要在目录上使用 execute 位,以便我们可以遍历它们。

$ mkdir dir-umask-000
$ ls -ld dir-umask-000
drwxrwxrwx. 2 root root 4096 Jul 17 22:03 dir-umask-000/

结论

管理员可以通过许多其他方式来控制对系统上文件的访问。 这些权限是 Linux 的基础,我们可以建立在这些基本方面之上。 如果您的工作涉及到 FACL 或 SELinux,您会发现它们也建立在这些文件访问的第一条规则之上。

User profile image.
Alex Juarez 是 Rackspace 的首席工程师,已经在该公司工作了 11 年。 Alex 热衷于所有开源事物,以及培训和指导他人。作为 RHCA/RHCI,他完全有资格这样做。 Alex 曾在许多地区性和全国性的开源会议上发表演讲,分享知识并鼓励人们学习更多知识。

2 条评论

感谢这篇文章。 这是一个很好的提醒。

如果我有一个经常运行的 python 脚本,我通常会设置它的执行位,但是你不必设置它来做另一种选择,那就是
python ./somescript.py
一旦你了解了一些关于权限的知识,当收到一些消息,例如说保存文件无法完成或者找不到某个可执行文件时,你就会开始寻找权限问题。

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.