一、 文件与目录的原始属性
由于不希望文件具有可执行的原始权限,默认情况下,文件是没有可执行(x)权限的,因此文件的原始属性是:-rw-rw-rw(0666)
目录的原始属性全部开放,为:-rwxrwxrwx(0777)
二、 umask
1. 文件的默认属性
在每个用户创建文件时,都有一个默认属性,这个属性是由文件的原始属性减去一个掩码而生成的,通过umask可以查看该用户的掩码,如:
[root@yxyz_test sdz]# umask
0022
或者
[root@yxyz_test test]# umask -S
u=rwx,g=rx,o=rx
这种是符号的方式直接显示用户最多拥有的权限,至于实际拥有的还与上面说的原始权限有关,譬如文件的原始属性中是没有x权限的,因此创建文件时自然也没有该权限。
root的掩码一般是0022(为什么是四位?第一位代表特殊权限,一般都为0),则root创建的文件默认权限是从原来的0666中减去相应的权限,为0644(-rw- r-- r--):
-rw-r--r-- 1 root root 0 Nov 25 09:57 test_file
目录的默认权限是0755(drwx r-x r-x):
drwxr-xr-x 2 root root 4096 Nov 25 09:54 test_dir
2. 修改掩码
(1) 直接在umask后面加上数字,如:
[root@yxyz_test test]# umask 0002
[root@yxyz_test test]# touch test_umask_file
[root@yxyz_test test]# mkdir test_umask_dir
[root@yxyz_test test]# ls -l
drwxrwxr-x 2 root root 4096 Nov 25 10:23 test_umask_dir
-rw-rw-r-- 1 root root 0 Nov 25 10:22 test_umask_file
(2) 如果在 shell 提示符下设置 umask,它将只适用于当前登录会话中的 shell 和 subshell。
但不适用于以后登录的会话。要在登录时自动应用 umask 设置,就需要修改/ets/bashrc 中的内容,但一般不建议修改该文件。
三、 文件特殊权限:SUID/SGID/Sbit
1. Set User ID
使用 ls -l 命令查看文件的访问权限,通常都是rwx ,但有时会发现有些文件的执行权限位不是 "x" 而是 "s". 如:
-rwsr-xr-x 1 root root 22984 Jan 7 2007 /usr/bin/passwd
这说明 /usr/bin/passwd 文件被设置了SUID。SUID 表示"设置用户ID",SGID表示"设置组ID"。当用户执行一个设置了SUID文件时,用户的有效ID在程序运行过程中被置为文件拥有者的用户ID。如果文件属主是 root,当用户在程序的执行过程中就成为 root 用户,有着与 root 同样的权限。同样,当一个用户执行设置了SGID文件时,用户的属组在程序执行过程中被置为文件的属组。
根据现在的Unix机里,脚本是无法设置SUID/SGID的,因为真正运行的进程是脚本的解释程序而不是脚本本身;而bash shell script 在先天上不支持SUID/SGID,但/bin/zsh是支持SUID/SGID的。perl亦如此。
2. Set Group ID
s的权限如果是在用户组,那么就是SGUID,可以用在两个方面:
(1) 文件:如果SGUID设置在二进制文件上,则不论用户是谁,在执行该程序的时候,它的有效用户组id(effective group id)将会变成该程序的用户组所有者(group id);
(2) 目录:如果是设置在目录上,则这个目录内所建立的文件或目录的用户组,将是此目录的用户组。
一般来说SGUID多用在特定的多人团队的项目开发上,在系统中用得较少。
3. Sticky Bit
SBit当前只对目录有效,对文件没有效果。对目录的作用是:“在具有SBit的目录下,用户若在该目录下具有w和x权限,则当用户在该目录下建立文件或目录时,只有文件拥有者与root才有权利删除”。
例如,/tmp 本身的属性是drwxrwxrwt 4 root root 724992 Nov 25 15:10 /tmp,在tmp里谁都可以新增或者修改文件,但仅有该文件/目录的创建者或者root能删除。
4. SUID/SGID/Sbit 权限设置
在文章开始说到umask的时候,提到掩码的第一位是特殊权限位,因为创建任何文件时,原始属性中是没有设置特殊权限的,因此在umask中,第一位始终是0。而在特殊权限中,不同的权限也是用数字来表示的,SUID为4,SGUID为2,SBit为1。(注意,在设置特殊权限位之前,相应的执行权限位(x)必须要被设置,不然设置的特殊权限位也会无效,试想一下,拥有者都无法执行了,哪里给别人执行的权限?)
例如,如果有文件test_uid,
-rwxr-xr-x 1 root root 0 Nov 25 15:23 test_uid
要增加s权限,则要在原来的权限755之前加多一个4,即4775,则
chmod 4755 test_uid 或者用符号的形式:
chmod u+s test_uid
得到的最终属性是:
-rwsr-xr-x 1 root root 0 Nov 25 15:23 test_uid
如果想为目录设置Sbit为,如
drwxr-xr-x 2 root root 4096 Nov 25 16:11 test_sbit
则可以用chmod 1755 test_sbit或者chmod o+t test_sbit,得到:
drwxr-xr-t 2 root root 4096 Nov 25 16:11 test_sbit
5. 改变所有权对特殊权限位的影响
在改变一个文件的所有权时,相应的SUID/SGID也将被清除,这是出于安全性的考虑。
四、 关于进程运行时的有效用户id和有效组id
如果普通文件myfile是属于foo用户的,是可执行的,现在没设SUID位,ls -l命令显示如下:
-rwxr-xr-x 1 foo staff 7734 Apr 05 17:07 myfile
任何用户都可以执行这个程序。UNIX的内核是根据什么来确定一个进程对资源的访问权限的呢?是这个进程的运行用户的(有效)ID,包括user id和group id。用户可以用id命令来查到自己的或其他用户的user id和group id。
除了一般的user id和group id外,还有两个称之为effective 的id,就是有效id,上面的四个id表示为:uid,gid,euid,egid。内核主要是根据euid和egid来确定进程对资源的访问权限。
一个进程如果没有SUID或SGID位,则euid=uid egid=gid,分别是运行这个程序的用户的uid和gid。例如kevin用户的uid和gid分别为204和202,foo用户的uid和gid为200,201,kevin运行myfile程序形成的进程的euid=uid=204,egid=gid=202,内核根据这些值来判断进程对资源访问的限制,其实就是kevin用户对资源访问的权限,和foo没关系。
如果一个程序设置了SUID,则euid和egid变成被运行的程序的所有者的uid和gid,例如kevin用户运行myfile,euid=200,egid=201,uid=204,gid=202,则这个进程具有它的属主foo的资源访问权限。
SUID的作用就是这样:让本来没有相应权限的用户运行这个程序时,可以访问他没有权限访问的资源。passwd就是一个很鲜明的例子。
SUID的优先级比SGID高,当一个可执行程序设置了SUID,则SGID会自动变成相应的egid。
下面讨论一个例子:
UNIX系统有一个/dev/kmem的设备文件,是一个字符设备文件,里面存储了核心程序要访问的数据,包括用户的口令。所以这个文件不能给一般的用户读写,权限设为:cr--r----- 1 root system 2, 1 May 25 1998 kmem
但ps等程序要读这个文件,而ps的权限设置如下:
-r-xr-sr-x 1 bin system 59346 Apr 05 1998 ps
这是一个设置了SGID的程序,而ps的用户是bin,不是root,所以不能设置SUID来访问kmem,但大家注意了,bin和root都属于system组,而且ps设置了SGID,一般用户执行ps,就会获得system组用户的权限,而文件kmem的同组用户的权限是可读,所以一般用户执行ps就没问题了。但有些人说,为什么不把ps程序设置为root用户的程序,然后设置SUID位,不也行吗?这的确可以解决问题,但实际中为什么不这样做呢?因为SGID的风险比SUID小得多,所以出于系统安全的考虑,应该尽量用SGID代替SUID的程序,如果可能的话。
五、 安全性
SUID虽然很好了解决了一些问题,但是同时也会带来一些安全隐患。因为设置了 SUID 位的程序如果被攻击(通过缓冲区溢出等方面),那么hacker就可以拿到root权限。因此在安全方面特别要注意那些设置了SUID的程序。
六、参考
1. 《shell十三问》
(完)