# 文件与目录的默认权限与隐藏权限

前面讲解过文件有若干的属性,读写执行等基本权限(rwx), 是否为目录(d)、文件(-)或则是链接(l)等属性,修改属性也可通过 chgrp、chown、chmod。

除了基本的 rwx 权限外,在传统的 ext2、3、4 文件系统下,还可以设置其他的系统隐藏属性, 可以使用 chattr 来设置,以 lsattr 来查看,最重要的属性就是可以设置不可修改的特性, 让连文件的拥有者都不能进行修改。

在安全机制方面特别的重要,但是在 CentOS7 中利用 xfs 作为预设文件系统, 该文件系统就不支持 chattr 参数了,仅有部分参数还有支持

# 文件预设权限 umask

umask:指定目前用户在建立文件或目录时候的默认权限

# 以数值形态显示
[mrcode@study tmp]$ umask
0002   # 与一般权限有关的是后面三个数字

# 还可以以符号来显示
[mrcode@study tmp]$ umask -S
u=rwx,g=rwx,o=rx
1
2
3
4
5
6
7

在数值形态下有 4 组,第一组是特殊权限用的,先不看,因此预设情况如下:

  • 文件

    没有可执行(x)权限、只有 rw 两个项目,也就是最大为 666 分 -rw-rw-rw-

  • 目录

    由于 x 与是否可以进入此目录有关,因此默认所有权限均开发,即 777 分 drwxrwxrwx

注意:umask 的分数指的是,该默认值需要 减掉 的权限!也就是需要从预设的权限中减掉

使用上面的示例来说明:

r、w、x 分别是 4、2、1 分。

002,也就是 others 的权限被拿掉了 2 也就是 w,那么权限如下:

建立文件时:预设 -rw-rw-rw-,减掉 2 变成 -rw-rw-r--
建立目录时:预设 drwxrwxrwx,减掉 2 变成 drwxrwxr-x
1
2
3
4
5
6

不信吗?可以实践看下

[mrcode@study tmp]$ umask
0002
[mrcode@study tmp]$ touch 123
[mrcode@study tmp]$ mkdir 456
[mrcode@study tmp]$ ls -ld 123 456
# 看这里属性,和上面推测的一模一样
-rw-rw-r--. 1 mrcode mrcode 0 Oct 13 22:13 123
drwxrwxr-x. 2 mrcode mrcode 6 Oct 13 22:15 456
1
2
3
4
5
6
7
8

# umask 的利用与重要性:专题制作

你和你同学在同一个目录下 /home/class 合作一个专题,那么有没有可能你制作的文件, 你的同学无法编辑?

如果 umask 设置为 0022 ,那么相当于 group 默认创建只有 r 属性,除了拥有者, 其他人只能读,不能写。所以需要修改 umask 的值

# 修改语法是 umask 后接数值
# 由于笔者的 centos 较新,默认已经是 002 的了,这里就更改回 022 来测试
[mrcode@study tmp]$ umask
0002
[mrcode@study tmp]$ umask 022   # 更改为 022
[mrcode@study tmp]$ umask
0022
[mrcode@study tmp]$ touch test3
[mrcode@study tmp]$ mkdir test4
[mrcode@study tmp]$ ll -d test[34]  # 使用正则来匹配 test3和4
# 可以看到 文件 group 和 ohters 已经没有了 w
-rw-r--r--. 1 mrcode mrcode 0 Oct 13 22:23 test3
drwxr-xr-x. 2 mrcode mrcode 6 Oct 13 22:23 test4
1
2
3
4
5
6
7
8
9
10
11
12
13

TIP

umask 对于新建文件与目录的默认权限很重要,这个概念可以用在任何服务器上面, 尤其是未来假设文件服务器(file server),如 SAMBA Server 或则是 FTP server 时, 牵涉到你的使用者是否能够将文件进一步利用的问题

原来在预设的情况下,身份不同默认值也是不同的,root 的 umask 默认是 022,一般账户是 002。 关于预设设定可以参考 /etc/bashrc 这个文件的内容,不过这里不建议修改该文件, 后续讲解 bash shell 环境参数配置中再详解

# 文件隐藏属性

除了基本的 9 个权限外,还有隐藏属性,而隐藏属性对系统有很大的帮助,尤其是在安全上面。

# chattr 配置文件隐藏属性

强调:在 ext2/3/4 中完全支持,而在 xfs 上部分支持

chattr [+-=][ASacdistu] 文件或目录名称
1
  • +:增加一个特殊参数,其他参数不变
  • -:移除一个特殊参数
  • =:设定为后面接的参数
  • A:若有存取此文件/目录时,它的访问时间 atime 将不会被修改
  • S:对文件的修改变成同步写入磁盘中,一般默认是异步写入(前面章节讲到过 sync)
  • a:该问价只能增加数据,不能删除也不能修改数据,只有 root 才能设置该属性
  • c:自动将此文件压缩,在读取的时候也将会自动解压缩,但是在存储的时候,会先压缩后再存储(对大文件似乎有用)
  • d:当 dump 程序被执行的时候,可使该标记的文件或目录不被 dump 备份
  • i:让文件不能被删除、改名、设置连接、写入或新增数据,完完全全就是只读文件了。只有 root 能设置该属性
  • s:当文件被删除时,将会被完全的移除这个硬盘空间,所以如果误删,就找不回来了
  • u:与 s 相反,删除后,其实数据还在磁盘中,可以用来救援该文件

注意:

  • 属性设置常见的是 a 与 i 的设置,而且很多设置值必须要 root
  • xfs 文件系统仅支持 AadiS 选项

实践练习

[root@study tmp]# cd /tmp/
[root@study tmp]# touch attrtest
# 添加 i 属性
[root@study tmp]# chattr +i attrtest
# 尝试删除,发现不能删除,连 root 也无法删除
[root@study tmp]# rm attrtest
rm: remove regular empty file ‘attrtest’? y
rm: cannot remove ‘attrtest’: Operation not permitted
[root@study tmp]# rm -rf attrtest
rm: cannot remove ‘attrtest’: Operation not permitted

# 移除 -i 属性
[root@study tmp]# chattr -i attrtest
[root@study tmp]# rm attrtest
rm: remove regular empty file ‘attrtest’? y
# 这次再删除就成功了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

个人觉得 +i 和 +a 属性最重要:

  • i:无法被更动
  • a:不能修改旧的数据,只能新增

那么 a 属性在后续的登录档(log file)这种登录日志类的场景就很适合了

# lsattr 显示文件因此属性

lsattr [-adR] 文件或目录
1
  • a:将隐藏文件的属性也秀出来
  • d:如果接的是目录,仅列出目录本身的属性而非目录内的文件名
  • R:连同子目录的数据也列出来
# 这里创建一个文件,然后观察他的特殊属性
[root@study tmp]# touch attrtest
[root@study tmp]# ll attrtest
-rw-r--r--. 1 root root 0 Oct 13 22:50 attrtest
[root@study tmp]# lsattr attrtest
# 发现是一片空白
---------------- attrtest
# 添加之后再观察
[root@study tmp]# chattr +aiS attrtest
[root@study tmp]# lsattr attrtest
--S-ia---------- attrtest
1
2
3
4
5
6
7
8
9
10
11

# 文件特殊权限 SUID、SGID、SBIT

除了前面的 9 个权限之外,还有特殊的权限,如下面两个目录

[mrcode@study ~]$ ls -ld /tmp/;ls -l /usr/bin/passwd
# 尾部多了一个 t
drwxrwxrwt. 38 root root 4096 Oct 16 21:37 /tmp/
# 拥有者里面多了一个 s
-rwsr-xr-x. 1 root root 27856 Aug  9 09:39 /usr/bin/passwd
1
2
3
4
5

s 与 t 这两个的权限与后续的 「系统的账户」及系统的程序(process)较为相关, 关于概念需要再后续两个章节讲完之后,才会了解,这里只需要知道 SUID、SGID 如何设定即可

# Set UID

当 s 标志出现在文件拥有者 x 权限上时,就被称为 Set UID,简称 SUID 特殊权限, 对于文件的特殊功能如下:

  • SUID 权限仅对二进制程序(binary program)有效
  • 执行者对于该程序需要具有 x 的可执行权限
  • 本权限仅在执行该程序的过程中有效(run-time)
  • 执行者将具有该程序拥有者(owner)的权限

比如:linux 中,所有的账户的密码都记录在 /etc/shadow 文件中,既然该文件仅有 root 可以修改,那么我自己的 mrcode 一般账户使用者能否自行修改自己的密码呢?

[mrcode@study ~]$ passwd
Changing password for user mrcode.
Changing password for mrcode.
(current) UNIX password:
1
2
3
4

使用如上命令,发现可以修改,那么: shadow 一般账户不能读取,为什么还能修改密码呢?(也就是间接的修改了 shadow 中的数据),这就是 SUID 的功能了。

  • mrcode 对于 /usr/bin/passwd 这个程序来说具有 x 权限的,表示 mrcode 能执行 passwd
  • passwd 的拥有者是 root 账户
  • mrcode 执行 passwd 的过程中,会暂时获得 root 的权限
  • /etc/shadow 就可以被 mrcode 所执行的 passwd 所修改

那么使用 cat 去读取 /etc/shadow 可以吗?通过查看 cat 的权限,会发现 cat 没有包含 SUID 特殊权限,就是为什么不能读取的原因

[mrcode@study ~]$ ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 27856 Aug  9 09:39 /usr/bin/passwd
[mrcode@study ~]$ ll /usr/bin/cat
-rwxr-xr-x. 1 root root 54080 Aug 20 14:25 /usr/bin/cat

1
2
3
4
5

TIP

SUID 仅可用在 binary program 上,不能用在 shell script 上面, 因为 shell script 只是将很多的 binary 执行档叫进来执行而已。

所以 SUID 的权限部分需要看脚本中执行的指令是否具有 SUID ,而不是脚本自身。 对目录页是无效的

# Set GID

s 在群组的 x 时称为 Set GID

[mrcode@study ~]$  ls -l /usr/bin/locate
-rwx--s--x. 1 root slocate 40520 Apr 11  2018 /usr/bin/locate
1
2

SGID 可以针对文件或目录来设置,针对文件来说有如下功能含义:

  • SGID 对二进制程序有用
  • 程序执行者对于该程序来说,需要具备 x 的权限
  • 执行者在执行的过程中将会获得该程序群组的支持

例如:/usr/bin/locate 这个程序可以搜索 /var/lib/mlocate/mlocate.db 文件内容, 权限如下

[root@study ~]# ll /usr/bin/locate /var/lib/mlocate/mlocate.db
-rwx--s--x. 1 root slocate   40520 411 2018 /usr/bin/locate
-rw-r-----. 1 root slocate 3468856 1013 15:36 /var/lib/mlocate/mlocate.db
1
2
3

如果使用 mrcode 账户去执行 locate 时,mrcode 将会取得 slocate 群组的支持; (这里有点懵逼,使用 locate -A /var/lib/mlocate/mlocate.db 没有报错,但是没有内容, 但是直接使用 ll /var/lib/mlocate/ 却提示没有权限,只能后续的课程讲了后才知道是什么意思了)

除了 binary program 外,SGID 还能用在目录上,当一个目录设置了 SGID 的权限后,将具有如下的功能:

  • 用户若对于此目录具有 r 与 x 的权限时,该用户能够进入此目录
  • 用户在此目录下的有效群组(effective group)将会变成该目录的群组
  • 用途:若用户在此目录下具有 w 的权限(可以新建文件),则使用者所建立的新文件,该新文件的群组与此目录的群组相同

SGID 对于项目开发来说非常重要,涉及到群组权限的问题。可以参考下后续的「情景模拟的案例」, 能加深一点了解

# Sticky Bit

Sticky Bit简称为 SBT ,目前只针对目录有效,对于文件没有效果了

作用是:当用户对于此目录具有 w、x 权限,即具有写入的权限时,当用户在该目录下简历文件或目录时, 仅有自己与 root 才有权利删除该文件

例如:mrcode 用户在 A 目录是具有 w 的权限(群组或其他人类型权限),这表示 mrcode 对该目录 内任何人简历的目录或则文件均可进行删除、更名、搬移等动作,但是将 A 目录加上了 SBIT 的权限时,则 mrcode 只能够针对自己建立的文件或目录进行删除、更名、搬移等动作,而无法删除他人的文件

TIP

这部分内容在后续章节「关于程序方面」的只是后,再回过头来看,才能明白讲的是什么

# SUID、SGID、SBIT 权限设定

可以使用数值权限更改方法来设置,他们代表的数值是:

  • SUID:4
  • SGID:2
  • SBIT:1

下面演示具体这个数值加载哪里

[root@study tmp]# cd /tmp/
[root@study tmp]# touch test
# -rwsr-xr-x 拥有者权限 rwx 都有分数为 7,后面的都是5,原本权限为 755
# 那么久在 755 前增加特殊权限数值即可
# 这里添加 SUID 的权限
[root@study tmp]# chmod 4755 test; ls -l test
-rwsr-xr-x. 1 root root 0 1016 22:16 test
1
2
3
4
5
6
7

下面再来演示几个

# 添加 SUID + SGID 权限
[root@study tmp]# chmod 6755 test; ls -l test
-rwsr-sr-x. 1 root root 0 1016 22:16 test

# 添加 SBIT
[root@study tmp]# chmod 1755 test; ls -l test
-rwxr-xr-t. 1 root root 0 1016 22:16 test

# 添加具有空的 SUID SGID 权限
# 这里出现了大写的 SST
[root@study tmp]# chmod 7666 test; ls -l test
-rwSrwSrwT. 1 root root 0 1016 22:16 test

1
2
3
4
5
6
7
8
9
10
11
12
13

上面最后一个例子出现了大写的三个特殊权限 S、S、T,这里是这样的,因为 666 的权限中 不包含 x 权限,所以当特殊权限出现在 x 中的时候(又不拥有 x)则会出现大写的,表示空。 SUID 表示该文件在执行的时候,具有文件拥有者的权限,但是文件拥有者都无法执行了, 哪里来的权限给其他人使用呢?

除了数值,还可以使用符号来处理:

  • SUID:u+s
  • SGID:g+s
  • SBIT:o+t
# 设置为 -rws--x--x
[root@study tmp]# chmod u=rwxs,go=x test; ls -l test
-rws--x--x. 1 root root 0 1016 22:16 test

# 在上面的权限基础上,增加 SGID 与 SBIT
[root@study tmp]# chmod g+s,o+t test; ls -l test
-rws--s--t. 1 root root 0 1016 22:16 test

1
2
3
4
5
6
7
8

# 观察文件类型 file

想知道某个文件的基本数据,例如属于 ASCII 或则是 data 文件、binary 、是否用到动态函数库(share library)等信息,可以使用 file 指令来检阅

# ASCII 文本文件
[root@study tmp]# file ~/.bashrc
/root/.bashrc: ASCII text

# 执行文件的数据就很多了,包括这个文件的 suid 权限、兼容于 intel x86-64 等级的硬件平台
# 使用的是 linux 核心 2.6.32 的动态函数库链接
[root@study tmp]# file /usr/bin/passwd
/usr/bin/passwd: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=471dad50eb96512f90dd9394adbd7513ae60f072, stripped

# data 文件
[root@study tmp]# file /var/lib/mlocate/mlocate.db
/var/lib/mlocate/mlocate.db: data

1
2
3
4
5
6
7
8
9
10
11
12
13

通过这个指令可以简单的判断文件的格式,包括判断使用 tar 文档是使用的哪一种压缩功能