用户身份与权限-文件的权限

文章目录[x]
  1. 0.1:文件的基本权限
  2. 0.2:文件的特殊权限
  3. 0.3:chmod 命令
  4. 0.4:文件隐藏权限
  5. 0.5:文件访问控制列表(FACL)
  6. 0.6:su命令与sudo服务

Linux系统中,“一切皆是文件”。但是文件也是不同的,每个文件都有他们各自的“特点”,这些“特点”Linux使用了一套完整的属性描述,我们使用ll-i 命令就可以看到完整的文件属性

[root@Shinya ~]# ll -i Shinya.sh 
71480148 -rw-r--r--. 1 root root 594 Feb  7 14:35 Shinya.sh

1.inode索引节点编号:这是文件的唯一识别号码
2.文件类型与权限(共11位):第一位为文件类型标识字符,后面10位为文件权限描述
3.硬链接次数
4.文件所有者
5.文件所属组
6.文件大小:单位为Byte
7.文件Mtime:月 日 时:分
8.文件名

其中的文件类型,Linux使用了不同的标识字符来进行区分

- :file,普通文件
d :directory,目录文件
b :block device,块设备文件,例如硬盘,以块为单位访问
c :character device,字符设备文件,例如键盘,以字符为单位访问
l :symbolic link,符号链接文件,即软链接文件
p :pipe,管道文件
s :socket,套接字文件,用于两个进程通信

文件的基本权限

Linux中,一切的文件都有所有者和所有组,Linux系统里就好像是一个大房子,有好多的家庭,集体和人,文件就是一个个物品,人和团体肯定对他们有一定的所有权和支配权。这些权利被划分为许多部分和种类。

文件的基本权限
对文件最基本的权限是三个:r(read),w(write),x(execute)。读,写,执行。这被称为文件的基本权限

对普通文件(file)的这三种权限很好理解。r:可以读取文件的内容,w:可以改写文件的内容,x:如果是一个脚本文件,那么就可以运行它。 文件的rwx相对独立,拥有那个权限就可以做什么事

但是对于目录文件(directory),就不好理解了。r:可以读取目录文件中的文件列表,w:可以在目录中新增,删除,重命名文件,x:可以进入该目录中(但这仅仅从inode的理论上可以做到这些,实际组合起来各个权限并不独立):

只有目录的读权限,只能查看目录中文件的文件名(详细信息无法得到),不能创建文件或目录,不能切换进目录。
只有目录的写权限,不能查看目录中的文件信息,不能新建文件或目录,不能切换进目录
只有目录的执行权限,不能查看目录中的文件信息,不能新建文件或目录,只能切换进目录
有目录的读和写权限,只能查看目录中文件的文件名(详细信息无法得到),不能创建文件或目录,不能切换进目录
有目录的读和执行权限,可以查看目录中文件的文件名(详细信息无法得到),不能创建文件或目录,可以切换进目录
有目录的写和执行权限,不能查看目录中的文件信息,可以新建文件或目录,可以切换进目录

Linux对一个文件的权限描述对象分成了三个部分,分别对:文件所有者,文件所属组,其他用户,来进行描述。每一组都会对基础权限进行一次描述,其中,为了简洁,我们将r,w,x,换成数字,分别对应2的次方数,r=1,w=2,x=4.(这其实算是8进制)

权限分配		文件所有者		文件所属组		其他用户
权限项		读	写	执行	读	写	执行	读	写	执行
字符表示		r	w	x	r	w	x	r	w	x
数字表示		4	2	1	4	2	1	4	2	1

这样,假如说一个文件的基础权限是:所有者的权限是:r,w,x,所有组的权限是:r,x,其他用户的权限是:r,x。那么这个文件的权限就可以表示为:755. 在系统中就是下面这样。

[root@Shinya Desktop]# cd
[root@Shinya ~]# ll -a Desktop/
total 4
drwxr-xr-x.  2 root root    6 Sep 28 23:43 .

rwxr-xr-x:755

特别说一下,man中有时会有一种奇怪的权限称谓“search premission”,提前说好,这不是特别严谨的官方叫法,但是很有趣。这个“搜查权限”指的是,当文件权限的某个描述对象同时拥有齐全“rwx”这一组基础权限,就称它拥有了“search premission”搜查权限。也就是说,假如文件Shinya,它的文件所属主权限为:rwx,那么就可以称Shinya文件的属主拥有了对Shinya文件的搜查权限。就像是对文件有了很高的权限之后,随时都可以冲进文件的家门喊一声“FBI open the door!”,当FBI探员搜查它一样23333333333

文件的特殊权限

Linux中,由于复杂多变的生产环境,单纯的rwx基础权限已经不能满足我们的需求,所以出现了三种用来弥补基础权限不足的特殊权限,他们和基础权限可以一起使用。
这三种特殊权限是:SUID,SGID,SBIT

SUID(set user ID)
SUID是对二进制文件设置的特殊权限,可以让二进制文件的执行者临时拥有所属主对文件的权限。

Linux中,执行命令实际上是执行某个二进制文件,例如普通用户执行修改自己密码的命令,我们知道/etc/shadow 文件普通用户的权限是000,修改自己的密码就要修改shadow文件,那么普通用户是怎么做得到的呢

查看passwd 命令对应的二进制文件我们可以得到答案

[root@Shinya ~]# whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/share/man/man1/passwd.1.gz /usr/share/man/man5/passwd.5.gz
[root@Shinya ~]# ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jan 30 2014 /usr/bin/passwd

可以看到,passwd命令文件所属主的权限是:rws ,其中变成s 而不是x 的执行权限就代表设置了SUID权限

那么普通用户在执行passwd的时候,就会获取到root的权限,就可以实现修改自己的密码了
注意的是,所属主的x权限存在时,设置SUID后会变为“s”,但是所属主x 权限不存在或者文件不为二进制文件时,显示为“S”。其实“S”表示失效,文件连所属主都没有执行权限,或者文件根本不是可以执行的二进制文件,设置SUID自然无效。

SGID(set group ID)
SGID对二进制文件设置时,可以让二进制文件的执行者临时拥有所属组对文件的权限。对目录设置时,这个目录中所有的新文件都会继承这个目录的所有组。

Unix系统有一个设备文件/dev/kmem,是一个字符设备文件,里面存放了访问内核的数据,所以这个文件不能开放给普通用户读写,权限为:cr--r----- 1 root system 。但是早期使用ps等命令查看系统运行信息的时候需要查看内核信息,普通用户根本没有权限访问kmem文件。所以,ps的权限被设置成了这样:-r-xr-sr-x 1 bin system 。普通用户去执行ps命令的时候,会临时获得system组的权限(bin与root都属于sysytem组,所以root本身就有权限执行ps),也就可以读取到内核信息了。

实际环境中,达成相同的目的,设置SGID要比SUID安全,上面的例子就是这样做的。另外,如果所属组的执行权限是“S”,和SUID出现的情况一样,并且表示SGID设置无效

给目录设置SGID权限

[root@Shinya Shinya]# mkdir Shinya
[root@Shinya Shinya]# ll
total 0
drwxr-xr-x. 2 root root 6 Feb 11 15:33 Shinya
[root@Shinya Shinya]# chmod -R 777 Shinya/
[root@Shinya Shinya]# chmod -Rf g+s Shinya/
[root@Shinya Shinya]# ll
total 0
drwxrwsrwx. 2 root root 6 Feb 11 15:33 Shinya
[root@Shinya Shinya]# su - Shinya
Last login: Tue Feb 11 15:31:21 CST 2020 on pts/0
[Shinya@Shinya ~]$ cd Shinya/
[Shinya@Shinya Shinya]$ touch Shinya
[Shinya@Shinya Shinya]$ ll
total 0
-rw-rw-r--. 1 Shinya root 0 Feb 11 15:34 Shinya

设置SGID的目录中,新的文件会继承所属目录的所属组

SBIT(sticky bit)
SBIT:粘滞位,但是叫做保护位更加形象。他是设置在目录文件的其他用户执行权限位上的。设置了SBIT权限的目录,其中的文件只有其所属主可以进行删除

SBIT的权限,可以保护公共目录中上传的文件不会被其他用户删除(就像上传的作业233333,不会被别人进行盗用)。Linux中就有一个公共目录/temp/

drwxrwxrwt. 19 root root 4096 Feb 11 16:00 tmp

/temp/的权限给所有人开放,意味着理论上所有人可以进行其中文件的读写更改,但是其其他用户执行权限位为“t”。

[Shinya@Shinya tmp]$ ll
total 0
-rwx------. 1 Shinya Shinya 0 Feb 11 15:58 Shinya
-rwx------. 1 zzy zzy 0 Feb 11 16:00 zzy
[Shinya@Shinya tmp]$ rm -rf zzy
rm: cannot remove ‘zzy’: Operation not permitted

如果要删除别人的文件,操作会被制止

和之前一样,如果原本其他用户执行权限为空,设置SBIT后会显示为“T”,表示无效,因为没有目录执行权限,无法对其中的文件进行更改,自然设置无效。如果对一个其他用户执行权限存在的文本文件设置SBIT,会显示“t”,但是设置没有任何效果。

文件的基础权限和特殊权限,就组成了一套比较完整的文件权限,和rwx一样可以划为数字,特殊权限也一样可以。SUID=4,SGID=2,SBIT=1.把特殊权限放在第一位数字上,就组成了完整权限的四位描述数字。

例如,权限为:rwxrws--T,划为数字表示就是:3770

chmod 命令

chmod 命令
用于:更改指定文件的访问权限 格式:chmod [OPTION]…(MODE[,MODE]... FILE...)/(OCTAL-MODE FILE...)/(--reference=RFILE FILE...)

chmod:change the permissions mode of a file ,简称change mode。命令用于更改文件的权限,只有root用户和文件属主对自己所属文件进行更改时才能使用。chmod有三种更改权限的方式,指定符号标记,指定八进制数,指定参考文件

-c :仅在权限发生实际变化时显示操作信息
-f :不显示操作信息,操作失败也不显示报错信息
-v :显示操作信息
-R :递归操作,更改目录以及目录下所有子目录以及文件的权限
1.指定符号标记
指定符号标记: chmod [who] [+/-/=] [mode] [file]

who:指定对象,可以是:u(user)所属主,g(group)所属组,o(other)其他用户,a(all)所有用户
这一项如果没有指定则默认为“a”所有用户,并且who一次可以指定多个

+/-/= : 这是操作方式,+ 表示对指定对象添加权限,- 表示去除指定对象的权限,= 表示将指定对象的权限设置为(指定列表,覆盖原有权限列表)

mode:指定权限,可以是{rwxXst}集合中的一个或多个,也可以是{ugo}集合中的一个,或者是“-”
r:read,读权限 w:write,写权限 x :execute,执行权限
X:只有目标文件是可执行文件或目录文件时才追加 x 权限
s:在文件执行时将执行用户的ID设置为文件属所主/组 的ID
t:限制删除,粘滞位
u:文件所属主的权限列表 g:文件所属组的权限列表 o:文件其他用户的权限列表
- :空权限

file:指定目标文件,可以用空格隔开不同的文件来指定文件列表,可以使用通配符

实例:

[Shinya@Shinya ~]$ ll -d Shinya
total 0
drwxrwxr-x. 2 Shinya Shinya 66 Feb 13 20:54 Shinya
[Shinya@Shinya ~]$ ll Shinya/
total 0
-rw-rw-r--. 1 Shinya Shinya 0 Feb 13 20:53 file1
-rw-rw-r--. 1 Shinya Shinya 0 Feb 13 20:53 file2
-rw-rw-r--. 1 Shinya Shinya 0 Feb 13 20:53 file3

指定Shinya文件夹的权限为rwsr-x---,遍历操作

[Shinya@Shinya ~]$ chmod -R u=rws Shinya/
chmod: cannot access ‘Shinya/file1’: Permission denied
chmod: cannot access ‘Shinya/file2’: Permission denied
chmod: cannot access ‘Shinya/file3’: Permission denied

可以看到,操作失败了,查看Shinya目录的权限

[Shinya@Shinya ~]$ ll -d Shinya/
drwSrwxr-x. 2 Shinya Shinya 66 Feb 13 22:19 Shinya/

这是因为给Shinya目录设置了SUID权限,而Shinya是目录文件,于是设置所属主的rws变成了rwS,没了执行权限,无法进入目录,无法修改目录中文件的信息

正确操作:

[Shinya@Shinya ~]$ chmod -R u=rwx Shinya/
[Shinya@Shinya ~]$ chmod -R g=rx Shinya/
[Shinya@Shinya ~]$ chmod -R o=- Shinya/
[Shinya@Shinya ~]$ chmod u+s Shinya/*
[Shinya@Shinya ~]$ ll -d Shinya/
drwxr-x---. 2 Shinya Shinya 42 Feb 13 22:24 Shinya/
[Shinya@Shinya ~]$ ll Shinya/
total 0
-rwsr-x---. 1 Shinya Shinya 0 Feb 13 22:24 file1
-rwsr-x---. 1 Shinya Shinya 0 Feb 13 22:24 file2
-rwsr-x---. 1 Shinya Shinya 0 Feb 13 22:24 file3

将Shinya目录中的文件去除执行权限,再给其他用户添加 X 权限

[Shinya@Shinya ~]$ chmod -x Shinya/*
[Shinya@Shinya ~]$ ll Shinya/
total 0
-rwSr-----. 1 Shinya Shinya 0 Feb 13 22:24 file1
-rwSr-----. 1 Shinya Shinya 0 Feb 13 22:24 file2
-rwSr-----. 1 Shinya Shinya 0 Feb 13 22:24 file3
[Shinya@Shinya ~]$ chmod o=X Shinya/*
[Shinya@Shinya ~]$ ll Shinya/
total 0
-rwSr-----. 1 Shinya Shinya 0 Feb 13 22:24 file1
-rwSr-----. 1 Shinya Shinya 0 Feb 13 22:24 file2
-rwSr-----. 1 Shinya Shinya 0 Feb 13 22:24 file3

可以看到,这时文件因为没有任何执行权限,所以没有被识别成可执行文件,X 权限判定为不添加x权限

给其他用户添加 x 权限,再给所属主添加 X 权限

[Shinya@Shinya ~]$ chmod o+x Shinya/*
[Shinya@Shinya ~]$ ll Shinya/
total 0
-rwSr----x. 1 Shinya Shinya 0 Feb 13 22:24 file1
-rwSr----x. 1 Shinya Shinya 0 Feb 13 22:24 file2
-rwSr----x. 1 Shinya Shinya 0 Feb 13 22:24 file3
[Shinya@Shinya ~]$ chmod u=X Shinya/*
[Shinya@Shinya ~]$ ll Shinya/
total 0
---xr----x. 1 Shinya Shinya 0 Feb 13 22:24 file1
---xr----x. 1 Shinya Shinya 0 Feb 13 22:24 file2
---xr----x. 1 Shinya Shinya 0 Feb 13 22:24 file3

可以看出,只要文件有x权限,就会被判定为可执行文件,这就是Linux判定文本文件是否为可执行文件的规则

将shinya目录的其他用户权限设置为所属主的权限,把所属组权限去除所属主权限

[Shinya@Shinya ~]$ chmod o=u Shinya/
[Shinya@Shinya ~]$ ll -d Shinya/
drwxr-xrwx. 2 Shinya Shinya 42 Feb 13 22:24 Shinya/
[Shinya@Shinya ~]$ chmod g-u Shinya/
[Shinya@Shinya ~]$ ll -d Shinya/
drwx---rwx. 2 Shinya Shinya 42 Feb 13 22:24 Shinya/

权限减法:(r-x)-(rwx)=(---),有则减之无则加勉~

2.指定八进制数
指定八进制数:chmod [mode] [file]

mode:指定权限,这里完整的指定是四位八进制数,分别代表 [特殊权限][所属主][所属组][其他用户] 对应的权限。数字表示前面叙述过,不加赘述。
例如:rwsr-xrwT 代表 5756.

指定的时候可以进行省略,省略规则是:优先认为省略了前面的位数,优先匹配后面的位数。
例如:777 实际为:0777 , 4 实际为:0004 。

实例:

[Shinya@Shinya ~]$ ll
total 0
drwxrwxr-x. 2 Shinya Shinya 16 Feb 13 22:56 Shinya
-rw-rw-r--. 1 Shinya Shinya 0 Feb 13 22:56 zzy
[Shinya@Shinya ~]$ ll Shinya/
total 0
-rw-rw-r--. 1 Shinya Shinya 0 Feb 13 22:56 zzy
改变~/zzy 文件权限为 rws---r--
[Shinya@Shinya ~]$ chmod 4704 zzy
[Shinya@Shinya ~]$ ll zzy
-rws---r--. 1 Shinya Shinya 0 Feb 13 22:56 zzy
改变zzy文件权限为 ------r--
[Shinya@Shinya ~]$ chmod 4 zzy
[Shinya@Shinya ~]$ ll zzy
-------r--. 1 Shinya Shinya 0 Feb 13 22:56 zzy

这和 chmod o=r 相同

3.指定参考文件
指定参考文件:chmod --reference=[rfile] [file]

指定所有的文件或目录的权限全部更改为指定的参考文件的权限,参考文件可以是文件或目录

实例:

[Shinya@Shinya ~]$ ll
total 0
drwxrwxr-x. 2 Shinya Shinya 16 Feb 13 22:56 Shinya
-rwxrwxr--. 1 Shinya Shinya 0 Feb 13 22:56 zzy
[Shinya@Shinya ~]$ ll Shinya/
total 0
-rw-rw-r--. 1 Shinya Shinya 0 Feb 13 22:56 zzy

将~/zzy的权限改为~/Shinya/zzy的权限

[Shinya@Shinya ~]$ chmod --reference=Shinya/zzy zzy
[Shinya@Shinya ~]$ ll zzy
-rw-rw-r--. 1 Shinya Shinya 0 Feb 13 22:56 zzy

ps:文件所属主在任何时候都有对自己文件的写权限,也就是一定可以进行编辑。

[Shinya@Shinya ~]$ ll zzy
----------. 1 Shinya Shinya 0 Feb 13 22:56 zzy
[Shinya@Shinya ~]$ vim zzy
Shinya
[Shinya@Shinya ~]$ chmod 700 zzy
[Shinya@Shinya ~]$ cat zzy
Shinya

vim退出的时候必须“wq!”强制退出

补充
chmod永远不会改变符号链接的权限,这是chmod的调用原因,而且符号链接文件的权限永远不会使用(所以默认777),但是chmod会改变符号链接指向的文件的权限,但是如果指向文件是一个目录,在使用-R遍历目录时会忽略目录中出现的另外的符号链接。chmod如果用于更改符号链接文件指向的目录文件的权限时,需要使用不带参数的chmod,并在符号链接文件末尾加“/”,例如:Shinya是符号链接文件,指向了zzy这个目录文件,那么改变zzy目录文件的权限就要用 “chmod Shinya/”
umask(掩码)
文件在创建的时候都有自己默认的权限值,这个默认值是由/etc/profile (全局配置文件)文件和家目录下的 .bash_profile 或 .profile(个人配置文件)中的 umask 值决定。

默认文件权限值为:文件 666 (rw-rw-rw-),目录 777 (rwxrwxrwx)

不特殊设定个人配置文件的情况下,会执行/etc/profile 文件中的配置,查看其 umask 设定

if [ $UID -gt 199 ] && [ "`id -gn`" = "`id -un`" ]; then
umask 002
else
umask 022
fi

如果用户UID大于199,并且用户名和基本组名相同,则 umask 为 002 ,反之为 022.

有了 umask 值,新文件的权限计算方式为:
文件:666-002=(rw-rw-rw-)-(-------w-)=(rw-rw-r--)
目录:777-002=(rwxrwxrwx)-(-------w-)=(rwxrwxr-x)

umask可以使用 umask 命令进行临时指定

[Shinya@Shinya ~]$ umask 022
[Shinya@Shinya ~]$ touch zzy
[Shinya@Shinya ~]$ ll zzy
-rw-r--r--. 1 Shinya Shinya 0 Feb 13 23:45 zzy

666-022=644(rw-r--r--)

Linux中的文件颜色
# Attribute codes: 字符属性
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
#00无 01粗体 04下划线 05闪烁 07反转 08隐藏
# Text color codes: 字符颜色
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
#30黑 31红 32绿 33黄 34蓝 35粉红 36淡蓝 37白
# Background color codes: 字符背景色
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
#40黑 41红 42绿 43黄 44蓝 45粉红 46淡蓝 47白

NORMAL 00 # global default, although everything should be something. 普通文件 终端默认颜色
FILE 00 # normal file 普通文件 终端默认颜色
DIR 01;34 # directory 目录 粗体-蓝字
LINK 01;36 # symbolic link 符号链接 粗体-淡蓝字
# numerical value, the color is as for the file pointed to.)
FIFO 40;33 # pipe 管道API 黑底-黄字
SOCK 01;35 # socket 套接字API 粗体-粉红字
DOOR 01;35 # door 门API 粗体-粉红字
BLK 40;33;01 # block device driver 块设备驱动 粗体-黑底-黄字
CHR 40;33;01 # character device driver 字符设备驱动 粗体-黑底-黄字
ORPHAN 40;31;01 # symlink to nonexistent file 指向文件不存在的符号链接 粗体-黑底-红字

SETUID 37;41 # file that is setuid (u+s) 指定UID(SUID)的文件 红底-白字
SETGID 30;43 # file that is setgid (g+s) 指定GID(SGID)的文件 黄底-黑字
STICKY_OTHER_WRITABLE 30;42 # dir that is sticky and other-writable (+t,o+w) +t,o+w权限的文件 绿底-黑字(不常用)
OTHER_WRITABLE 34;42 # dir that is other-writable (o+w) and not sticky -t,o+w权限的文件 绿底-蓝字(不常用)
STICKY 37;44 # dir with the sticky bit set (+t) and not other-writable +t,o-w权限的文件 蓝底-白字(不常用)

# This is for files with execute permission:
EXEC 01;32 有执行权限的文件 粗体-绿字
#.cmd 01;32 # executables (bright green) .cmd可执行文件 粗体-绿字(亮)
#.exe 01;32 .exe文件 粗体-绿字
#.com 01;32 .com文件 粗体-绿字
#.btm 01;32 .btm文件 粗体-绿字
#.bat 01;32 .bat文件 粗体-绿字

.tar 01;31 # archives or compressed (bright red) .tar压缩文件 粗体-红字(亮)
.tgz 01;31 .tgz文件 粗体-红字
.arj 01;31 .arj文件 粗体-红字
.taz 01;31 .taz文件 粗体-红字
.lzh 01;31 .lzh文件 粗体-红字
.zip 01;31 .zip文件 粗体-红字
.z 01;31 .z文件 粗体-红字
.Z 01;31 .Z文件 粗体-红字
.gz 01;31 .gz文件 粗体-红字
.bz2 01;31 .bz2文件 粗体-红字
.deb 01;31 .deb文件 粗体-红字
.rpm 01;31 .rpm文件 粗体-红字
.jar 01;31 .jar文件 粗体-红字

# image formats
.jpg 01;35 .jpg图片 粗体-粉红字
.jpeg 01;35 .jpeg图片 粗体-粉红字
.gif 01;35 .gif图片 粗体-粉红字
.bmp 01;35 .bmp图片 粗体-粉红字
.pbm 01;35 .pbm 图片 粗体-粉红字
.pgm 01;35 .pgm图片 粗体-粉红字
.ppm 01;35 .ppm图片 粗体-粉红字
.tga 01;35 .tga图片 粗体-粉红字
.xbm 01;35 .xbm图片 粗体-粉红字
.xpm 01;35 .xpm图片 粗体-粉红字
.tif 01;35 .tif图片 粗体-粉红字
.tiff 01;35 .tiff图片 粗体-粉红字
.png 01;35 .png 图片 粗体-粉红字
.mov 01;35 .mov视频 粗体-粉红字
.mpg 01;35 .mpg视频 粗体-粉红字
.mpeg 01;35 .mpeg视频 粗体-粉红字
.avi 01;35 .avi视频 粗体-粉红字
.fli 01;35 .fli视频 粗体-粉红字
.gl 01;35 .gl视频 粗体-粉红字
.dl 01;35 .dl视频 粗体-粉红字
.xcf 01;35 .xcf视频 粗体-粉红字
.xwd 01;35 .xwd视频 粗体-粉红字

# audio formats
.flac 01;35 .flac音频 粗体-粉红字
.mp3 01;35 .mp3音频 粗体-粉红字
.mpc 01;35 .mpc音频 粗体-粉红字
.ogg 01;35 .ogg音频 粗体-粉红字
.wav 01;35 .wav音频 粗体-粉红字

这是大部分,系统当前shell配色使用 dircolors -p (print database)可以查看当前文件字体颜色数据库

文件隐藏权限

文件除了能够被查看到的权限,还有一些,被刻意隐藏起开的权限,这种权限默认情况下不能被用户发觉,也是因此,这些有些神秘的权限在某些时候可以保护Linux系统

chattr 命令
用于:设置文件的隐藏权限 格式:chattr [-RVf] [-+=AaCcDdeijsSu] [-v version] files…

chattr:change attribute(属性)。chattr只有root管理员才可以使用,它被用来更改存放在一些文件系统上的文件的特有属性

-V :输出chattr的操作信息,并输出chattr版本
-f :不输出操作信息
-R :递归操作
-v :设置文件系统的版本

更改属性需要用到{+-=}操作符中的一个,加在属性前面,+表示为指定对象添加隐藏权限,-表示去除指定对象的隐藏权限,=表示指定对象的隐藏权限列表(指定列表,覆盖原有权限列表)

属性/隐藏权限
可读写属性:
A:atime,设置了A属性的文件的atime不会被更改(不记录访问)
a:append only,设置了a属性的文件只能在追加模式下打开和写入数据。文件使用,只允许在这个文件末尾追加数据,不允许删除与修改数据。目录使用,只允许在目录中新建和修改文件,不允许删除文件
C:copy-on-write,设置了C属性的文件不会受“写时拷贝更新的影响”,C属性只能在支持“copy-on-write updates”的文件系统中启用
c:compress,设置了c属性的文件会被内核自动压缩到磁盘上,从此文件读取数据将返回未被压缩的数据,写入数据会先将数据压缩再写入到磁盘上。c属性在当前主流的Linux内核实现的ext2,ext3,ext4文件系统中不遵循
D:dirsync,设置了D属性的目录被修改时,修改会被同步写入到磁盘上,这相当于子文件应用了“dirsync”的挂载选项。D属性仅在Linux内核版本2.5.19及以上可用
d:dump,当dump执行时,设置了d属性的文件不会被dump备份
e:extent for mapping,有e属性的文件表示,文件正在使用扩展分区来映射磁盘上的块,这个属性可能不能被chattr删除
i:immutable,设置了i属性的文件不允许发生任何更改。对设置了i属性的文件来说,无法对这个文件进行删除,重命名,不能创建链接给这个文件,不能写入任何数据。设置了i属性的目录不允许对目录进行重命名,增加或删除目录中子文件的操作,当然也不能创建连接,但是可以对目录中现有文件进行编辑
j:journaled,当文件系统使用“data=ordered”或者“data=writeback”挂载选项时,设置了j属性的文件会将数据写入文件本身之前写入ext3,ext4的日志中。使用“data=journal”时,数据已经写入日志,所以这个属性不起作用。j属性只在文件系统挂载为ext3,ext4时才有用
s:zerod disk,设置了s属性的文件,在文件被删除时,会将文件原来的块写入0,以此确保文件不会被恢复。s属性在当前主流的Linux内核实现的ext2,ext3,ext4文件系统中不遵循
S:sync,设置了S属性的文件被修改时,修改会被同步到磁盘上,这相当于文件应用了“sync”的挂载选项
u:undelete,设置了u属性的文件,被删除的时候内容依然会被保存,以便今后有恢复的机会。u属性在当前主流的Linux内核实现的ext2,ext3,ext4文件系统中不遵循

只读属性:
E:compression Error,E属性被用于实验性补丁,来指明压缩文件有压缩错误,它可以被lsattr显示但是不能被chattr设置和修改
I:indexed,I属性被用于htree 代码,来指明目录正在使用散列树来建立索引,它可以被lsattr显示但是不能被chattr设置和修改
h:huge file,h属性表示该文件是以文件系统的块大小为单位来存储自己的块而不是扇区大小,这表明这个文件的大小/一次性读取 会超过2TB的大小,它可以被lsattr显示但是不能被chattr设置和修改
T:top directory,T属性的目录,它会被Orlov块分配器当作目录层次的顶层结构,这是对ext3,ext4文件系统的提示,表示该目录下的子目录不相关,因此文件系统进行块分配时应该有目的的分开。例如,在/home/目录设置这个属性就很合适,不同用户的家目录会被放在单独的块组中,如果没有设置这个属性,块分配器将尽可能地将子目录分配在一起
t:no tail-merging,t属性的文件,不会有在存储块的末尾存在与其他文件合并的块碎片,这个属性只能在支持末尾合并(tail-merging)的文件系统中启用。这个属性适合一些无法理解文件合并的应用,目前ext2,ext3不支持末尾合并
X:access raw content directly,X属性被用于实验性补丁,来指明可以直接访问压缩文件的原始内容,它可以被lsattr显示但是不能被chattr设置和修改
Z:dirty compressed file,Z属性被用于实验性补丁,来指明压缩文件是脏文件,它可以被lsattr显示但是不能被chattr设置和修改

lsattr 命令
用于:列出文件的隐藏属性 格式:lsattr [-RVadlv] [files...]

-a:列出所有文件,包括隐藏文件
-d:列出目录文件本身,而不是目录下的子文件
-R:递归操作
-V:输出lsattr版本
-v:显示文件版本
实例
immutable:
给一个权限正常的文件设置immutable隐藏权限

[root@Shinya ~]# lsattr -V Shinya.sh
lsattr 1.42.9 (28-Dec-2013)
---------------- Shinya.sh
[root@Shinya ~]# chattr -V +i Shinya.sh
chattr 1.42.9 (28-Dec-2013)
Flags of Shinya.sh set as ----i-----------
[root@Shinya ~]# lsattr -v Shinya.sh
18446744072795453182 ----i----------- Shinya.sh
[root@Shinya ~]# ll Shinya.sh
-rw-r--r--. 1 root root 594 Feb 7 14:35 Shinya.sh
[root@Shinya ~]# rm -rf Shinya.sh
rm: cannot remove ‘Shinya.sh’: Operation not permitted

一个权限正常的文件,但是连root管理员都无法删除

移除Shinya.sh文件的不可更改属性,即可进行删除操作

[root@Shinya ~]# chattr -i Shinya.sh
[root@Shinya ~]# lsattr Shinya.sh
---------------- Shinya.sh
[root@Shinya ~]# rm Shinya.sh
rm: remove regular file ‘Shinya.sh’? y
[root@Shinya ~]# ll Shinya.sh
ls: cannot access Shinya.sh: No such file or directory

给一个权限正常的目录设置immutable隐藏权限

[root@Shinya ~]# ll -d Shinya/
drwxr-xr-x. 2 root root 16 Feb 16 17:40 Shinya/
[root@Shinya ~]# ll Shinya/
total 4
-rw-r--r--. 1 root root 8 Feb 16 17:40 zzy
[root@Shinya ~]# cat Shinya/zzy
Shinya~
[root@Shinya ~]# chattr -V +i Shinya/
chattr 1.42.9 (28-Dec-2013)
Flags of Shinya/ set as ----i-----------
[root@Shinya ~]# vim Shinya/zzy
[root@Shinya ~]# cat Shinya/zzy
Shinya~
lalala~
[root@Shinya ~]# touch Shinya/file
touch: cannot touch ‘Shinya/file’: Permission denied
[root@Shinya ~]# rm -rf Shinya/zzy
rm: cannot remove ‘Shinya/zzy’: Permission denied

目录下无法添加和删除文件,但是可以编辑现有文件

append only:
使一个权限正常的文件只能进行追加操作

[root@Shinya ~]# ll Shinya.txt
-rw-r--r--. 1 root root 16 Feb 16 17:53 Shinya.txt
[root@Shinya ~]# cat Shinya.txt
Shinya is here~
[root@Shinya ~]# chattr -V +a Shinya.txt
chattr 1.42.9 (28-Dec-2013)
Flags of Shinya.txt set as -----a----------
[root@Shinya ~]# rm -rf Shinya.txt
rm: cannot remove ‘Shinya.txt’: Operation not permitted
[root@Shinya ~]# vim Shinya.txt
"Shinya.txt" E212: Can't open file for writing
[root@Shinya ~]# echo "zzy is here" >> Shinya.txt
[root@Shinya ~]# cat Shinya.txt
Shinya is here~
zzy is here

可以进行追加数据操作,但是不能编辑删改原有内容,也不能删除文件(使用vim即使不改动原有内容只进行追加内容也不行,只能用追加重定向符)

使用vim强制修改的话不会成功,但是因为vim使用了强制操作,会判断为意外,会对原文件进行备份,于是就有了这些命名奇怪的文件(名字带“~”表示临时/备份文件)

-rw-r--r--. 1 root root 28 Feb 16 19:54 Shinya.txt~
-rw-r--r--. 1 root root 28 Feb 16 19:55 Shinya.txx~
-rw-r--r--. 1 root root 28 Feb 16 19:55 Shinya.txy~
-rw-r--r--. 1 root root 28 Feb 16 19:54 Shinya.txz~

这个属性就常常用在日志文件中,防止黑客对日志文件动手脚,只允许追加日志文件的内容的话就没问题~

给一个权限正常的目录设置append only属性

[root@Shinya ~]# ll -d Shinya
drwxr-xr-x. 2 root root 16 Feb 16 17:40 Shinya
[root@Shinya ~]# ll Shinya
total 4
-rw-r--r--. 1 root root 16 Feb 16 17:43 zzy
[root@Shinya ~]# cat Shinya/zzy
Shinya~
[root@Shinya ~]# chattr -V +a Shinya
chattr 1.42.9 (28-Dec-2013)
Flags of Shinya set as -----a----------
[root@Shinya ~]# rm -rf Shinya
rm: cannot remove ‘Shinya/zzy’: Operation not permitted
[root@Shinya ~]# rm -rf Shinya/zzy
rm: cannot remove ‘Shinya/zzy’: Operation not permitted
[root@Shinya ~]# touch Shinya/Shinya
[root@Shinya ~]# echo "Shinya desi~" >> Shinya/Shinya
[root@Shinya ~]# ll Shinya
total 8
-rw-r--r--. 1 root root 13 Feb 16 20:02 Shinya
-rw-r--r--. 1 root root 8 Feb 16 19:59 zzy
[root@Shinya ~]# cat Shinya/Shinya
Shinya desi~
[root@Shinya ~]# echo "zzy desi~" > Shinya/Shinya
[root@Shinya ~]# cat Shinya/Shinya
zzy desi~
[root@Shinya ~]# echo "zzy~" >> Shinya/zzy
[root@Shinya ~]# cat Shinya/zzy
Shinya~
zzy~
[root@Shinya ~]# vim Shinya/zzy
E45: 'readonly' option is set (add ! to override)
[root@Shinya ~]# cat Shinya/zzy
lalalala~

目录和目录中的文件无法删除,只能增加文件,文件内容使用重定向符(不论追加还是覆盖)可以正常修改,但是使用vim进行编辑会报错,强制退出后也会修改成功,但是会被创建一些临时文件(莫名……)

-rw-r--r--. 1 root root 0 Feb 16 19:52 4913
-rw-r--r--. 1 root root 10 Feb 16 19:52 zzy
-rw-r--r--. 1 root root 13 Feb 16 19:52 zzy~
-rw-r--r--. 1 root root 4096 Feb 16 19:52 .zzy.swo
-rw-------. 1 root root 0 Feb 16 19:52 .zzy.swp
-rw-------. 1 root root 0 Feb 16 19:52 .zzy.swpx

文件访问控制列表(FACL)

不论是一般权限,特殊权限,还是隐藏权限,都是对特定的对象群设置的,对文件的属主,文件的所有组,特殊的文件,以至于所有人。但是如果我们需要对某个特殊的用户设置某项或者一些权限,比如某个用户既不是文件的属主,也不在文件的所属组中,但是对这个文件所需要的权限又比其他用户要多,就无法使用这些权限进行设置,这就需要使用文件访问控制列表进行设置。(VIP设置~)

setfacl 命令
用于:管理facl 格式: setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...

-m:modify,更改对象的facl
-M:mofify file=[file],从文件/标准输入读取facl来更改对象的facl
-x:remove,移除对象的facl
-X:removr file=[file],从文件/标准输入读取facl来移除对象的facl
-d:default,设置默认/缺省facl
--set:指定对象新的facl列表,原来列表将覆盖
--set-file=[file]:从文件/标准输入读取facl来指定对象新的facl列表,原来列表将覆盖
-b:remove all,删除所有扩展facl,基础facl将保留
-k:remove default,删除默认/缺省facl,若缺省不存在则忽略操作
-n:no-mask,不重新计算ACL-mask(默认ACL-mask会在设定后重新计算,除非已经规定)
--mask:重新计算ACL-mask,即使已经规定
--restore=[file]:恢复备份文件中的facl,这种机制可以恢复整个目录树结构的facl,此不能和除--test之外的参数一同使用
--test:测试模式,不会实际改变facl,但是可以将进行操作后的facl列出
-R:recursive,递归操作
-L:logical,逻辑操作,会跟踪所有符号链接文件(默认只跟踪文件,不跟踪目录)(会使用-R会忽略递归到的符号链接?)
-P:physical,自然操作,不会跟踪任何符号链接文件
--:标志命令行结束,后面的数据将被读取为文件名
-:出现在文件名位置时,将会从标准输入读取文件名

setfacl使用接收文件/标准输入的参数时,可以接受getfacl的输出,#注释,每一行一条规则

恢复整个Linux系统的facl:
getfacl -R / > backup.bak
setfacl -R --set-file=backup.bak / 或 setfacl --restore=backup.bak

在不支持ACL的文件系统上使用setfacl,stefacl会去修改文件权限位使其尽可能地匹配,如果没法完全匹配的话,会在尽力修改权限位的基础上发送错误报告

FACL规则
setfacl只有文件的属主和root管理员可以使用,来设置文件的FACL
一个文件创立之初,会有三条已经建立的FACL规则,这被称为基本ACL
一个文件的facl规则如果要运行正常,必须满足以下要求:

* The three base entries cannot be removed. There must be exactly one entry of each of these base entry types.
* Whenever an ACL contains named user entries or named group objects, it must also contain an effective rights mask.
* Whenever an ACL contains any Default ACL entries, the three Default ACL base entries (default owner, default group, and default others) must also exist.
* Whenever a Default ACL contains named user entries or named group objects, it must also contain a default effective rights mask.
To help the user ensure these rules, setfacl creates entries from existing entries under the following conditions:
* If an ACL contains named user or named group entries, and no mask entry exists, a mask entry containing the same permissions as the group entry is created. Unless the -n option is given, the permissions of the mask entry are further adjusted to include the union of all permissions affected by the mask entry. (See the -n option description).
* If a Default ACL entry is created, and the Default ACL contains no owner, owning group, or others entry, a copy of the ACL owner, owning group, or others entry is added to the Default ACL.
* If a Default ACL contains named user entries or named group entries, and no mask entry exists, a mask entry containing the same permissions as the default Default ACL's group entry is added. Unless the -n option is given, the permissions of the mask entry are further adjusted to include the union of all permissions affected by the mask entry. (See the -n option description).
——man 1 setfacl

*三条基本ACL规则必须存在,每个基本条目类型必须有一个条目。
*当ACL包含ACL-USER或ACL-GROUP时,必须包含有效的ACL-MASK
*当包含任何缺省ACL项时,三个缺省ACL基本项(缺省所有者、缺省组和缺省其他项)必须存在。
*当一个默认ACL包含Default-ACL-USER与Default-ACL-GROUP时,它还必须包含一个默认有效权限掩码(Default-ACL-MASK)。

为了帮助用户确保这些规则,setfacl按照以下条件下从现有条目创建新条目:
*如果ACL包含ACL-USER与ACL-GROUP,且不存在ACL-MASK,则创建包含与组项相同权限的掩码项。除非提供-n选项,否则将进一步调整掩码项的权限,以包括受掩码项影响的所有权限的并集。(参见-n选项描述)。
*如果创建了缺省ACL条目,并且缺省ACL不包含所有者、所属组或其他条目,则将ACL-USER-OBJ,ACL-GROUP-OBJ,ACL-OTHER的副本添加到缺省ACL。
*如果默认ACL包含Default-ACL-USER与Default-ACL-GROUP,且不存在Default-ACL-MASK,则添加与默认ACL的组项具有相同权限的掩码项。除非提供-n选项,否则将进一步调整掩码项的权限,以包括受掩码项影响的所有权限的并集。(参见-n选项描述)。

FACL格式
[d[efault]:] u[ser]:uid [:perms]         #指定用户权限,当UID未指定时,指定文件属主的权限
[d[efault]:] g[roup]:gid [:perms]        #指定组权限,当GID未指定时,指定文件所属组的权限
[d[efault]:] m[ask][:] [:perms]          #指定权限掩码
[d[efault]:] o[ther][:] [:perms]         #指定其他用户权限

UID和GID可以使用数字来指定,也可以使用名称。
perms域可以使用字符来指定权限,也可以使用八进制数

FACL由一系列Access Entry 组成,每一条Access Entry都定义了对文件的某种类别的某种操作权限。它由三个部分组成:Entry tag type,optional,premissions
Access Entry由Entry tag type定义了类别,分别有:

ACL-USER-OBJ            定义了文件所属主对文件的权限
ACL-USER                定义了额外用户对文件的权限
ACL-GROUP-OBJ           定义了文件所属组对文件的权限
ACL-GROUP               定义了额外组对文件的权限
ACL-MASK                定义了文件的权限掩码,这是ACL-USER,ACL-GROUP,ACL-GROUP-OBJ的权限范围
ACL-OTHER               定义了其他用户对文件的权限

用一个文件的FACL来举例说明:

[root@Shinya ~]# getfacl Shinya
# file: Shinya
# owner: root
# group: root
user::rwx
user:zzy:rw-
group::r-x
group:zzy:rw-
mask::rwx
other::r-x
user::rwx                ACL-USER-OBJ,表示文件属主root对文件有read,write,execute(search permission)权限
user:zzy:rw-             ACL-USER,表示zzy用户对文件有read,write的权限
group::r-x               ACL-GROUP-OBJ,表示文件所属组root的用户对文件有read,execute的权限
group:zzy:rw-            ACL-GROUP,表示zzy组的用户对文件有read,write的权限
mask:rwx                  ACL-MASK,表示权限掩码为:rwx
other:r-x                 ACL-OTHER,表示其他用户对文件有read,execute的权限

可以发现,上面的FACL都是由两个“:”区分成三个部分的,其中,第一个部分就是Entry tag type,这个字段定义了FACL的类别,对应关系如下:

user:ACL-USER-OBJ,ACL-USER
group:ACL-USER-OBJ,ACL-GROUP
mask:ACL-MASK
other:ACL-OTHER

ACL-USER和ACL-GROUP都是对额外用户以及组的权限定义,所以在第二部分就有对应的用户以及组了。而留空就指的是文件属主和所属组本身,也就是ACL-USER-OBJ和ACL-GROUP-OBJ了。这就好区分了

接下来来设置FACL,把新创建的Shinya文件的FACL设置为上面的样子

[root@Shinya ~]# ll -d Shinya/
drwxr-xr-x. 2 root root 6 Feb 17 22:45 Shinya/
[root@Shinya ~]# getfacl Shinya/
# file: Shinya/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
[root@Shinya ~]# setfacl -m u:zzy:rw-,group:zzy:rw Shinya/
[root@Shinya ~]# getfacl Shinya/
# file: Shinya/
# owner: root
# group: root
user::rwx
user:zzy:rw-
group::r-x
group:zzy:rw-
mask::rwx
other::r-x
[root@Shinya ~]# ll -d Shinya/
drwxrwxr-x+ 2 root root 6 Feb 17 22:45 Shinya/

设置FACL时,条目间使用“,”隔开

可以发现,变化如下:
1.设置了ACL-USER/ACL-GROUP之后ACL-MASK会对应出现
2.文件属性改变,权限位的最后一位从“.”变为“+”
3.文件权限改变,FACL中记录的文件所有组的权限为r-x,和修改前一样,而且也未修改ACL-GROUP-OBJ位,但是所属组的权限变为了rwx

首先解释第二条,本文开头说过,ll命令下的完整文件属性第二部分,“文件类型与权限”,后10位都是对文件权限的描述,其中的前9位都已经详细描述,这第十位,就是来描述文件是否人为设置了FACL,“.”表示未被设置,“+”表示被设置。
下来来解释另外两个变化,这两个变化与ACL-MASK有关

ACL-MASK
用上面的Shinya文件举例,文件的“file permission”为:rwxr-xr-x。其中可以很容易得出文件所属组的权限“group permission”为r-x,但是这只是在FACL不存在ACL-MASK值的时候的情况。如果FACL有ACL-MASK值,这三位所代表的就不是“group permission”了

依然用上面的实例举例子,为什么Shinya被设置了ACL-USER与ACL-GROUP之后会出现ACL-MASK,这是因为,ACL-MASK是ACL-USER,ACL-GROUP,ACL-GROUP-OBJ的权限范围,一旦设置ACL-USER或ACL-GROUP,默认情况下Linux系统就会自动重新计算ACL-MASK

上面的实例,ACL-USER:rw-,ACL-GROUP-OBJ:r-x,ACL-GROUP:rw-,于是,他们的最大值(并集)就是ACL-MASK的值:rwx。

ACL-MASK的值一旦出现,就会顶替“group permission”的值(这时使用chmod修改所属组的权限其实修改的是ACL-MASK!),所以这个时候所属组的权限依然为r-x,但是所属组权限位显示为rwx,root组的普通用户执行写权限就会被 permisson deny。所以才设置了FACL的文件就会有权限位最后一位的提示符变化,若为“+”,就在提示我们需要去使用getfacl查看文件的FACL来明确实际的权限情况

但是如果这时强行设置ACL-MASK的值低于它应有的最大值呢:

[root@Shinya ~]# setfacl -m mask::rw- Shinya/
[root@Shinya ~]# ll -d Shinya/
drwxrw-r-x+ 2 root root 6 Feb 17 22:45 Shinya/
[root@Shinya ~]# getfacl Shinya/
# file: Shinya/
# owner: root
# group: root
user::rwx
user:zzy:rw-
group::r-x #effective:r--
group:zzy:rw-
mask::rw-
other::r-x

可以看到,文件的“group permission”位的值改变成了掩码的值。这时查看文件的FACL,发现了一行有“effective”的提示

回顾掩码的作用,这时的ACL-MASK只有rw-,而ACL-GROUP-OBJ是r-x,掩码规定了权限最大值,所以ACL-GROUP-OBJ只能最多有r--的权限(取交集),于是就有了“effective permission”:“effective:r--”,虽然设置了r-x的权限,但是实际只能生效r--

Defaule FACL
以上所叙述的都是Access FACL(拓展FACL),下来来说说Default FACL(缺省FACL)

Default FACL是对一个目录设置的FACL,目录下的所有新文件都将继承父目录的Defaule FACL

现在新建一个Shinya目录,要求这个目录下将来出现的所有文件Shinya用户都有“search permission”

[root@Shinya ~]# mkdir Shinya
[root@Shinya ~]# ll -d Shinya/
drwxr-xr-x. 2 root root 6 Feb 18 03:14 Shinya/
[root@Shinya ~]# setfacl -d -m user:Shinya:rwx Shinya/
[root@Shinya ~]# getfacl Shinya/
# file: Shinya/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:Shinya:rwx
default:group::r-x
default:mask::rwx
default:other::r-x

可以看到,缺省FACL开头用“default”做了新的标记,表示他们都是缺省FACL,会一并继承给子文件(缺省FACL对当前目录文件是不生效的,掩码不会替代所属组的权限值)

并且一提,FACL有一定的简写法,user可以写成“u”,group写成“g”,other写成“o”,都没问题。设置缺省FACL时可以使用-d参数,也可以在FACL条目前加上“d:”。就例如上面的命令行,可以写成:“setfacl -m d:u:Shinya:rwx Shinya/”

在Shinya目录下新建文件查看FACL

[root@Shinya ~]# touch Shinya/zzy
[root@Shinya ~]# mkdir Shinya/Shinya
[root@Shinya ~]# getfacl Shinya/zzy
# file: Shinya/zzy
# owner: root
# group: root
user::rw-
user:Shinya:rwx #effective:rw-
group::r-x #effective:r--
mask::rw-
other::r--
[root@Shinya ~]# getfacl Shinya/Shinya/
# file: Shinya/Shinya/
# owner: root
# group: root
user::rwx
user:Shinya:rwx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:Shinya:rwx
default:group::r-x
default:mask::rwx
default:other::r-x

会发现好奇怪,权限似乎并不是完全无脑复制,还有莫名的掩码值限制了权限。当然,能发现的是,子目录也会继承并生成一模一样的缺省FACL

查看了一天的man page,也没有得出特别确切的结论,应该是本人英文水平太次23333333333,但还是从多次试验中总结出了规律
之前说过掩码,为什么目录文件的原始权限是777,普通文件是666呢。其实很好理解,目录只有有x执行权限才能切换进去进行操作,进行文件添加删除,所以必须有x权限。但是并不是每个普通的文本文件都是可执行的脚本,并且一旦有执行权限的普通文件会被判断成可执行文件,所以一开始就得让普通文件是普通文件,就不能有x权限,所以普通文件的原始权限就是666了。
经过试验发现,不论怎么变umask,普通文件的初始ACL-MASK永远是rw-,也就是6,目录文件是rwx,也就是7.这样做的意思大概就是我上面的思考结果,ACL-MASK是三个FACL的权限上限,借此来限制新文件的初始权限正确性。至于为什么不被掩码限制的ACL-USER-OBJ不管,因为他有掩码和原始权限管
那为什么会要限制其他三个权限呢,这就要先讲述创建在有缺省FACL目录下的文件是怎么继承缺省FACL的了

从man 5 acl 找到了这些

The access ACL of a file object is initialized when the object is created with any of the creat(), mkdir(), mknod(), mkfifo(), or open() functions. If a default ACL is associated with a directory, the mode parameter to the functions creating file objects and the default ACL of the directory are used to determine the ACL of the new object:

1. The new object inherits the default ACL of the containing directory as its access ACL.

2. The access ACL entries corresponding to the file permission bits are modified so that they contain no permissions that are not contained in the permissions specified by the mode parameter.

当使用creat()、mkdir()、mknod()、mkfifo()或open()函数创建对象时,将初始化file对象的访问ACL。如果一个默认的ACL与一个目录相关联,那么创建文件对象的函数的mode参数和目录的默认ACL将用于确定新对象的ACL:
1. 新对象继承包含目录的默认ACL作为其访问ACL。
2. 修改与文件权限位对应的访问ACL项,使它们不包含未包含在指定权限中的权限通过模式参数。

1.继承缺省FACL 2.修改继承过来的FACL,问题就在这个修改没太懂。
但是经过试验,还是明白这其中怎么做的了。

文件创建之后,首先会复制父目录的所有缺省FACL。第二步,判断文件类型,修改ACL-MASK,普通文件的ACL-MASK值为rw-(6),目录文件为rwx(7)。第三步,将ACL-USER-OBJ与ACL-OTHER的值修改为正常该文件应有的权限值(通过umask计算出的文件初始权限)
这时可以发现,有这些FACL是会原封不动从父目录的缺省FACL继承过来的:ACL-USER,ACL-GROUP,ACL-GROUP-OBJ。这就是为什么会使用ACL-MASK来限制了~
以上,原创,我厉害~
但是还是感觉好麻烦…… ̄へ ̄

su命令与sudo服务

在生产环境中,处处都有出安全问题的可能,因此如果和实验环境一样,直接使用root进行操作,可能一条命令的错误都会导致系统崩溃,所以用户的操作权限要受到限制,使用普通用户操作是很好的选择。但是Linux普通用户的权限太低,限制太多,很多事情必须要root管理员权限才能做到。这时就需要进行用户的灵活切换和高级权限的下放,这就要好好谈谈su命令和sudo服务了

su 命令
用于:切换当前用户身份到指定用户或以指定用户身份执行命令 格式: su [options] [-] [USER [arg]...] (arg:传入新shell的数据)

用户登录时会涉及到两种读取用户配置的方式,“login-shell”和“non-login-shell”,他们主要涉及了对用户环境变量的读取,配置用户的工作环境。

-/-l:login,使用“login-shell”的方式进行用户切换
-m/-p:preserve environment,保留目前的环境变量,不会进行变更
-c:command,使用新用户执行单次命令
-s:shell,指定切换用户后使用的shell,这个shell必须是/etc/shells下的一个
-f:fast,适用于csh和tsch,不去读取启动文件
-g:primary group,指定切换后使用的基本组
-G:supplemental group,指定切换后使用的扩展组

su命令不指定用户的话,默认值为root。root管理员使用su命令切换任何能够切换的用户都不需要进行密码验证

实例
su命令下“login-shell”和“non-login-shell”切换用户的区别

[Shinya@Shinya ~]$ su zzy
Password:
[zzy@Shinya Shinya]$ env | grep zzy
USER=zzy
HOME=/home/zzy
LOGNAME=zzy
[zzy@Shinya Shinya]$ env | grep Shinya
HOSTNAME=Shinya
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/Shinya/.local/bin:/home/Shinya/bin
MAIL=/var/spool/mail/Shinya
PWD=/home/Shinya

可以发现,su命令不加“-”,默认使用“non-login-shell”的方式切换,切换过去后查看用户当前环境变量,许多重要的环境变量都没有改变,家目录没第一时间切换,邮箱是之前用户的,最重要的PATH变量没变,这就会导致没法使用用户自己特有的一些命令

[Shinya@Shinya ~]$ su - zzy
Password:
Last login: Wed Feb 19 13:40:17 CST 2020 on pts/0
[zzy@Shinya ~]$ env | grep zzy
USER=zzy
MAIL=/var/spool/mail/zzy
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/zzy/.local/bin:/home/zzy/bin
PWD=/home/zzy
HOME=/home/zzy
LOGNAME=zzy
[zzy@Shinya ~]$ env | grep Shinya
HOSTNAME=Shinya

使用“login-shell”的方式切换用户,可以看到重要的环境变量都成功切换过去了,真正使用新用户的工作环境

使用su命令单次执行权限之外的命令
普通用户是没有权限查看/etc/shadow这样的文件的,但是如果需要查看,就必须使用到root管理员权限,但是又不想用权限做多余的事,防止系统出问题,就需要用su单次的去执行某项命令

[Shinya@Shinya ~]$ tail /etc/shadow
tail: cannot open ‘/etc/shadow’ for reading: Permission denied
[Shinya@Shinya ~]$ su root -c "tail -n 3 /etc/shadow"
Password:
tcpdump:!!:18167::::::
Shinya:$6$YdlMZuYZ$drbKfCUwDiNzFDP10PtgHlVGWxoy73Eh6n.2nWqoIz3Xt60ngbyAkjTXdv8h3ByxVkV93Mp4Mr7Tff7peIeX9/:18301:0:99999:7:::
zzy:$6$3P405opz$OFNZYr1.7eJ3qozzaRnz0ClhWJQKwB/kpAonQAtmEs2.FwBBMNPSlGuQv0HyWpeM.udJTqelhvmpMdfSdtJDi1:18311:0:99999:7:::
[Shinya@Shinya ~]$

可以看到,始终都处在Shinya用户的环境中,但是使用了root的管理员权限安全执行了自己需要的命令

虽然使用su命令可以灵活切换用户以及调用高级权限来完成任务,但是su 命令有一个很大的缺陷。如果一大批工作用户都需要使用root管理员权限来完成一项任务,如果使用的是su命令来实现,那么每个人都得知道root管理员的密码,这就会有可能泄露密码。于是就需要更加灵活的权限下放功能,将root管理员与留给其他用户调用的权限分开,这就是sudo

sudo 命令
用于:管理,下放管理员的权限给其他用户,提高普通用户的操作权限 格式:sudo [参数]……

-l:list,列出当前用户(-u可指定用户)可使用的sudo参数,-ll可更详细的列出
-u:user,以指定的用户身份执行命令,可指定用户名或UID
-k:kill,使时间戳缓存清零,下次执行sudo需要再次输入密码(默认5分钟)
-K:sure kill,删除时间戳文件
-v:validate,更新时间戳缓存,重新计时sudo要输入密码的时间
-b:background,后台运行sudo,这时shell的交互式命令可能无法正常工作甚至崩溃(后台运行,但是会打印输出到屏幕)
-e:edit file,使用sudo提供的权限修改文件,而不是执行什么,相当于“sudoedit”
-H:home,将HOME变量指定为新身份的HOME变量
-i:login-shell,以login-shell的方式登录目标用户的shell
-s:non-login-shell,以non-login-shell的方式登录目标用户的shell
-p:prompt,更改sudo的询问密码提示符(破参数没法单独用,必须和要执行的命令一起用)
-E:preserve environment,保留当前环境变量,如果用户没有权限保留将会错误返回

sudo不指定转换的用户身份,默认指的是root用户

sudoers文件
sudo是需要在配置后才能使用的,这个配置文件是/etc/sudoers

[root@Shinya ~]# ll /etc/sudoers
-r--r-----. 1 root root 4000 Jan 15 2014 /etc/sudoers

权限很小,440

配置sudoers文件时,Linux给我们了一个快捷命令“visudo”,这个命令直接敲下去和“vi /etc/sudoers”效果相同,都是使用没有着色功能的vi编辑器对sudoers文件进行编辑。但是 visudo 命令有两个好处,它可以帮助用户检查sudoers 文件的语法错误,有语法错误会在编辑后报错,并且使用“visudo -c”命令可以立即检查

[root@Shinya ~]# visudo
visudo: >>> /etc/sudoers: syntax error near line 1 <<<
What now? n
Options are:
(e)dit sudoers file again
e(x)it without saving changes to sudoers file
(Q)uit and save changes to sudoers file (DANGER!)

What now? x
[root@Shinya ~]# visudo -c
/etc/sudoers: parsed OK

还有一个好处是,可以阻止不同用户同时编辑sudoers文件

[Shinya@Shinya ~]$ sudo visudo
[root@Shinya ~]# visudo
visudo: /etc/sudoers busy, try again later

下来我们来详细分析sudoers 文件
## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
##
##该文件允许特定用户像root用户一样使用各种各样的命令,而不需要root用户的密码
##

##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
##
##在文件的底部提供了很多相关命令的示例以供选择,这些示例都可以被特定用户或用户组所使用
##

##
## This file must be edited with the 'visudo' command.
##
##该文件必须使用"visudo"命令编辑

## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
##
##对于一组服务器,你可能会更喜欢使用主机名(可能是全域名的通配符)或IP地址,这时可以配置主机别名
##

# Host_Alias FILESERVERS = fs1, fs2
# Host_Alias MAILSERVERS = smtp, smtp2

## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
##
##这并不很常用,因为你可以通过使用组来代替一组用户的别名
##

# User_Alias ADMINS = jsmith, mikem

## Command Aliases
## These are groups of related commands…
##
## 指定一系列相互关联的命令(当然可以是一个)的别名,通过赋予该别名sudo权限,可以通过sudo调用所有别名包含的命令,下面是一些示例
##

## Networking
##
##网络操作相关命令别名
##

# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool

## Installation and management of software
##
##软件安装管理相关命令别名
##

# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum

## Services
##
##服务相关命令别名
##

# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig

## Updating the locate database
##
##本地数据库升级命令别名
##

# Cmnd_Alias LOCATE = /usr/bin/updatedb

## Storage
##
##磁盘操作相关命令别名
##

# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount

## Delegating permissions
##
##代理权限相关命令别名
##

# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp

## Processes
##
##进程相关命令别名
##

# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall

## Drivers
##
##驱动命令别名
##

# Cmnd_Alias DRIVERS = /sbin/modprobe

# Defaults specification
#
#默认规则

#
# Disable "ssh hostname sudo ", because it will show the password in clear.
# You have to run "ssh -t hostname sudo ".
#
#禁用"ssh hostname sudo ",因为它将显示清楚的密码。您必须运行"ssh -t hostname sudo "。(-t:给ssh分配tty)
#

#
Defaults requiretty #默认:需要在tty下才能执行sudo

#
# Refuse to run if unable to disable echo on the tty. This setting should also be
# changed in order to be able to use sudo without a tty. See requiretty above.
#
#如果无法禁用tty上的echo,则拒绝运行sudo。为了能够不使用tty而使用sudo,还应该更改此设置。参见上面的requiretty。
#

#
Defaults !visiblepw #默认:不允许(!)出现可见的密码

#
# Preserving HOME has security implications since many programs
# use it when searching for configuration files. Note that HOME
# is already set when the the env_reset option is enabled, so
# this option is only effective for configurations where either
# env_reset is disabled or HOME is present in the env_keep list.
#
#保留HOME环境变量具有安全含义,因为许多程序在搜索配置文件时使用它。请注意,当启用env_reset选项时,HOME环境变量已经被设置,因此该选项仅对 #env_reset被禁用或env_keep列表中存在HOME环境变量的配置有效。
#

#
Defaults always_set_home #默认:总是更改HOME环境变量为指定用户的HOME环境变量

Defaults env_reset #默认:重置环境变量为指定用户的环境变量。env_keep为要为调用者保留的环境变量
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"

#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
#将HOME添加在env_keep列表中可能会导致用户不受限制使用sudo执行命令
#

#
# Defaults env_keep += "HOME" #默认:不添加HOME到env_keep列表中

Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin #执行sudo时代替PATH变量的内容

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
##
##接下来是主要部分:哪些用户可以在哪些机器上运行什么软件(sudoers文件可以在多个系统之间共享)。
##

## Syntax: ##语法
##
## user MACHINE=COMMANDS ##用户 登陆主机(主机名/地址)=(可变换的身份) 可执行的命令
##
## The COMMANDS section may have other options added to it. ##“命令”部分可以使用一些其他的选项
##
## Allow root to run any commands anywhere ##示例:允许root用户在任何地方登录执行任意命令
root ALL=(ALL) ALL

## Allows members of the 'sys' group to run networking, software, ##示例:允许“sys”组的成员执行网络、软件、服务管理应用程序等类型的命令
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS

## Allows people in group wheel to run all commands ##示例:允许“wheel”组的成员执行所有的命令
%wheel ALL=(ALL) ALL

## Same thing without a password ##示例:和上面相同但是不需要密码确认即可做到
# %wheel ALL=(ALL) NOPASSWD: ALL

## Allows members of the users group to mount and unmount the ##示例:允许users组成员像root一样mount和unmount cdrom
## cdrom as root
# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom

## Allows members of the users group to shutdown this system ##示例:允许users组成员shutdown系统
# %users localhost=/sbin/shutdown -h now

## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment) ##从/etc/sudoers.d读取drop-in文件(这里的#不代表注释)
#includedir /etc/sudoers.d

sudoer中几个变量的解释
requiretty:

If set, sudo will only run when the user is logged in to a real tty. When this flag is set, sudo can only be run from a login session and not via other means such as cron(8) or cgi-bin scripts. This flag is off by default.
——man 5 sudoers

如果设置了,sudo将只在用户登录到实际tty时运行。设置此标志后,sudo只能在登录会话中运行,而不能通过其他方式(如cron(8)或cgi-bin脚本)运行。这个标志默认是关闭的。

(默认好像没关闭啊……)ssh连接时默认只是连接上主机交换数据,不去进行会话,也不会请求使用tty,这时输的密码可能就会明文显示,出于安全,只允许将sudo运行在tty,实际的登录会话上。如果使用ssh直接使用sudo会进行报错

[Shinya@Shinya ~]$ ssh Shinya@175.24.101.243 sudo ls /root
……
sudo: no tty present and no askpass program specified

所以ssh连接不请求tty使用sudo时,应该关闭这个开关

visiblepw:

By default, sudo will refuse to run if the user must enter a password but it is not possible to disable echo on the terminal. If the visiblepw flag is set, sudo will prompt for a password even when it would be visible on the screen. This makes it possible to run things like “ssh somehost sudo ls” since by default, ssh(1) does not allocate a tty when running a command. This flag is off by default.
——man 5 sudoers

默认情况下,如果用户必须输入密码,但是不可能在终端上禁用echo,sudo将拒绝运行。如果设置了visiblepw标志,即使在屏幕上可以看到密码,sudo也会提示输入密码。这使得运行“ssh somehost sudo ls”之类的操作成为可能,因为在默认情况下,ssh(1)在运行命令时不分配tty。这个标志默认是关闭的。

(这个默认是关闭了的……“!”表示关闭)跟上面一样的,都是为了保护ssh连接时的密码保密性,ssh连接不请求tty使用sudo时,也应该关闭这个开关

解释一下“console”“terminal”“tty”都是什么,因为看起来好像
console:控制台,计算机发展初期,巨大的机器上就有一个充满指示灯和开关的面板,这个就叫控制台,是管理主机许多重要功能开关的地方。现在的话也大多数指的是机器上最重要的调试接口
terminal:终端,早期因为计算机资源稀少,用户机都是连接到大型主机上使用的,这些从主机连接出来的就是“终端”,意为连接线缆的末端。早期的“终端”只能与主机进行很简单的文字交互。现在,PC,手机,移动设备,都可以被称为终端,当然他们也是一台完整的主机
tty:teletypewriter,电传打印机。这个翻译很老旧……tty是终端的一种,因为早期的终端中电传打印机使用的最多,所以tty这个词就流传了下来。简单说他就指的是虚拟终端,进行交互的接口。

配置sudoers
具体配置部分在sudoers文件中标注出来了,这里主要探讨如何去写配置
Syntax:caller   MACHINE=(users) COMMANDS

caller(调用者)部分,指定用户的话直接使用用户名即可(不能使用UID),指定用户组的话要使用“%组名”

MACHINE部分,可以使用IP地址与主机名,“ALL”表示任何主机。(“localhost”不代表本地主机,而是没改主机名时候主机名的的默认值是localhost,2333333)

users:使用用户名来指定可以变换的用户身份(不能使用UID),多个用户使用“,”隔开

其中“commands”部分,shell命令必须使用二进制文件的路径来写。使用“ALL”,表示任何命令。使用“NOPASSWD:”可以来指定那些命令不需要密码即可使用,“NOPASSWD:ALL”表示不需要密码确认即可执行所有命令。命令条目之间使用“,”隔开。

实例:
设置Shinya的sudo条目,要求:从本地登录可用,可以以root用户身份执行命令,可以执行ls,cat命令,其中ls命令不用密码确认即可使用

[root@Shinya ~]# visudo
root ALL=(ALL) ALL
Shinya Shinya=(root) /usr /bin/cat,NOPASSWD:/usr/bin/ls
[Shinya@Shinya ~]$ sudo ls /root
anaconda-ks.cfg Desktop Documents Downloads initial-setup-ks.cfg list.txt Music Pictures Public Shinya Templates Videos
[Shinya@Shinya ~]$ sudo cat /etc/shadow
[sudo] password for Shinya:
……
……

可以发现,sudo使用时,只是需要登录用户使用自己的密码进行确认罢了,不需要root管理员的密码,保证了密码不被泄露。

设置Shinya的sudo条目,Shinya用户使用sudo创建一个由sshd用户创建的文件

[root@Shinya ~]# visudo
root ALL=(ALL) ALL
Shinya Shinya=(root,sshd) /usr/bin/touch
[Shinya@Shinya ~]$ sudo -u sshd touch /tmp/file
[sudo] password for Shinya:
[Shinya@Shinya ~]$ ll /tmp/file
-rw-r--r--. 1 sshd sshd 0 Feb 20 20:39 /tmp/file

这里就能体现出sudo的强大了,sshd作为一个shell设置为/sbin/nologin 的系统用户,使用sudo可以不去登录而使用这样的用户进行操作

使用sudo与su配合,使可信的用户不需root密码即可登录root进行操作

[root@Shinya ~]# visudo
Shinya Shinya=(root) /usr/bin/su
[Shinya@Shinya ~]$ sudo su - root
[sudo] password for Shinya:
Last login: Wed Feb 19 13:56:38 CST 2020 on pts/0
[root@Shinya ~]#

这样就可以将root登录绕过密码,直接使信任的用户登录root进行操作了!(厉害啊……)

其实上面,所有实验条目的“commands”设为“ALL”也可以进行,但是这时极其不安全的,不建议使用。

“commands”中,禁止使用的条目可以直接删掉,也可以使用“!”进行无效化。例如:除了vim,其他的命令都可以使用,可以这样设置“(ALL,!/usr/bin/vim)”。这里注意的是,“commands”中是从后往前执行的,所以禁止的命令应该放在后面才行

sudo的运行原则
普通用户运行sudo -> 检查/var/db/sudo/下是否有时间戳文件(执行成功后会创建,且免密5分钟),并检查是否已经过期

未过期  -> 检查/etc/sudoers里面是否配置了运行sudo和执行相应命令的权限
->有权限 ->执行命令并且返回结果 ->退出
->无权限 ->退出

过期  -> 输入当前用户自己的口令 ->检查/etc/sudoers里面是否配置了运行sudo和执行相应命令的权限
->有权限 ->执行命令并且返回结果 ->退出
->无权限 ->退出

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像

Title - Artist
0:00