一、安全上下文

在操作系统中,用户执行某个指令,该指令会调用一系列的进程来完成操作,而当一个进程去访问某个文件时,会判断以下两点:

1.进程的运行者是谁

 

比如用户openstack执行/bin/cat命令来查看/etc/fstab,该程序(cat)就发起了一个进程。

 

[root@localhost tutor]# ls -l `which cat`

-rwxr-xr-x. 1root root 45224 Nov 22  2013 /bin/cat

 

由于cat的属组和属主都是root,如果cat命令发起的进程属于root用户,那么就意味着这些进程可以访问所有root组能访问的文件,而这是不允许的,故cat命令所发起的进程代表的是openstack用户及openstack用户所属的基本组。

 

2. 进程访问的对象

openstack用户执行cat命令去访问/etc/fstab时,文件/etc/fstab本身也有属组和属主,而openstack用户能否访问该文件,取决于openstack用户是否具有对该文件的访问权限。

 

[root@localhost tutor]# ls -l /etc/fstab

-rw-r--r--. 1root root 932 Jul 11 14:15 /etc/fstab

 

文件/etc/fstab的属组和属主都是root,而openstack不属于root组,故openstack用户只能用other组的权限去访问该文件,而other组对此文件有读权限,故openstack用户通过cat命令发起的进程可以访问此文件。

 

通过判断以上两点,来确定某一个用户是否可以访问某个文件,即为安全上下文。

 

二、特殊权限

A. 设置属主的特殊权限(suid

现在考虑这种情况,用户openstack无法访问文件/etc/shadow(该文件存放密码信息,只有管理员有权限访问),但openstack用户可以执行passwd命令来修改密码,而passwd命令代表openstack用户发起了一个进程,将用户修改后的密码保存到/etc/shadow文件中,这样一来似乎openstack用户又具备了访问/etc/shadow权限了,明显于安全上下文的判断相冲突,这是什么原因呢?我们需要引入特殊权限的概念:

 

[root@localhost tutor]# ls -l `which passwd`

-rwsr-xr-x. 1 root root 30768 Feb22  2012 /usr/bin/passwd


这里可以看到passwd命令有一个s权限,s表示的是suid,即set uid。当属主具有s权限时,意味着其他任何用户在执行此程序时,其进程的属主不再是发起者本人,而是这个程序的属主。故当openstack用户执行passwd命令时,passwd所发起的进程就属于passwd这个文件的属主,即root用户,而root用户是可以访问/etc/shadow文件的。

wKioL1Pi79_AygSZAAcAB-wjOIQ377.jpg

 

设置s权限的方式很简单:

chmod u+|-s /path/to/somfile

或者

chmod 4644 /path/to/somfile

有的文件s权限为小写,表示该文件的原有属主有执行权限,有的S则为大写,表示该文件没有执行权限。这里644前面还有一个4,其含义将在本文最后介绍。

 

B. 设置属组的特殊权限(sgid

 

如果某文件的属组有ssgid,表示set gid)权限,意味着执行此程序时,其进程的属组不再是运行者本人所属的基本组,而是进程文件的属组。

设置属组的s权限方式和设置属主的s权限一样:

chmod g+|-s /path/to/somfile

 

设置属组s权限的主要作用,和设置属主s权限不同,它不是为了让某个进程具有访问权限,而是将目录的属组属主,和目录中文件的属组属主分离开。看下面的例子:

 

[root@localhost tutor]# useradd hadoop


[root@localhost tutor]# useradd hive


[root@localhost tutor]# groupadd mygrp

# 创建两个用户hadoophive,创建组mygrp


[root@localhost tutor]# usermod -a -G mygrp hadoop


[root@localhost tutor]# usermod -a -G mygrp hive

# 为用户hadoophive添加额外组mygrp


[root@localhost tutor]# mkdir test


[root@localhost tutor]# ls -ld test

drwxr-xr-x. 2root root 4096 Jul 13 19:49 test


[root@localhost tutor]# chmod g+w test

# 新建目录test,并为test目录添加写权限


[root@localhost tutor]# ls -ld test

drwxrwxr-x. 2root root 4096 Jul 13 19:49 test


[root@localhost tutor]# chown :mygrp test

# test目录的属组改为mygrp


[root@localhost tutor]# ls -ld test

drwxrwxr-x. 2root mygrp 4096 Jul 13 19:49 test


[root@localhost tutor]# su hadoop


[hadoop@localhost tutor]$ cd test


[hadoop@localhost test]$ touch a.hadoop

# 切换到hadoop用户,在test目录下成功创建文件a.hadoop


[hadoop@localhost test]$ ls -l

total 0
-rw-rw-r--. 1hadoop hadoop 0 Jul 13 19:52 a.hadoop

[hadoop@localhost test]$ exit

exit


[root@localhost tutor]# su hive


[hive@localhost tutor]$ cd test


[hive@localhost test]$ touch a.hive

# 再切换到hive用户,成功创建文件a.hive


[hive@localhost test]$ ls -l

total 0
-rw-rw-r--. 1hadoop hadoop 0 Jul 13 19:52 a.hadoop
-rw-rw-r--. 1hive   hive   0 Jul 13 19:53 a.hive
# 可以看到hadoop和hive这两个用户创建的文件和目录本身没有任何关系


[hive@localhost test]$ whoami

hive

[hive@localhost test]$ echo hello >> a.hadoop

bash:a.hadoop: Permission denied
# 当前用户为hive,不能编辑hadoop创建的文件。


 

如果想让用户hive访问a.hadoop,则需要修改hadoop的属主或属组,如果有大量类似的文件都需要修改,则会造成很大的不便,sgid的作用就在这里体现出来了。

 

[root@localhost tutor]# ls test -ld

drwxrwxr-x. 2root mygrp 4096 Jul 13 19:53 test

 

[root@localhost tutor]# chmod g+s test

# test目录的属组添加s属性

 

[root@localhost tutor]# ls test -ld

drwxrwsr-x. 2 root mygrp 4096 Jul 13 19:53 test

 

[root@localhost tutor]# cd test


[root@localhost test]# su hadoop


[hadoop@localhost test]$ touch b.hadoop

# 切换为hadoop用户,然后再创建一个文件


[hadoop@localhost test]$ ls -ld

drwxrwsr-x. 2root mygrp 4096 Jul 13 20:25 .
# 当前目录的属组为mygrp

 

[hadoop@localhost test]$ ll

total 0
-rw-rw-r--. 1hadoop hadoop 0 Jul 13 19:52 a.hadoop
-rw-rw-r--. 1hive   hive   0 Jul 13 19:53 a.hive
-rw-rw-r--. 1hadoop mygrp  0 Jul 13 20:25 b.hadoop
# 此时会发现刚才由hadoop用户创建的文件b.hadoop其属组不再是其基本组了,而变成了mygrp


[hadoop@localhost test]$ exit

exit


[root@localhost test]# su hive


[hive@localhost test]$ echo hello >> b.hadoop


[hive@localhost test]$ cat b.hadoop

Hello
# 用户hive可以编辑hadoop创建的b.hadoop文件了


[hive@localhost test]$ rm b.hadoop

# 用户hive甚至可以删除b.hadoop

 

设置s权限是个比较危险的操作,试想root用户写了一个脚本,其中含有 rm -rf / 这样的操作,然后为该脚本设置了s权限,那么意味着任何用户都可以执行操作系统自杀命令。故不到万不得已的情况,不要随意设置s权限

 

三、粘贴位权限(冒险位权限:sticky

上面的例子中当某个目录的属组有了s权限后,以该属组为附加组的用户,可以随意操作该目录中其他用户创建的文件,这样是很不合适的,于是就引出了另外一个权限:t权限,意为sticky,粘贴位权限。

t权限是附加在other上的权限,表示该权限附加在文件的属主上,即在某个公共目录内,每个用户只能删除自己创建的文件,即使其他用户有写权限,也不能删除该文件。该权限同样也有大小写之分:

小写t:表示原来有执行权限

大写T:表示原来没有执行权限

更改t权限的方法也和s权限一样,格式如下:

chmod o+|-t /path/to/somefile

 

下面来演示一下t权限的使用:


[root@localhost test]# cd ../


[root@localhost tutor]# chmod o+t test

# 使用root用户为test目录增加t权限

 

[root@localhost tutor]# ls -ld test

drwxrwsr-t. 2root mygrp 4096 Jul 13 20:47 test

# 可以看到具有t权限的目录变为蓝底了

 

[root@localhost tutor]# su hadoop


[hadoop@localhost tutor]$ cd test


[hadoop@localhost test]$ touch c.hadoop

# 现在切换回hadoop用户,然后创建c.hadoop文件

 

[hadoop@localhost test]$ exit

exit


[root@localhost tutor]# su hive


[hive@localhost tutor]$ cd test


[hive@localhost test]$ ll

total 0
-rw-rw-r--. 1hadoop hadoop 0 Jul 13 19:52 a.hadoop
-rw-rw-r--. 1hive   hive   0 Jul 13 19:53 a.hive
-rw-rw-r--. 1hadoop mygrp  0 Jul 13 20:47 b.hadoop
-rw-rw-r--. 1hadoop mygrp  0 Jul 13 20:51 c.hadoop


[hive@localhost test]$ echo hello >> c.hadoop


[hive@localhost test]$ cat c.hadoop

Hello
# 再切换到hive用户,可以编辑由hadoop创建的c.hadoop文件

 

[hive@localhost test]$ rm c.hadoop

rm: cannotremove `c.hadoop': Operation not permitted
# 但是hive用户无法创建其他用户创建的文件


 

下面总结一下特殊权限和粘贴权限和属主属组的对应关系:

u位:s权限

g位:s权限

o位:t权限

上述三位对应的sst权限也可以组成一个8进制的数字:

0000

0011

0102

1004

0113

1015

1106

1117

在为文件修改权限时,这个代表sst权限的8进制数放在普通权限的前面,故修改某个文件的权限如果写成如下形式:

chmod 6664/path/to/somefile

它就表示该文件的属主、属组都有s权限、读写权限,其他用户只有读权限。由于sst都属于特殊权限,所以将这三者集中管理,而不是和ugo的普通权限一起管理。

 

下面来举个例子演示一下通过8进制数来修改文件特殊权限的过程:


[root@localhost tutor]# cp /etc/fstab test


[root@localhost tutor]# cd test


[root@localhost test]# ll

-rw-rw-r--. 1hadoop mygrp    6 Jul 13 20:54 c.hadoop
-rw-r--r--. 1root   mygrp 932 Jul 13 21:14 fstab


[root@localhost test]# chmod 6640 fstab


[root@localhost test]# ll

-rw-rw-r--. 1hadoop mygrp    6 Jul 13 20:54 c.hadoop

-rwSr-S---. 1 root  mygrp  932 Jul 13 21:14 fstab

 

注意,sst权限的设置只能通过手动完成,不要通过umask的方式来操作