一、 文件与目录的原始属性

由于不希望文件具有可执行的原始权限,默认情况下,文件是没有可执行(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十三问》

(完)

最新文章

  1. PyQt4学习资料汇总
  2. Keepalived+Redis高可用部署(第二版)
  3. python内置函数每个执行一次
  4. Autofac 解释第一个例子 《第一篇》
  5. bzoj 3109: [cqoi2013]新数独
  6. Android 手写Binder 教你理解android中的进程间通信
  7. LeeCode Algorithm #3 Longest Substring Without Repeating Characters
  8. SHELL中的特殊变量和结构
  9. 一百多道.NET面试题!
  10. QSqlDatabase::addDatabase第一次运行的时候,生成SQLite文件的同时会产生一个默认连接
  11. 前台图片上传展示JS(单张图片展示)
  12. 地图API地址  百度地图开放平台
  13. Python中使用MongoEngine1
  14. 使用ssh服务管理远程主机
  15. mkimage command not found – U-Boot images will not be built
  16. Eclipse导出WAR包
  17. 《Linux 性能及调优指南》1.4 硬盘I/O子系统
  18. Nginx单向认证的安装配置
  19. go语言之进阶篇借助bufio实现按行读取内容
  20. android setContentView

热门文章

  1. 2.Python输入pip命令出现Unknown or unsupported command 'install'问题解决
  2. oracle 卸载操作
  3. mac下的virtualbox启动失败处理
  4. elasticsearch 5.0 获取 TransportClient 操作客户端java API
  5. 设置VS以管理员身份运行
  6. java,js 解unicode
  7. MySQL 加快导入数据
  8. 【BZOJ】1007: [HNOI2008]水平可见直线(凸包)
  9. 06_java之类概述
  10. requests模块session处理cookie 与基于线程池的数据爬取