2.18特殊权限set_uid
我们曾经用过passwd来更改过root的密码。我们来查看一下这个文件的权限
[root@lhy ~]# which passwd
/usr/bin/passwd
[root@lhy ~]# ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 27832 Jun 10 2014 /usr/bin/passwd
我们发现当前用户的权限并不是rwx而是rws,这个s就是set_uid的权限。
对于linux系统,更改密码必然涉及更改文件/etc/shadow,而这个文件的权限是000,普通用户想更改自己用户的密码总不能每次都要麻烦管理员,这就是一个矛盾。
[root@lhy ~]# ll /etc/shadow
---------- 1 root root 616 Jun 6 16:39 /etc/shadow
因此就有了这个特殊权限set_uid,当普通用户执行带set_uid权限的文件(必然是二进制文件)的时候,就会给普通用户临时提升到所有者的权限(仅限此命令)。
下面介绍如何给文件授权set_uid
首先我们新开一个终端,把用户切换到lhy01,此时普通用户是不能浏览/root/目录的。
[root@lhy ~]# su - lhy01
Last login: Wed Jun 6 16:45:16 CST 2018 on pts/0
[lhy01@lhy ~]$ whoami
lhy01
[lhy01@lhy ~]$ ls /root/
ls: cannot open directory /root/: Permission denied
[lhy01@lhy ~]$ ls -ld /root
dr-xr-x---. 6 root root 255 Jun 6 19:12 /root
那我们来看一下命令的所有者,并使用chmod命令添加set_uid权限
[root@lhy ~]# ll /usr/bin/ls
-rwxr-xr-x 1 root root 117672 Apr 11 12:35 /usr/bin/ls
[root@lhy ~]# chmod u+s /usr/bin/ls
[root@lhy ~]# ll /usr/bin/ls
-rwsr-xr-x 1 root root 117672 Apr 11 12:35 /usr/bin/ls
此时,切换到普通用户,就会发现我们已经可以ls /root/了
[lhy01@lhy tmp]$ ls /root
1 2 2.txt anaconda-ks.cfg anaconda-ks.cfg1 openscap_data
[lhy01@lhy tmp]$ ls -ld /root
dr-xr-x---. 6 root root 255 Jun 6 19:12 /root
上面提到使用u+s的方式添加set_uid, 那么通过u=rws是不是也能添加呢?我们实验一下
[root@lhy bin]# chmod u-s /usr/bin/ls
[root@lhy bin]# ll -d !$
ll -d /usr/bin/ls
-rwxr-xr-x 1 root root 117672 Apr 11 12:35 /usr/bin/ls
[root@lhy bin]# chmod u=rws /usr/bin/ls
[root@lhy bin]# ll -d /usr/bin/ls
-rwSr-xr-x 1 root root 117672 Apr 11 12:35 /usr/bin/ls
我们发现它变成了capital-S权限,这是因为ls没有了x权限,如果再给它添加一个x权限,就会变成s权限了。
[root@lhy bin]# chmod u+x /usr/bin/ls
[root@lhy bin]# ll -d /usr/bin/ls
-rwsr-xr-x 1 root root 117672 Apr 11 12:35 /usr/bin/ls
不过其他用户能否执行这个文件要看other段的x权限,即使是user位是rwS也是能够执行的,相对的如果other位是r--的话,就算有set_uid权限,你也无法执行这个命令。
2.19特殊权限set_gid
顾名思义,set_gid是作用在组权限的特殊权限。下面我们来演示一下。
[root@lhy ~]# chmod 755 /usr/bin/ls
[root@lhy ~]# ls /bin/ls -l
-rwxr-xr-x 1 root root 117672 Apr 11 12:35 /bin/ls
[root@lhy ~]# ll /usr/bin/ls
-rwxr-xr-x 1 root root 117672 Apr 11 12:35 /usr/bin/ls
[root@lhy ~]# ll /usr/bin/ls
-rwxr-sr-x 1 root root 117672 Apr 11 12:35 /usr/bin/ls
同样在group段出现了set_gid权限,也就是说普通用户拥有了ls命令的所属组的权限,这样普通用户也可以查看/root/目录,就是因为此目录权限为550。
[lhy01@lhy ~]$ ll -d /root
dr-xr-x---. 6 root root 255 Jun 6 19:12 /root
当我更改一个目录(./3/)的group的时候,如果没有set_gid,我在./3/下创建文件和目录的时候,文件和目录的所属组还是当前用户的所属组。
[root@lhy ~]# mkdir 3/
[root@lhy ~]# ll -d 3/
drwxr-xr-x 2 root root 6 Jun 7 14:05 3/
[root@lhy ~]# chown :lhy01 3/
[root@lhy ~]# ll -d 3/
drwxr-xr-x 2 root lhy01 6 Jun 7 14:05 3/
[root@lhy ~]# touch 3/1.xx
[root@lhy ~]# mkdir 3/xx
[root@lhy ~]# ll 3/
total 0
-rw-r--r-- 1 root root 0 Jun 7 14:06 1.xx
drwxr-xr-x 2 root root 6 Jun 7 14:06 xx
但是如果我设置了set_gid权限之后,新创建的目录和文件就变成了当前目录的所属组。
[root@lhy ~]# chmod g+s 3/
[root@lhy ~]# ll -d 3/
drwxr-sr-x 3 root lhy01 28 Jun 7 14:06 3/
[root@lhy ~]# touch 3/2.xx
[root@lhy ~]# mkdir 3/xxx
[root@lhy ~]# ll 3/
total 0
-rw-r--r-- 1 root root 0 Jun 7 14:06 1.xx
-rw-r--r-- 1 root lhy01 0 Jun 7 14:08 2.xx
drwxr-xr-x 2 root root 6 Jun 7 14:06 xx
drwxr-sr-x 2 root lhy01 6 Jun 7 14:08 xxx
2.20 特殊权限stick_bit
系统中,目录/tmp/有特殊权限stick_bit
[root@lhy ~]# ll -d /tmp/
drwxrwxrwt. 15 root root 4096 Jun 7 13:50 /tmp/
这个t权限又叫做防删除位。
当user1在/tmp/下创建一个文件,user2也是有权限查看这个文件的,但是user2写入和删除是非法的。
例如,用户lhy01在/tmp/下创建一个文件lhy01,并更改权限为777,此时用户lhy02是可以修改的
[lhy01@lhy ~]$ whoami
lhy01
[lhy01@lhy ~]$ cd /tmp/
[lhy01@lhy tmp]$ touch lhy01
[lhy01@lhy tmp]$ ls -l lhy01
-rw-rw-r-- 1 lhy01 lhy01 0 Jun 7 15:38 lhy01
[lhy01@lhy tmp]$ echo "asdgah" >> lhy01
[lhy01@lhy tmp]$ chmod 777 lhy01
[lhy01@lhy tmp]$
[lhy01@lhy tmp]$ ls -l lhy01
-rwxrwxrwx 1 lhy01 lhy01 7 Jun 7 15:38 lhy01
但是lhy02是不能删除这个文件的。
[lhy02@lhy tmp]$ whoami
lhy02
[lhy02@lhy tmp]$ echo "asdhadh" >> lhy01
[lhy02@lhy tmp]$ rm -f lhy01
rm: cannot remove ‘lhy01’: Operation not permitted
这里要提一句,其实能否删除文件与当前文件所在的目录的权限有关,而非文件本身的w权限。如果lhy01在/tmp下创建一个目录/tmp/lhy01。此时lhy02可以进入(x权限)目录,但是不能创建新文件(w权限)
[lhy01@lhy tmp]$ mkdir lhy01
[lhy01@lhy tmp]$ ll lhy01/ -d
drwxrwxr-x 2 lhy01 lhy01 6 Jun 7 15:52 lhy01/
[lhy02@lhy tmp]$ cd lhy01/
[lhy02@lhy lhy01]$ touch 1.txt
touch: cannot touch ‘1.txt’: Permission denied
再更改一下目录权限为777,此时就可以创建了,而且所属为lhy02。
[lhy02@lhy lhy01]$ touch 1.txt
[lhy02@lhy lhy01]$ mkdir 234/
[lhy02@lhy lhy01]$ ll -a
total 4
drwxrwxrwx 3 lhy01 lhy01 30 Jun 7 15:55 .
drwxrwxrwt. 16 root root 4096 Jun 7 15:52 ..
-rw-rw-r-- 1 lhy02 lhy02 0 Jun 7 15:55 1.txt
drwxrwxr-x 2 lhy02 lhy02 6 Jun 7 15:55 234
此时,目录虽然是lhy01的,lhy02也是可以删除文件的。
如果我们给目录添加stick_bit,就不能删除其他用户的文件了,当然,自己所有的文件是可以删除的。
[lhy01@lhy tmp]$ chmod o+t lhy01/
[lhy01@lhy tmp]$ ll -d lhy01/
drwxrwxrwt 3 lhy01 lhy01 30 Jun 7 15:55 lhy01/
[lhy02@lhy lhy01]$ ls
1.txt 2.txt 234
[lhy02@lhy lhy01]$ rm 1.txt
[lhy02@lhy lhy01]$ ls
2.txt 234
[lhy02@lhy lhy01]$ rm 2.txt
rm: remove write-protected regular empty file ‘2.txt’? y
rm: cannot remove ‘2.txt’: Operation not permitted
2.21 软链接文件
软链接与硬链接都属于链接文件。软链接类比于Windows下的快捷方式。
/bin/就是一个软链接。
[root@lhy tmp]# ls -l /bin
lrwxrwxrwx 1 root root 7 Jun 5 21:37 /bin -> usr/bin
软链接其实就是存储了一个“路径的指针”,软链接的大小和你路径的长短相关,路径越长文件越大。
软链接的作用可以参考/lib/或者/lib64/下的链接文件。在/lib64/目录下存放了大量的库文件,有很多程序执行的时候就要加载库文件。例如
[root@lhy bin]# ls -l /lib64/libxml*
lrwxrwxrwx. 1 root root 16 May 29 14:01 /lib64/libxml2.so.2 -> libxml2.so.2.9.1
-rwxr-xr-x. 1 root root 1509376 Jun 23 2016 /lib64/libxml2.so.2.9.1
lrwxrwxrwx 1 root root 28 Jun 5 21:37 /lib64/libxmlsec1-openssl.so -> libxmlsec1-openssl.so.1.2.20
lrwxrwxrwx 1 root root 28 Jun 5 21:37 /lib64/libxmlsec1-openssl.so.1 -> libxmlsec1-openssl.so.1.2.20
-rwxr-xr-x 1 root root 245128 Aug 31 2017 /lib64/libxmlsec1-openssl.so.1.2.20
lrwxrwxrwx 1 root root 20 Jun 5 21:37 /lib64/libxmlsec1.so.1 -> libxmlsec1.so.1.2.20
-rwxr-xr-x 1 root root 430520 Aug 31 2017 /lib64/libxmlsec1.so.1.2.20
程序1加载libxmlsec1.so.1.2.20的时候写的名称是libxmlsec1.so.1.2.20,但是程序2加载库文件的时候使用的名称为/lib64/libxmlsec1.so.1,此时如果我们cp一份也是没有任何问题的,但是如果因此而磁盘空间不足,或者yum更新库文件的时候只更新了/lib64/libxmlsec1.so.1.2.20,是不是还要重新cp一份。
还有一种情况,程序必须在/directory1/下找到file1文件,而文件储存在/directory2/下,而且此文件会更新,那么也可以使用软链接。
软链接的创建(无论文件还是目录)使用ln -s命令。
#ln -s source destiny
[root@lhy tmp]# ln -s /tmp/yum.log /root/1/yum.log
[root@lhy tmp]# ll /root/1/
total 0
lrwxrwxrwx 1 root root 12 Jun 7 16:25 yum.log -> /tmp/yum.log
[root@lhy tmp]# ln -s /tmp/aminglinux/ /root/1/aminglinux.copy
[root@lhy tmp]# ll /root/1/aminglinux.copy/ -d
dr-xr--r-x. 3 root root 33 Jun 6 11:00 /root/1/aminglinux.copy/
当然我们也可以使用相对路径创建软链接,但是当软链接被mv到其他目录之后可能就会出现问题。
[root@lhy 8]# ln -s ../yum.log yum.log.copy
[root@lhy 8]# ll
total 4
-rw-rw-r-- 1 root root 0 Jun 6 19:45 1.ttt
-rw-r--r-- 1 root root 5 Jun 6 19:49 2.11
-rw-r--r-- 1 root root 0 Jun 6 11:05 2.12
lrwxrwxrwx 1 root root 10 Jun 7 16:33 yum.log.copy -> ../yum.log
[root@lhy 8]# mv yum.log.copy /root/
[root@lhy 8]# cd /root/
[root@lhy ~]# ll
total 12
drwxr-xr-x. 2 root root 44 Jun 7 16:28 1
drwxr-xr-x. 3 root root 37 Jun 7 14:04 2
-rwx------ 1 root root 0 Jun 6 10:53 2.txt
drwxr-sr-x 4 root lhy01 51 Jun 7 14:08 3
-rw-------. 1 root root 1622 May 29 14:05 anaconda-ks.cfg
-rw------- 1 root root 5829 Jun 6 11:37 anaconda-ks.cfg1
drwxr-xr-x. 2 root root 40 May 29 14:04 openscap_data
lrwxrwxrwx 1 root root 10 Jun 7 16:33 yum.log.copy -> ../yum.log
[root@lhy ~]# cat yum.log.copy
cat: yum.log.copy: No such file or directory
这种情况就是当前目录不存在yum.log ,如果巧合,当前目录有其他文件也叫yum.log ,这样虽然不会报错,但是会出现我们意想不到的错误。
当然使用相对路径也有好处,比如user1下有个程序,其下有很多配置文件,我要把它打包压缩cp给user2,如果使用了绝对路径而user2不能访问user1的目录,程序很可能就会报错。
所以使用绝对路径还是相对路径要看个人需求。
2.22 硬链接文件
之前提到过一个inode的知识点,与它息息相关的就是硬链接了。硬链接不同于软链接的是,它会使文件的inode加1。例如我创建了一个软链接,可以看到anaconda-ks.cfg这个文件的inode依然是1。
[root@lhy ~]# ln -s anaconda-ks.cfg anaconda-ks.cfg.2
[root@lhy ~]# ll
-rw-------. 1 root root 1622 May 29 14:05 anaconda-ks.cfg
-rw------- 1 root root 5829 Jun 6 11:37 anaconda-ks.cfg1
lrwxrwxrwx 1 root root 15 Jun 7 16:45 anaconda-ks.cfg.2 -> anaconda-ks.cfg
而当我创建一个硬链接的时候,inode就变成2了,而且文件大小是一模一样的(并不会占用双份空间)。
[root@lhy ~]# ln anaconda-ks.cfg 1_hard.anaconda-ks.cfg
[root@lhy ~]# ll
drwxr-xr-x. 2 root root 44 Jun 7 16:28 1
-rw-------. 2 root root 1622 May 29 14:05 1_hard.anaconda-ks.cfg
-rw-------. 2 root root 1622 May 29 14:05 anaconda-ks.cfg
-rw------- 1 root root 5829 Jun 6 11:37 anaconda-ks.cfg1
查看一下两者的inode号,软链接文件的inode号与源文件不同,而硬链接是相同的。
[root@lhy ~]# ll -i
67145602 -rw-------. 2 root root 1622 May 29 14:05 1_hard.anaconda-ks.cfg
67145602 -rw-------. 2 root root 1622 May 29 14:05 anaconda-ks.cfg
67190660 lrwxrwxrwx 1 root root 15 Jun 7 16:45 anaconda-ks.cfg.2 -> anaconda-ks.cfg
软链接的源文件被删除之后,软链接就会失效,而硬链接文件是互为硬链接,删除文件的时候inode减少1,其他inode相同的文件是不受影响的。只有inode=0了,文件才会真正的被删除。
最后,目录不允许做硬链接(系统规定的)。因为它有自己的一套硬链接设定,比如当前目录(.)和上一级目录(..)。硬链接也不允许跨分区,这个个inode的性质所决定的。不同分区的inode是独立的。
[root@lhy ~]# ls -i /boot/
72 config-3.10.0-693.el7.x86_64 86 initramfs-3.10.0-862.3.2.el7.x86_64kdump.img
82 config-3.10.0-862.3.2.el7.x86_64 75 initrd-plymouth.img
67 efi 73 symvers-3.10.0-693.el7.x86_64.gz
68 grub 83 symvers-3.10.0-862.3.2.el7.x86_64.gz
393280 grub2 71 System.map-3.10.0-693.el7.x86_64
77 initramfs-0-rescue-7b83625f83564e1691eca0a488be153c.img 81 System.map-3.10.0-862.3.2.el7.x86_64
76 initramfs-3.10.0-693.el7.x86_64.img 78 vmlinuz-0-rescue-7b83625f83564e1691eca0a488be153c
79 initramfs-3.10.0-693.el7.x86_64kdump.img 74 vmlinuz-3.10.0-693.el7.x86_64
85 initramfs-3.10.0-862.3.2.el7.x86_64.img 84 vmlinuz-3.10.0-862.3.2.el7.x86_64
[root@lhy ~]# ln /boot/config-3.10.0-693.el7.x86_64 /tmp/config
ln: failed to create hard link ‘/tmp/config’ => ‘/boot/config-3.10.0-693.el7.x86_64’: Invalid cross-device link