SUID Set User ID, SGID Set Group ID的意思。

例子:

ls -l myfile显示为:

-rwxr-x--- 1 foo staff 7734 Apr 05 17:07 myfile

表示文件myfile是普通文件,文件的所有者是foo用户,而foo用户属于staff组,文件只有1个硬连接,长度是7734个字节,最后修改时间4517:07


所有foo对文件有读写执行权限,staff组的成员对文件有读和执行权限,其他的用户对这个文件没有权限。


如果一个文件被设置了SUIDSGID位,会分别表现在所有者同组用户的权限可执行位上。例如:

1-rwsr-xr-x 表示SUID和所有者权限中可执行位被设置

2-rwSr--r-- 表示SUID被设置,但所有者权限中可执行位没有被设置

3-rwxr-sr-x 表示SGID和同组用户权限中可执行位被设置

4-rw-r-Sr-- 表示SGID被设置,但同组用户权限中可执行位没有被设置


给文件加SUIDSGID的命令如下:


chmod u+s filename设置SUID

chmod u-s filename 去掉SUID设置

chmod g+s filename 设置SGID

chmod g-s filename 去掉SGID设置


由于SUIDSGID是在执行程序(程序的可执行位被设置)时起作用,而可执行位只对普通文件目录文件有意义,所以设置其他种类文件的SUIDSGID位是没有多大意义的。


首先讲普通文件SUIDSGID的作用。例子:


如果普通文件myfile是属于foo用户的,是可执行的,现在没设SUID位,ls命令显示如下:

-rwxr-xr-x 1 foo staff 7734 Apr 05 17:07 myfile 任何用户都可以执行这个程序。

UNIX的内核是根据什么来确定一个进程对资源的访问权限的呢?是这个进程的运行用户的(有效)ID,包括user idgroup id。用户可以用id命令来查到自己的或其他用户的user idgroup id除了一般的user id group id外,还有两个称之为effective id,就是有效id,上面的四个id表示为:uidgideuidegid。内核主要是根据euidegid来确定进程对资源的访问权限一个进程如果没有SUIDSGID位,则euid=uid egid=gid,分别是运行这个程序的用户的uidgid


例如kevin用户的uidgid分别为204202foo用户的uidgid200201kevin运行myfile程序形成的进程的euid=uid=204egid=gid=202,内核根据这些值来判断进程对资源访问的限制,其实就是kevin用户对资源访问的权限,和foo没关系。


如果一个程序设置了SUIDeuidegid变成被运行的程序的所有者的uidgid例如kevin用户运行myfileeuid=200egid=201uid=204gid=202,则这个进程具有它的属主foo的资源访问权限。


SUID的作用就是这样:让本来没有相应权限的用户运行这个程序时,可以访问他没有权限访问的资源。SUID的优先级比SGID高,当一个可执行程序设置了SUID,则SGID会自动变成相应的egid


如果一个目录设置了SGID位,那么如果任何一个用户对这个目录有写权限的话,他在这个目录所建立的文件的组都会自动转为这个目录的属主所在的组,而文件所有者不变,还是属于建立这个文件的用户。


SUID/SGID :


假如你有文件a.txt


#ls -l a.txt

-rwxrwxrwx


#chmod 4777 a.txt

-rwsrwxrwx ======>注意s位置


#chmod 2777 a.txt

-rwxrwsrwx ======>注意s位置


#chmod 7777 a.txt

-rwsrwxswt ======>出现了t,t的作用在内存中尽量保存a.txt,节省系统再加载的时间.


本来是只有root用户才能执行的命令,加了SUID,普通用户就可以像root一样的用,权限提升了。上面是对于文件来说的,对于目录也差不多

目录S属性使得在该目录下创建的任何文件及子目录属于该目录所拥有的组,目录的T属性使得该目录的所有者及root才能删除该目录


有效用户ID和有效组ID则决定了进程在运行时的权限。内核在决定进程是否有文件存取权限时,是采用了进程的有效用户ID来进行判断的。当一个程序设置了为SUID位时,内核就知道了运行这个程序的时候,应该认为是文件的所有者在运行这个程序。即该程序运行的时候,有效用户ID是该程序的所有者。举个例子:

ping命令应用广泛,可以测试网络是否连接正常。ping在运行中是采用了ICMP协议,需要发送ICMP报文。但是只有root用户才能建立ICMP报文,如何解决这个问题呢?同样,也是通过SUID位来解决。

[root@sgrid5 bin]# ls -l /bin/ping

-rwsr-sr-x 1 root root 28628 Jan 25 2003/bin/ping

我们可以测试一下,如果去掉pingSUID,再用普通用户去运行命令,看会怎么样。

[root@sgrid5 bin]#chmod u-s /bin/ping

[root@sgrid5 bin]# ls -l ping

-rwxr-xr-x 1 root root 28628 Jan 25 2003ping

[root@sgrid5 bin]#su test

[test@sgrid5 bin]$ ping byhh.net

ping: icmp open socket: Operation not permitted

SUID虽然很好的解决了一些问题,但是同时也会带来一些安全隐患。


通过以下的命令可以找到系统上所有的设置了suid的文件

[root@sgrid5 /]# find / -perm -04000 -type f -ls

对于这里为什么是4000,大家可以看一下前面的st_mode的各bit的意义就明白了。