# 文件与目录的默认权限与隐藏权限
前面讲解过文件有若干的属性,读写执行等基本权限(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
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
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
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
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] 文件或目录名称
+
:增加一个特殊参数,其他参数不变-
:移除一个特殊参数=
:设定为后面接的参数- 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
# 这次再删除就成功了
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] 文件或目录
- 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
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
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:
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
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
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 4月 11 2018 /usr/bin/locate
-rw-r-----. 1 root slocate 3468856 10月 13 15:36 /var/lib/mlocate/mlocate.db
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 10月 16 22:16 test
2
3
4
5
6
7
下面再来演示几个
# 添加 SUID + SGID 权限
[root@study tmp]# chmod 6755 test; ls -l test
-rwsr-sr-x. 1 root root 0 10月 16 22:16 test
# 添加 SBIT
[root@study tmp]# chmod 1755 test; ls -l test
-rwxr-xr-t. 1 root root 0 10月 16 22:16 test
# 添加具有空的 SUID SGID 权限
# 这里出现了大写的 SST
[root@study tmp]# chmod 7666 test; ls -l test
-rwSrwSrwT. 1 root root 0 10月 16 22:16 test
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 10月 16 22:16 test
# 在上面的权限基础上,增加 SGID 与 SBIT
[root@study tmp]# chmod g+s,o+t test; ls -l test
-rws--s--t. 1 root root 0 10月 16 22:16 test
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
2
3
4
5
6
7
8
9
10
11
12
13
通过这个指令可以简单的判断文件的格式,包括判断使用 tar 文档是使用的哪一种压缩功能