用示例解释Linux中的SUID和SGID
想象一下这样一种情况,我们有一个脚本或者可执行文件始终需要由特定用户运行,仅因为该用户对该脚本所执行的操作具有适当的访问权限。
我们还希望其他用户能够执行该脚本,但最终需要以脚本的原始用户身份运行该脚本(因为该用户仅具有执行操作所需的权限集)。
默认情况下,Linux应用程序和程序以与执行它的用户完全相同的权限运行。
由于这个原因,对于上述情况,我们需要一个好的解决方案(即:所有用户都应该能够执行特定用户拥有的程序,就像所有者自己执行了该程序一样)。
这就是SUID出现的地方。
SUID只是Linux中可用的特殊权限位,可以很容易地实现这一点。
如果我们是可执行文件的所有者,则在设置SUID权限的帮助下,其他用户将在许可下而不是在许可下运行该可执行文件。
SUID通常在Linux中使用,用于在执行期间临时提供提升的特权。
这种特权提升根本不是永久的。
仅在执行程序/脚本时,它才是临时高度。
具有SUID权限位设置的Linux中的可执行文件示例
-rwsr-xr-x 1根目录34904 2014年3月12日/bin/su-rwsr-xr-x 1根目录40760 2013年9月26日/bin/ping-rwsr-xr-x 1根目录77336 2014年4月28日/bin/mount-rwsr-xr-x 1根目录2014年4月28日/bin/umount-rwsr-xr-x 1根目录66352 2011年12月7日/usr/bin/chage-rwsr-xr-x 1根目录30768 2012年2月22日/usr/bin/passwd --- s--x--x 1个根目录123832 2013年11月22日/usr/bin/sudo-rwsr-xr-x 1个根目录51784 2013年11月23日/usr/bin/crontab
让我们通过一个例子来理解这一点。
从上面的可执行文件列表中,/usr/bin/passwd是系统中所有用户都应该可执行的文件(这是因为所有用户都应该能够更改自己的密码)。
如果我们不知道密码在Linux中的工作方式,建议阅读以下文章。
阅读:密码在Linux中的工作方式
更新用户密码要求用户在linux中编辑/etc/passwd,/etc/shadow文件。
但是,这仅适用于root用户。
这就是将SUID位应用于文件/usr/bin/passwd的原因。
由于root是该文件的所有者,并且在该文件上设置了SUID,因此任何执行/usr/bin/passwd命令的用户都将以root用户身份执行该文件。
让我们实际来看一下。
下面显示的是名为sarath的用户触发的passwd命令。
让我们看看是否以root用户身份执行了passwd命令过程。
[sarath@localhost ~]$passwd Changing password for user sarath. Changing password for sarath. (current) UNIX password:
让我们打开另一个终端,并启动ps aux commad,以查看root用户是否正在运行passwd命令进程。
可以如下所示进行。
[sarath@localhost ~]$ps aux | grep passwd root 24531 0.0 0.0 156928 1664 pts/0 S+ 07:24 0:00 passwd
我们可以清楚地看到root用户正在运行passwd命令进程(从上述输出的第一个字段可见)。
与passwd命令类似,先前显示的SUID应用文件列表中的任何命令将始终在文件所有者的许可下运行,而不考虑执行该文件的用户。
还要注意一个事实,即使ping命令也是SUID(请参见上面给出的初始列表),这是因为PING执行需要几个网络操作,这些操作只能由root用户执行。
如何在Linux中配置SUID?
只需一个CHMOD命令即可在所需的文件/脚本上配置SUID。
[sarath@localhost ~]$chmod u+s /path/to/file/or/executable
将上面命令中的“/path/to/file/or/executable”替换为需要SUID位打开的脚本的绝对路径。
这也可以通过使用chmod的数值方法来实现。
[sarath@localhost ~]$chmod 4755 /path/to/file/or/executable
“ 4755”中的第一个“ 4”表示SUID。
数值方法的另一个示例如下所示。
[sarath@localhost ~]$chmod 4750 /path/to/file/or/executable
基本上,在数值方法中,只需将4添加到该文件上所需的其他权限集之前即可。
如何验证SUID是否应用于文件?
我们可以使用ls命令验证SUID位是否应用于文件,如下所示。
root@ip-10-12-2-217:# cd /usr/bin root@ip-10-12-2-217:/usr/bin# ls -l passwd -rwsr-xr-x 1 root root 47032 May 15 2014 passwd
ls -l命令应显示是否应用了SUID。
只需查看ls -l输出的第一个字段。
-rwsr-xr-x中的s表示SUID位。
在某些情况下,我们会看到大写字母S而不是上面看到的小写字母s。
大写S表示没有适用于该文件/或者脚本的可执行权限。
root@ip-10-12-2-217:/usr/bin# chmod -x passwd root@ip-10-12-2-217:/usr/bin# ls -l passwd -rwSr--r-- 1 root root 47032 May 15 2014 passwd
我们可以从上面的输出中清楚地看到,从/usr/bin/passwd文件中删除可执行文件许可权后,ls -l的输出变为大写S。
在该文件上添加可执行文件许可权将使其变小,如下所示。
root@ip-10-12-2-217:/usr/bin# chmod +x passwd root@ip-10-12-2-217:/usr/bin# ls -l passwd -rwsr-xr-x 1 root root 47032 May 15 2014 passwd
如何查找所有在Linux中启用了SUID位的文件?
我们可以使用以下find命令来搜索系统中已启用SUID位的所有文件。
root@ip-10-12-2-217:~# find/-perm -4000 -exec ls -l {} \;
将上述命令中的第一个/替换为所需位置,以查找该位置中的所有SUID文件。
例如,要在/usr/bin中查找所有具有SUID的文件,请运行以下命令。
root@ip-10-12-2-217:~# find /usr/bin/-perm -4000 -exec ls -l {} \; -rwsr-xr-x 1 root root 68152 May 15 2014 /usr/bin/gpasswd -rwsr-sr-x 1 daemon daemon 51464 Oct 21 2013 /usr/bin/at -rwsr-xr-x 1 root root 155008 Aug 27 2014 /usr/bin/sudo -rwsr-xr-x 1 root root 41336 May 15 2014 /usr/bin/chsh -rwsr-xr-x 1 root root 23104 Jan 7 2014 /usr/bin/traceroute6.iputils -rwsr-xr-x 1 root root 47032 May 15 2014 /usr/bin/passwd -rwsr-xr-x 1 root root 75256 Oct 21 2013 /usr/bin/mtr -rwsr-xr-x 1 root root 46424 May 15 2014 /usr/bin/chfn -rwsr-xr-x 1 root root 23304 Nov 24 21:15 /usr/bin/pkexec -rwsr-xr-x 1 root root 32464 May 15 2014 /usr/bin/newgrp
请记住,Linux目录中的SUID位会被忽略。
SGID与SUID非常相似。
唯一的区别是,配置了SGID的脚本/文件将在组所有者相同的权限下运行。
如果在控制器上设置SGID,则在该目录内创建的所有文件或者目录将归同一公共组(配置了SGID的目录的组所有者)所有。
Linux中SGID文件的示例
-rwxr-sr-x 3 root mail 14592 Dec 3 2012 /usr/bin/mail-unlock -rwxr-sr-x 1 root utmp 421768 Nov 7 2013 /usr/bin/screen -rwxr-sr-x 1 root shadow 23360 Jul 15 2015 /usr/bin/expiry -rwxr-sr-x 1 root mail 14856 Dec 7 2013 /usr/bin/dotlockfile -rwxr-sr-x 3 root mail 14592 Dec 3 2012 /usr/bin/mail-lock -rwsr-sr-x 1 daemon daemon 51464 Oct 21 2013 /usr/bin/at -rwxr-sr-x 1 root shadow 54968 Jul 15 2015 /usr/bin/chage -rwxr-sr-x 1 root mlocate 39520 Jun 20 2013 /usr/bin/mlocate -rwxr-sr-x 1 root tty 14688 Jun 4 2013 /usr/bin/bsd-write -rwxr-sr-x 1 root ssh 284784 Jan 13 16:39 /usr/bin/ssh-agent -rwxr-sr-x 3 root mail 14592 Dec 3 2012 /usr/bin/mail-touchlock -rwxr-sr-x 1 root tty 19024 Sep 2 2015 /usr/bin/wall -rwxr-sr-x 1 root crontab 35984 Feb 9 2013 /usr/bin/crontab
如何在Linux中配置SGID?
类似于SUID,可以使用chmod命令配置SGID,如下所示。
root@localhost:~# chmod g+s /path/to/file
将上述命令中的“/path/to/file”替换为我们需要SGID位的脚本的绝对路径。
这也可以通过使用chmod的数值方法来实现(如下所示)。
root@localhost:~# chmod 2755 /path/to/file
如何验证SGID是否应用于文件或者脚本?
与SUID相似,我们可以轻松地在文件/目录上执行ls -l命令来查找是否启用了SGID。
下面显示的示例显示了相同的内容。
root@ip-10-12-2-217:# cd /usr/bin root@ip-10-12-2-217:/usr/bin# ls -l chage -rwxr-sr-x 1 root shadow 54968 May 15 2014 chage
about输出(-rwxr-sr-x)中第一个字段的小s部分表示SGID位。
与SUID相似,如果我们没有对该组应用可执行权限,则它将为大写S而不是小写,如下所示。
root@ip-10-12-2-217:/usr/bin# chmod g-x chage root@ip-10-12-2-217:/usr/bin# ls -l chage -rwxr-Sr-x 1 root shadow 54968 May 15 2014 chage
并在组上启用可执行权限将使其变小(如下所示)。
root@ip-10-12-2-217:/usr/bin# chmod g+x chage root@ip-10-12-2-217:/usr/bin# ls -l chage -rwxr-sr-x 1 root shadow 54968 May 15 2014 chage
如何在配置了SGID的Linux中查找所有文件?
我们可以使用以下find命令在Linux操作系统中搜索所有配置了SGID位的文件。
root@ip-10-12-2-217:~# find/-perm -2000 -exec ls -l {} \;
需要SGID或者SUID的脚本/应用程序必须格外小心地编写。
因为这对于整个操作系统来说可能是一个很大的安全漏洞。