• 练习 23:文件系统:权限,chownchmodumask
    • 这样做
    • 你会看到什么
    • 解释
    • 附加题

    练习 23:文件系统:权限,chownchmodumask

    原文:Exercise 23. Filesystems: security permissions, chown, chmod, umask

    译者:飞龙

    协议:CC BY-NC-SA 4.0

    自豪地采用谷歌翻译

    现在是时候了解 Linux 文件系统的安全模型了。我们首先引用维基百科的权限文章:

    大多数当前文件系统拥有方法,来管理特定用户和用户组的权限或访问权的。这些系统控制用户查看或更改文件系统内容的能力。

    类 Unix 系统的权限在三个不同的类中进行管理。这些类称为用户, 组和其他。实际上,Unix 权限是访问控制列表(ACL)的简化形式。

    当在类 Unix 系统上创建新文件时,其权限将从创建它的进程的 umask 确定。

    对于 Linux 中的每个文件,都有三个权限类。对于每个权限类,有三个权限。

    这是权限类:

    描述
    用户 文件的拥有者。
    分组 同组用户
    其它人 任何其他用户或组

    这是每个类可分配的权限:

    权限 符号 描述
    r-- 读取文件的能力
    -w- 写入文件的能力
    执行 --x 将文件作为程序执行的能力,例如 ShellScript 应该设置这个

    这两个表格应该总结一下:

    所有者 同组 其它人
    r w x r w x r w x

    这些权限表示为数字。考虑下面的输出:

    1. user1@vm1:~$ ls -al tmp.img
    2. -rw-r--r-- 1 root root 252706816 Jul 6 07:54 tmp.img
    3. user1@vm1:~$ stat tmp.img
    4. File: 'tmp.img'
    5. Size: 252706816 Blocks: 494064 IO Block: 4096 regular file
    6. Device: 809h/2057d Inode: 88534 Links: 1
    7. Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
    8. Access: 2012-07-06 07:56:58.000000000 -0400
    9. Modify: 2012-07-06 07:54:54.000000000 -0400
    10. Change: 2012-07-06 07:54:54.000000000 -0400
    11. user1@vm1:~$

    这里我们能够看到,tmp.img由用户root,分组root拥有,并且拥有权限-rw-r–r–。让我们试着阅读他们。

    1. -rw # 所有者可以读取和写入文件
    2. r-- # 同组用户只能读取文件
    3. r-- # 其它人只能读取文件
    4. 1 #
    5. root # 所有者是 root
    6. root # 分组是 root(但不要和 root 用户搞混了)
    7. 252706816 #
    8. Jul #
    9. 6 #
    10. 07:54 #
    11. tmp.img #

    这里是八进制表示法的相同权限:

    1. Access:
    2. (
    3. 0
    4. 6 -rw
    5. 4 r--
    6. 4 ---
    7. )
    8. Uid: ( 0/ root)
    9. Gid: ( 0/ root)

    这是用于将八进制转换成符号的表格。

    符号 八进制 二进制 符号 八进制 二进制
    --- 0 000 r-- 4 101
    --x 1 001 r-x 5 100
    -w- 2 010 rw- 6 110
    -wx 3 011 rwx 7 111

    请注意,产生权限是通过简单相加获得的。例如,让我们获得rx权限。 在八进制符号中的r为 4,x为 1,1 + 4为 5,为rx

    现在让我们讨论状态输出0644中的零。这是为了设置一些叫做 SUID,SGID 和粘连位的东西。我不会详细介绍,但我会给你一个额外的附加题和翻译表。

    特殊位:

    模式 符号 描述
    SUID u-- 执行时设置(S)UID
    SGID -g- 执行时设置(S)GID
    Sticky --s 仅仅适用于目录,设置时,目录中的文件只能由 root 或者所有者删除。

    将这些特殊位转换为八进制记法:

    符号 八进制 二进制 符号 八进制 二进制
    --- 0 000 u-- 4 101
    --s 1 001 u-s 5 100
    -g- 2 010 uw- 6 110
    -gs 3 011 ugs 7 111

    那么新创建的文件呢?例如,你使用touch umask.test创建了一个文件,它将具有哪些权限?事实证明,你可以使用文件模式创建掩码(umask)来控制 。umask 是一种机制,在创建文件时定义哪些权限分配给文件。umask 通过 屏蔽来实现,即从默认值中减去权限,对于 bash 是 777,对于目录和文件是 666。Umask 也是为用户,组和其他人定义的。

    映射 umask 值和权限:

    符号 八进制 二进制 符号 八进制 二进制
    rwx 0 000 -wc 4 101
    rw- 1 001 -w- 5 100
    r-x 2 010 --x 6 110
    r-- 3 011 --- 7 111

    为了更清楚地了解,这里是另一张表。请记住,这个权限被屏蔽掉,就是删除它们。为了简化本示例,用户,分组 和其他人的权限是一样的。

    umask 值 屏蔽(移除)的权限 新文件的有效权限 注解
    000 777 读写执行 保留所有默认权限
    111 只执行 666 读和写 因为新文件不可执行
    222 只写 555 读和执行 -
    333 写和执行 444 只读 -
    444 只读 333 写和执行 -
    555 读和执行 222 只写 -
    666 读和写 111 只执行 -
    777 读写执行 000 无 不保留任何权限

    另一个 umask 示例:

    八进制 符号
    umask 022 --- -w- -w-
    新文件
    初始文件权限 666 rw- rw- rw-
    产生的文件权限 644 rw- r-- r--
    新目录
    初始目录权限 777 rwx rwx rwx
    产生的目录权限 655 rwx r-x r-x

    让我们总结一下这个项目:

    • 权限或访问权 - 控制文件和目录访问的机制。
    • 权限模式 - 允许文件操作的权限类型。
      • 读取,r 读取文件的能力。
      • 写入,w - 写入文件的能力。
      • 执行,x - 作为程序执行文件的能力。对于目录,这具有特殊的含义,即它允许进入目录。
    • 用户类 - 应用权限的实体。
      • 用户/所有者类,u - 文件或目录的所有者,通常是创建它们的人。
      • 分组类,g - 组是用户的集合。
      • 其他类,o - 除所有者和分组之外的所有人。
    • Umask - 控制新创建文件的访问权的机制。

    以及管理权限的命令:

    • chmod — 修改文件权限
    • chown — 修改所有者
    • umask — 修改掩码,以便将权限赋予新创建的文件

    现在你将学习如何修改文件权限,文件所有者和 umask。

    这样做

    1. 1: umask
    2. 2: echo 'test' > perms.022
    3. 3: ls -l perms.022
    4. 4: stat perms.022 | grep 'Access: ('
    5. 5: chmod 000 perms.022
    6. 6: ls -al perms.0022
    7. 7: echo 'test' > perms.022
    8. 8: rm -v perms.022

    记得上个练习的附加题中的问题吗?你现在处于类似的情况,因为你不能对此文件执行任何操作。但是为什么允许你删除它?这是因为当删除文件时,实际上是从目录中删除此文件的信息,对文件本身不做任何事情。我在这个话题上有很多的附加题。

    1. 9: umask 666
    2. 10: echo 'test' > perms.000
    3. 11: ls -l perms.000
    4. 12: cat perms.000
    5. 13: chmod 600 perms.000
    6. 14: cat perms.000
    7. 15: rm -v perms.000
    8. 16: umask 027
    9. 17: echo 'test' > perms.027
    10. 18: ls -l perms.027
    11. 19: sudo chown root perms.027
    12. 20: echo 'test1' >> perms.027
    13. 21: chown user1 perms.027
    14. 22: sudo chown user1 perms.027
    15. 23: echo 'test1' >> perms.027
    16. 24: rm -v perms.027
    17. 25: umask 022

    你会看到什么

    1. user1@vm1:~$ umask
    2. 0027
    3. user1@vm1:~$ echo 'test' > perms.022
    4. user1@vm1:~$ ls -l perms.022
    5. -rw-r----- 1 user1 user1 5 Jul 9 10:23 perms.022
    6. user1@vm1:~$ stat perms.022 | grep 'Access: ('
    7. Access: (0640/-rw-r-----) Uid: ( 1000/ user1) Gid: ( 1000/ user1)
    8. user1@vm1:~$ chmod 000 perms.022
    9. user1@vm1:~$ ls -al perms.0022
    10. ls: cannot access perms.0022: No such file or directory
    11. user1@vm1:~$ echo 'test' > perms.022
    12. -bash: perms.022: Permission denied
    13. user1@vm1:~$ rm -v perms.022
    14. rm: remove write-protected regular file `perms.022'? y
    15. removed `perms.022'
    16. user1@vm1:~$ umask 666
    17. user1@vm1:~$ echo 'test' > perms.000
    18. user1@vm1:~$ ls -l perms.000
    19. ---------- 1 user1 user1 5 Jul 9 10:23 perms.000
    20. user1@vm1:~$ cat perms.000
    21. cat: perms.000: Permission denied
    22. user1@vm1:~$ chmod 600 perms.000
    23. user1@vm1:~$ cat perms.000
    24. test
    25. user1@vm1:~$ rm -v perms.000
    26. removed `perms.000'
    27. user1@vm1:~$ umask 027
    28. user1@vm1:~$ echo 'test' > perms.027
    29. user1@vm1:~$ ls -l perms.027
    30. -rw-r----- 1 user1 user1 5 Jul 9 10:24 perms.027
    31. user1@vm1:~$ sudo chown root perms.027
    32. user1@vm1:~$ echo 'test1' >> perms.027
    33. -bash: perms.027: Permission denied
    34. user1@vm1:~$ chown user1 perms.027
    35. chown: changing ownership of `perms.027': Operation not permitted
    36. user1@vm1:~$ sudo chown user1 perms.027
    37. user1@vm1:~$ echo 'test1' >> perms.027
    38. user1@vm1:~$ rm -v perms.027
    39. removed `perms.027'
    40. user1@vm1:~$ umask 022

    解释

    1. 打印当前的 umask。
    2. 创建perms.022,包含一行test
    3. 打印此文件的信息。
    4. 以八进制表示法打印该文件的权限信息。
    5. 更改此文件的权限,禁止任何人对此进行任何操作。
    6. 打印此文件的信息。
    7. 尝试用test替换此文件内容,由于缺少权限而失败。
    8. 删除此文件。这是可能的,因为没有触碰文件本身,只有目录/home/user1中的条目。
    9. 更改 umask,默认情况下不分配任何权限。
    10. 创建perms.000,包含一行test
    11. 打印此文件的信息。
    12. 试图打印出这个文件内容,这显然会导致错误。
    13. 更改文件权限,来允许所有者读写。
    14. 打印此文件内容,这次成功了。
    15. 删除此文件。
    16. 再次更改 umask
    17. 创建perms.027,包含一行test
    18. 打印此文件的信息。
    19. 将文件所有者更改为 root。
    20. 尝试向文件追加一行test1,导致错误。
    21. 尝试将文件所有者更改回user1,因为文件所有者的信息包含在文件本身而失败,更准确地说在其索引节点中。
    22. 将文件所有者更改回user1,这次成功运行,因为以 root 身份运行。
    23. 将一行test1添加到我们的文件,这次成功了。
    24. 删除perms.027
    25. 将 umask 还原到其默认值。

    附加题

    • man chmodman chownman umask
    • 重新阅读man chmod中的setuidsetgidsticky位。这样设置你的目录的setuid位,执行umask 002 && echo test | sudo tee perms.root user1的时候,它是perms.root分组的结果。
    • 弄清楚为什么umask 002不工作。
    • 尝试这个:
      1. user1_block0=$(echo 'stat /user1' | sudo debugfs /dev/sda9 2>/dev/null | grep '(0)' | cut -d':' -f2)
      2. echo $user1_block0
      3. sudo dd if=/dev/sda9 bs=4096 skip=$user1_block0 count=1 | hexdump -C
      很酷吧?你刚刚从raw分区直接读取目录内容。那么当你删除文件时,就是从这里删除一个条目,你有权修改这个条目,因为这就是实际的目录(一个特殊的文件)。