Linux

Linux上文件特殊权限位SUID,SGID,SBIT的使用说明

一问题现象

在Unix、Linux系统上,我们知道文件权限无非就是用rwx表示,结合文件所属owner,group,以及针对其他非同用户组的用户other而言,表示起权限来,无非也就类似这样的表示:

localhost-> id
uid=1101(oracle) gid=1000(oinstall) groups=1000(oinstall),1201(asmdba),1300(dba),1301(oper)
localhost-> pwd
/u01/app/oracle/product/11.2.0/db_1/bin
localhost-> ll zip 
-rwxr-xr-x. 1 oracle oinstall 88565 Jan  1  2000 zip
localhost-> 

可是,有时候我们会遇到这种权限表示的文件,比如:

localhost-> id
uid=1101(oracle) gid=1000(oinstall) groups=1000(oinstall),1201(asmdba),1300(dba),1301(oper)
localhost-> pwd
/u01/app/oracle/product/11.2.0/db_1/bin
localhost-> file oracle
oracle: setuid setgid ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
localhost-> ll oracle
-rwsr-s--x. 1 oracle oinstall 210823812 Nov 30  2016 oracle
localhost-> 

文件权限位上多出来一个s。嗯,这个s是什么?它表示什么意思呢?

注意:这里的oracle是一个二进制可执行文件。用file命令来查看文件类型。其输出结果中有两个关键词setuid setgid。

再比如:

localhost-> ll -d /tmp/
drwxrwxrwt. 12 root root 4096 Jul 23 07:58 /tmp/
localhost-> file /tmp 
/tmp: sticky directory
localhost-> file ~/Desktop/
/home/oracle/Desktop/: directory
localhost-> 

/tmp路径文件权限位上多出来一个t,这个t又表示什么意思呢?

注意:file /tmp和file ~/Desktop的输出结果不同。/tmp是一个sticky directory。

二SUID问题分析

带着疑问,我们来看看Unix、Linux系统上,这几个特殊权限位究竟表示什么?

1suid

其全称是set uid,啥意思呢?就是给文件设置uid,怎么理解?结合上述看到的/u01/app/oracle/product/11.2.0/db_1/bin/oracle文件来说明,就是这个oracle可执行的二进制文件,owner是oracle用户。表示的意思是,我希望当其它用户来执行或者运行这个可执行程序(文件)的时候,其实是相当于以这个文件的owner即oracle用户的身份来调用或者执行的。

同样,对于/bin/ping和/bin/mount:

localhost-> ll /bin/ping
-rwsr-xr-x. 1 root root 40760 Sep 26  2013 /bin/ping
localhost-> ll /bin/mount
-rwsr-xr-x. 1 root root 77336 Nov 22  2013 /bin/mount
localhost-> file /bin/ping
/bin/ping: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
localhost-> file /bin/mount
/bin/mount: setuid ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
localhost-> 

也是同样的道理。操作系统上的其它用户如果调用或者执行这2个可执行程序的时候,事实上相当于是以root用户的身份在执行的。

这样做的好处就是,避免了通过sudo来授予权限。

注意:suid的作用对象,一定是一个可执行的二进制文件。对普通文件无效,且对路径(目录,文件夹)也无效

2如何设置suid权限位
localhost-> pwd
/home/oracle
localhost-> ll afiedt.buf 
-rw-r--r-- 1 oracle oinstall 1777 Jul 16  2019 afiedt.buf
localhost-> 

设置suid:

localhost-> chmod 4644 afiedt.buf 
localhost-> ll afiedt.buf 
-rwSr--r-- 1 oracle oinstall 1777 Jul 16  2019 afiedt.buf
localhost-> 

咦?怎么跑出来个大S,uppercase S?

再继续:

localhost-> chmod u+x afiedt.buf 
localhost-> ll afiedt.buf 
-rwsr--r-- 1 oracle oinstall 1777 Jul 16  2019 afiedt.buf
localhost-> chmod u-x afiedt.buf 
localhost-> ll afiedt.buf 
-rwSr--r-- 1 oracle oinstall 1777 Jul 16  2019 afiedt.buf
localhost-> 

如果文件自己本身就没有执行权限x的话,那么设置SUID之后,其权限位的x位置处,会变为S,反之就是s。

注意:由于这里的afiedt.buf文件只是一个普通文件,这里的suid设置只是一个演示,并没有实际意义。因为SUID对普通文件无效。

3 SUID的工作原理和流程

拿/usr/bin/passwd可执行程序举例。

localhost-> ll /usr/bin/passwd 
-rwsr-xr-x. 1 root root 30768 Feb 22  2012 /usr/bin/passwd
localhost-> 
  • a 这个命令是修改用户的密码的,把新密码写入到/etc/shadow文件;
  • b 操作系统上每个用户都可以执行/usr/bin/passwd来修改自己的密码;注意该文件的other权限位上有x;
  • c /etc/shadow文件只有root用户才有权限进行读写;
  • d 问题来了,普通用户可以执行/usr/bin/passwd,却不能把结果写入到/etc/shadow文件,岂不矛盾?
  • e 于是,在/usr/bin/passwd文件上加SUID,这样普通用户执行该命令的时候,就相当于是以该文件的owner,root身份来执行一样,进而有了root权限,而root用户是有权限写/etc/shadow文件的。进而问题解决。

补充说明:为啥我的/etc/shadow文件root用户没有读写权限呢?

[root@localhost ~]# cat /etc/redhat-release 
CentOS release 6.5 (Final)
[root@localhost ~]# ll /etc/shadow
---------- 1 root root 1499 7月  22 08:09 /etc/shadow
[root@localhost ~]# 

这是因为,从CentOS6开始,操作系统修改了对root用户的权限机制。具体可以参看:

https://unix.stackexchange.com/questions/549464/etc-shadow-permissions-security-best-practice-000-vs-600-vs-640

https://www.stigviewer.com/stig/red_hat_enterprise_linux_6/2015-05-26/finding/V-38504

当然,另外一个Ubuntu的OS就不同了:

root@iZwz96377ws99tjeva00kcZ:~# lsb_release -a
LSB Version:    core-9.20170808ubuntu1-noarch:security-9.20170808ubuntu1-noarch
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.5 LTS
Release:        18.04
Codename:       bionic
root@iZwz96377ws99tjeva00kcZ:~# cat /etc/issue
Ubuntu 18.04.5 LTS \n \l

root@iZwz96377ws99tjeva00kcZ:~# ll /etc/shadow
-rw-r----- 1 root shadow 866 Nov 30  2020 /etc/shadow
root@iZwz96377ws99tjeva00kcZ:~# 

三 sgid

前面的SUID是设置文件owner的权限位上,即让执行该文件的用户,就像是以该文件的owner一样来执行该文件。如果让执行该文件的用户,就像是以该文件的group一样来执行该文件,就是设置sgid了。

具体的设置跟SUID类似,只不过默认情况下sgid的权限用数字来表示就是,2。例如:

localhost-> pwd
/home/oracle
localhost-> ll afiedt.buf 
-rwSr--r-- 1 oracle oinstall 1777 Jul 16  2019 afiedt.buf
localhost-> chmod 2744 afiedt.buf 
localhost-> ll afiedt.buf 
-rwxr-Sr-- 1 oracle oinstall 1777 Jul 16  2019 afiedt.buf
localhost-> chmod g+x afiedt.buf 
localhost-> ll afiedt.buf 
-rwxr-sr-- 1 oracle oinstall 1777 Jul 16  2019 afiedt.buf
localhost-> 

该权限位的主要作用:该权限主要用在路径上,表示的是在具有该权限的路径下,新建出来的文件或者路径,其group都变成该路径的group。如:

localhost-> id
uid=1101(oracle) gid=1000(oinstall) groups=1000(oinstall),1201(asmdba),1300(dba),1301(oper)
localhost-> cd /u01
localhost-> pwd
/u01
localhost-> ll
total 4
drwxrwxr-x. 6 oracle oinstall 4096 Nov 30  2016 app
localhost-> mkdir sgid_dir
localhost-> ll
total 8
drwxrwxr-x. 6 oracle oinstall 4096 Nov 30  2016 app
drwxr-xr-x  2 oracle oinstall 4096 Jul 23 10:44 sgid_dir
localhost-> chmod 2755 sgid_dir/
localhost-> ll
total 8
drwxrwxr-x. 6 oracle oinstall 4096 Nov 30  2016 app
drwxr-sr-x  2 oracle oinstall 4096 Jul 23 10:44 sgid_dir
localhost-> 

然后,以root用户创建文件:touch /u01/sgid_dir/tfile

[root@localhost ~]# touch /u01/sgid_dir/tfile
[root@localhost ~]# ll /u01/sgid_dir/
总用量 0
-rw-r--r-- 1 root oinstall 0 7月  23 10:45 tfile
[root@localhost ~]# 

看到,该文件的group自动变成了sgid_dir路径的group:oinstall了。

另外,在Ubuntu操作系统上:

root@iZwz96377ws99tjeva00kcZ:~# which mlocate 
/usr/bin/mlocate
root@iZwz96377ws99tjeva00kcZ:~# ll /usr/bin/mlocate 
-rwxr-sr-x 1 root mlocate 43088 Mar  2  2018 /usr/bin/mlocate*
root@iZwz96377ws99tjeva00kcZ:~# ll /var/lib/mlocate/mlocate.db 
-rw-r----- 1 root mlocate 4372336 Jul 23 06:25 /var/lib/mlocate/mlocate.db
root@iZwz96377ws99tjeva00kcZ:~# 

普通用户,即other用户,对于/usr/bin/mlocate有执行权限x,当执行该命令时,其实是相当于获取了该文件的group上的sgid,即相当于以该文件的group,mlocate用户组身份来执行,最后去读取了/var/lib/mlocate/mlocate.db该文件。而该文件又是属于mlocate用户组。嗯,权限是这么一步一步关联过来的。

四 sbit

全称是Sticky Bit,”粘滞位”权限。

通常用在/tmp路径上,表示在路径下新建的文件,只有文件的owner或者是root才可以删除。这个很好理解:大家都可以在/tmp路径下写文件,但是我的文件,你不能删除,你的文件我也不能删除。你的文件只能是你自己或者是root才可以删除。

设置该权限位的示例:

localhost-> pwd
/u01
localhost-> ll
total 8
drwxrwxr-x. 6 oracle oinstall 4096 Nov 30  2016 app
drwxr-sr-x  2 oracle oinstall 4096 Jul 23 10:45 sgid_dir
localhost-> chmod 3755 sgid_dir/
localhost-> ll
total 8
drwxrwxr-x. 6 oracle oinstall 4096 Nov 30  2016 app
drwxr-sr-t  2 oracle oinstall 4096 Jul 23 10:45 sgid_dir
localhost-> 

注意,这里的特殊权限位设置的3,表示的sgid位的2和sbit位的1的组合。

五 小结

  • suid只能用在可执行的二进制文件上;对应的权限位数字是4;
  • sgid通常用在路径上,用于文件的共享;对应的权限位数字是2;
  • sbit通常用在/tmp路径上,不能用在文件上,对应的权限位数字是1;

参考链接:

https://www.cnblogs.com/sparkdev/p/9651622.html

https://www.cnblogs.com/jyzhao/p/6077368.html

https://www.cnblogs.com/ftl1012/p/9260157.html

当初,自己在管理维护Oracle数据库过程中,还记得有一次因为s权限位,导致系统故障的,不是很清晰问题原因的情况下,虽然也把问题解决了,但是总觉得是一知半解的,现在搞清楚了。