在复杂的生产环境中,单纯设置文件的rwx权限无法满足我们对安全和灵活性的需求,因此便有了SUID、SGID与SBIT的特殊权限位。这是一种对文件权限进行设置特殊功能的方法,可以与一般权限同时使用,以弥补一般权限不能实现的功能。下面具体解释这3个特殊权限位的功能以及用法。
Linux 系统文件除了9位基本权限,还有额外3位特殊权限,分别是SUID(setuid),SGID(setgid),SBIT(sticky bit)。
Linux 系统文件3位特殊权限位说明
标注:这3位特殊权限不建议使用(除系统默认的特殊权限可以使用以外),除非有特殊需求
特殊权限 | 特殊权限位小写 | 特殊权限位大写 | 权限值 |
---|---|---|---|
s (suid) | 小写s (有suid执行权限) | 大写S (无suid执行权限) | 4 |
s (sgid) | 小写s (有sgid执行权限) | 大写S (无sgid执行权限) | 2 |
t(sticky bit) | 小写t (有sticky bit执行权限) | 大写T (无sticky bit执行权限) | 1 |
SUID是一种对二进制程序进行设置的特殊权限,可以让二进制程序的执行者临时拥有文件所属者的权限(仅对拥有执行权限的二进制文件有效)。例如,所有用户都可以执行passwd命令来修改自己的用户密码,而用户密码保存在/etc/shadow文件中。仔细查看这个文件就会发现它的默认权限是000,也就是说除了root管理员以外,所有用户都没有查看或编辑该文件的权限。但是,在使用passwd命令时如果加上SUID特殊权限位,就可让普通用户临时获得程序所属者的身份,把变更的密码信息写入到shadow文件中。这很像我们在古装剧中见到的手持尚方宝剑的钦差大臣,他手持的尚方宝剑代表的是皇上的权威,因此可以惩戒贪官,但这并不意味着他永久成为了皇上。因此这只是一种有条件的、临时的特殊权限授权方法。
查看passwd命令属性时发现所有者的权限由rwx变成了rws,其中x改变成s就意味着该文件被赋予了SUID权限。另外有读者会好奇,那么如果原本的权限是rw-呢?如果原先权限位上没有x执行权限,那么被赋予特殊权限后将变成大写的S。
[root@itcast share]# ls -l /etc/shadow
---------- 1 root root 1525 8月 3 17:08 /etc/shadow
[root@itcast share]#
[root@itcast share]# ls -l /bin/passwd
-rwsr-xr-x. 1 root root 27832 6月 10 2014 /bin/passwd
[root@itcast share]#
用户属主对应的前三位权限的x位上如果有s就表示suid权限,当x位上没有小写x执行权限时候,suid的权限显示就是大S
注意:suid功能是一把双刃剑,是一个比较危险的功能,对系统安全有一定威胁系统,suid的无用的功能取消suid权限(安全优化)
设置SUID的例子
[root@itcast tmp]# pwd
/tmp
[root@itcast tmp]# touch file
[root@itcast tmp]# ls -l file
-rw-r--r-- 1 root root 0 8月 7 22:25 file
#切换到deng用户
[root@itcast tmp]# su - deng
上一次登录:三 8月 7 22:16:01 CST 2019pts/1 上
[deng@itcast ~]$ cd /tmp/
[deng@itcast tmp]$ rm -rf file
rm: 无法删除"file": 不允许的操作
[deng@itcast tmp]$
[deng@itcast tmp]$ exit
登出
[root@itcast tmp]# which rm
alias rm='rm -i'
/bin/rm
[root@itcast tmp]# chmod u+s /bin/rm #追加特权
[root@itcast tmp]# ls -l /bin/rm
-rwsr-xr-x. 1 root root 62864 4月 11 2018 /bin/rm
[root@itcast tmp]#
#切换到deng用户
[root@itcast tmp]# su - deng
上一次登录:三 8月 7 22:26:16 CST 2019pts/1 上
[deng@itcast ~]$ cd /tmp/
[deng@itcast tmp]$ rm -rf file #删除成功
[deng@itcast tmp]$
取消suid权限
[root@itcast tmp]# chmod u-s /bin/rm
[root@itcast tmp]# ls -l /bin/rm
-rwxr-xr-x. 1 root root 62864 4月 11 2018 /bin/rm
[root@itcast tmp]#
等同命令chmod 4755 /bin/rm,取消suid命令 chmod u-s /bin/rm或chmod 0755 /bin/rm
SGID主要实现如下两种功能:
让执行者临时拥有所属组的权限(对拥有执行权限的二进制程序进行设置有效);
在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置有效)。
SGID的第一种功能是参考SUID而设计的,不同点在于执行程序的用户获取的不再是文件所有者的临时权限,而是获取到文件所属组的权限。举例来说,在早期的Linux系统中,/dev/kmem是一个字符设备文件,用于存储内核程序要访问的数据,权限为:
cr--r----- 1 root system 2, 1 Feb 11 2017 kmem
除了root管理员或属于system组成员外,所有用户都没有读取该文件的权限。由于在平时我们需要查看系统的进程状态,为了能够获取到进程的状态信息,可在用于查看系统进程状态的ps命令文件上增加SGID特殊权限位。查看ps命令文件的属性信息:
-r-xr-sr-x 1 bin system 59346 Feb 11 2017 ps
由于ps命令被增加了SGID特殊权限位,所以当用户执行该命令时,也就临时获取到了system用户组的权限,从而可以顺利地读取设备文件了。
之前提到,每个文件都有其归属的所有者和所属组,当创建或传送一个文件后,这个文件就会自动归属于执行这个操作的用户(即该用户是文件的所有者)。如果现在需要在一个部门内设置共享目录,让部门内的所有人员都能够读取目录中的内容,那么就可以创建部门共享目录后,在该目录上设置SGID特殊权限位。这样,部门内的任何人员在里面创建的任何文件都会归属于该目录的所属组,而不再是自己的基本用户组。此时,我们用到的就是SGID的第二个功能,即在某个目录中创建的文件自动继承该目录的用户组(只可以对目录进行设置)。
[root@itcast tmp]# mkdir /tmp/test
[root@itcast tmp]# ls -ld test
drwxr-xr-x 2 root root 6 8月 7 22:08 test
[root@itcast tmp]# chmod 777 test
[root@itcast tmp]# chmod g+s test
[root@itcast tmp]# ls -ld test
drwxrwsrwx 2 root root 6 8月 7 22:08 test
[root@itcast tmp]#
在使用上述命令设置好目录的777权限(确保普通用户可以向其中写入文件),并为该目录设置了SGID特殊权限位后,就可以切换至一个普通用户,然后尝试在该目录中创建文件,并查看新创建的文件是否会继承新创建的文件所在的目录的所属组名称:
[root@itcast tmp]# su - deng
上一次登录:三 8月 7 21:22:00 CST 2019从 172.16.0.51pts/1 上
[deng@itcast ~]$ cd /tmp/test
[deng@itcast test]$ ls
[deng@itcast test]$ touch file
[deng@itcast test]$ ls -l file
-rw-rw-r-- 1 deng root 0 8月 7 22:09 file
[deng@itcast test]$
我们发现新创建的文件默认所属组是root
设置SGID的例子
[root@itcast ~]# mkdir test
[root@itcast ~]# ls -ld test
drwxr-xr-x 2 root root 6 8月 7 22:32 test
[root@itcast ~]# chown deng:itcast test
[root@itcast ~]# ls -ld test
drwxr-xr-x 2 deng itcast 6 8月 7 22:32 test
[root@itcast ~]# touch test/file
[root@itcast ~]# ls -l test/file #发现创建文件的所属者和所属组都是root
-rw-r--r-- 1 root root 0 8月 7 22:32 test/file
[root@itcast ~]#
[root@itcast ~]#
[root@itcast ~]# chmod g+s test #设置SGID权限
[root@itcast ~]# touch test/file2
[root@itcast ~]# ls -l test/file2 #发现创建文件所属组是itcast
-rw-r--r-- 1 root itcast 0 8月 7 22:33 test/file2
[root@itcast ~]#
现实生活中,大学里的很多老师都要求学生将作业上传到服务器的特定共享目录中,但总是有几个“破坏分子”喜欢删除其他同学的作业,这时就要设置SBIT(Sticky Bit)特殊权限位了(也可以称之为特殊权限位之粘滞位)。SBIT特殊权限位可确保用户只能删除自己的文件,而不能删除其他用户的文件。换句话说,当对某个目录设置了SBIT粘滞位权限后,那么该目录中的文件就只能被其所有者执行删除操作了。
最初不知道是哪位非资深技术人员将Sticky Bit直译成了“粘滞位”,我们建议将其称为“保护位”,这既好记,又能立刻让人了解它的作用。RHEL 7系统中的/tmp作为一个共享文件的目录,默认已经设置了SBIT特殊权限位,因此除非是该目录的所有者,否则无法删除这里面的文件。
[deng@itcast test]$ ls -ld /tmp
drwxrwxrwt. 17 root root 4096 8月 7 22:08 /tmp
[deng@itcast test]$
与前面所讲的SUID和SGID权限显示方法不同,当目录被设置SBIT特殊权限位后,文件的其他人权限部分的x执行权限就会被替换成t或者T,原本有x执行权限则会写成t,原本没有x执行权限则会被写成T。
[deng@itcast ~]$ su - deng
密码:
上一次登录:三 8月 7 22:13:04 CST 2019pts/1 上
[deng@itcast ~]$
[deng@itcast ~]$ cd /tmp
[deng@itcast tmp]$ touch file1
[deng@itcast tmp]$ chmod 777 file1
[deng@itcast tmp]$ ls -l file1
-rwxrwxrwx 1 deng deng 0 8月 7 22:16 file1
[deng@itcast tmp]$
其实,文件能否被删除并不取决于自身的权限,而是看其所在目录是否有写入权限。为了避免现在很多用户不放心,所以上面的命令还是赋予了这个test文件最大的777权限(rwxrwxrwx)。我们切换到另外一个普通用户,然后尝试删除这个其他人创建的文件就会发现,即便读、写、执行权限全开,但是由于SBIT特殊权限位的缘故,依然无法删除该文件:
[deng@itcast tmp]$ su - itcast
密码:
上一次登录:三 8月 7 22:15:11 CST 2019pts/1 上
[itcast@itcast ~]$ cd /tmp/
[itcast@itcast tmp]$ rm -rf file1
rm: 无法删除"file1": 不允许的操作
[itcast@itcast tmp]$
当然,要是也想对其他目录来设置SBIT特殊权限位,用chmod命令就可以了。对应的参数o+t代表设置SBIT粘滞位权限
[deng@itcast ~]$ mkdir test
[deng@itcast ~]$ chmod o+t test
[deng@itcast ~]$ ls -ld test
drwxrwxr-t 2 deng deng 6 8月 7 22:18 test
[deng@itcast ~]$
设置特权位的例子
[root@itcast /]# mkdir /ddd
[root@itcast /]# touch /ddd/test.sh
[root@itcast /]# chmod -R 0777 /ddd
[root@itcast /]# ls -ld /ddd
drwxrwxrwx 2 root root 21 8月 7 22:39 /ddd
#等同命令chmod o+s /ddd
[root@itcast /]# chmod 1777 /ddd
[root@itcast /]# ls -ld /ddd
drwxrwxrwt 2 root root 21 8月 7 22:39 /ddd
[root@itcast /]# su - deng
上一次登录:三 8月 7 22:37:28 CST 2019pts/1 上
[deng@itcast ~]$ rm -rf /ddd/test.sh
rm: 无法删除"/ddd/test.sh": 不允许的操作
[deng@itcast ~]$ exit
登出
[root@itcast /]# rm -rf /ddd/test.sh
[root@itcast /]#
参考:【Linux】一步一步学Linux系列教程汇总