> Linux教程 > 系统运维 >

linux 文件(文件夹)权限安全

每一个文件有所有者及组编号,set uid ;set gid可以改变用户对文件具有的权限:写和执行.

setuid: 在执行时具有文件所有者的权限.
setgid: 设置目录. 一个目录被标上setgid位,此目录下创建的文件继承该目录的属性.
sticky bit: 该位可以理解为防删除位. 设置sticky bit位后,就算用户对目录具有写权限,但也只能添加文件而不能删除文件。

如何设置:

操作这些标志与操作文件权限的命令是一样的, 都是 chmod. 有两种方法来操作,
1) chmod u+s temp — 为temp文件加上setuid标志. (setuid 只对文件有效,U=用户)
chmod g+s tempdir — 为tempdir目录加上setgid标志 (setgid 只对目录有效,g=组名)
chmod o+t temp — 为temp文件加上sticky标志 (sticky只对文件有效)

2) 采用八进制方式. 这一组八进制数字三位的意义如下,
abc
a – setuid位, 如果该位为1, 则表示设置setuid
b – setgid位, 如果该位为1, 则表示设置setgid
c – sticky位, 如果该位为1, 则表示设置sticky

设置后, 可以用 ls -l 来查看. 如果本来在该位上有x, 则这些特殊标志显示为小写字母 (s, s, t). 否则, 显示为大写字母 (S, S, T)
如:

rwsrw-r– 表示有setuid标志 (rwxrw-r–:rwsrw-r–)
rwxrwsrw- 表示有setgid标志 (rwxrwxrw-:rwxrwsrw-)
rwxrw-rwt 表示有sticky标志 (rwxrw-rwx:rwxrw-rwt)

这三个权限的数字位可以这么理解:在原来的三位权限位前增设一位,表示强制位和冒险位。与原来一样,该位取值亦用加法运算。如,同时设定sid和gid,该位为6.

所以,可以得出

chmod 4777是设sid,user为7,group为7,other为7

chmod 2777是设置gid,user为7,group为7,other为7

chmod 1777是设sticky,user为7,group为7,other为7

常用操作:

1、找出所有危险的目录(设置目录所有人可读写却没有设置sticky位的目录)

find / -perm -0007 -type d

2、找出所有设置了suid的文件

find / -perm -4000 -type f

要删除一个文件,你不一定要有这个文件的写权限,但你一定要有这个文件的上级目录的写权限。也就是说,你即使没有一个文件的写权限,但你有这个文件的上级目录的写权限,你也可以把这个文件给删除,而如果没有一个目录的写权限,也就不能在这个目录下创建文件。

如何才能使一个目录既可以让任何用户写入文件,又不让用户删除这个目录下他人的文件,sticky就是能起到这个作用。stciky一般只用在目录上,用在文件上起不到什么作用。

在一个目录上设了sticky位后,(如/tmp,权限为1777)所有的用户都可以在这个目录下创建文件,但只能删除自己创建的文件,这就对所有用户能写的目录下的用户文件启到了保护的作用。(我当时/tmp没有设sticky位,而在文件上设了,这也就是为什么我为什么设了sticky位,还能删除自己创建的文件的原因了)

要了解 suid/sgid, 必需先了解 process 及 permission.
我们需知道: 每个 process 都有其 effective uid/gid , 以决定其在传统 unix filesystem 中获得的实际 permission .
再, process 是由 binary 产生的, 而 binary 是从 shell / shell script 载入执行.
在正常的情況下, process 的 effective uid/gid 是从 parent 集成, 或简单说是于 shell 的 uid/gid 一样.
shell 的 uid/gid 则是根据 /etc/passwd 的第 3 与 第 4 栏位决定.

当我们有了以上的概念之后, 再来看 suid 对 effective uid/gid 的影响:
若 binary file 带有 suid/sgid 的时候,
其 effective id 就不是从 parent 那边集成, 而是以 binary file 本身的 user/group 为准.

举例而言, 若一个 prog1 的 user/group 都是 root , 但没设 suid/sgid ,
那当一个 uid(500)/gid(500) 的 parent process 执行這个 prog1 的话,
那 effective uid/gid 就是 500 …
但若 prog1 设了 suid/sgid 后, 那其 effective uid/gid 就是 root !

一旦這个 process effective 是 root 的话, 那它对 file system 的 permission 就如脱缰野马般任意奔腾而不受限制了.
因此我才在前面提到木马程式与病毒的例子…
试想一下: 若病毒的 user/group 被设为 root, 然后被一般 user 执行时,
suid/sgid 的有与无将导致什么不同結果?

好了, 由于 suid/sgid 在系统上有其存在的必要性(举 /usr/bin/passwd 与 /etc/shadow 为例),
但同时又有极大的杀伤力, 在应用上要异常小心!
因此, bash shell script 在先天上不支援 suid/sgid .
perl 亦如此, 除非额外再安裝 suid-perl ….

根据现在的Unix原理,脚本是无法设置suid的,因为真正运行的进程是脚本的解释程序而不是脚本本身
当然,理论上可以让脚本的解释程序获得脚本的suid状态并且动态的改变自己的suid属性,然后在脚本运行完毕后再改回去。不过这样的整个系统架构的修改可以说不算小,而且也不符合POSIX规范(POSIX规范中没有允许一个正在运行的进程动态修改自身的suid属性)

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

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

-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的设备文件, 是一个字符设备文件,里面存储了核 心程序要访问的数据,包括用户的口令。所以这个文件不能给一般的用户读写, 权限设为:

crr—- 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的程序,如果可能的话。 下面来说明一下SGID对目录的影响。SUID对目录没有影响。 如果一个目录设置了 SGID位,那么如果任何一个用户对这个目录有写权限的 话,他在这个目录所建立的文件的组都会自动转为这个目录的属主所在的组,而 文件所有者不变,还是属于建立这个文件的用户

————————
find-perm参数

在看linux系统管理技术手册时,遇到一个课后题,提到了find-perm,由此在网上查看了setuid,setgid等知识,做一总结。
讲这个知识都是从命令passwd开始的,linux系统/etc/passwd文件保存了用户信息,/etc/shadow文件保存了各账户密码,两者权限为:
-rw-r–r– 1 root root 1703 2011-04-23 23:55 /etc/passwd
-rw-r—– 1 root shadow 1072 2011-04-23 23:55 /etc/shadow

可以看出,保存密码的文件/etc/shadow文件只有root账户才可以写入,然而在实际中普通账户也可以改变自己的密码,对该文件做了写入。似乎矛盾,这也是这里要讲的重点。

在linux中,设置或更给密码,是先写到/etc/passwd文件中,然后通过pwconv命令转换到/etc/shadow文件。而/etc/passwd文件中原来打XX的地方变成了真正的加密密码。

其实,普通用户能够修改密码,不在于是否对/etc/shadow有写入的权限,而在于命令passwd,看一下passwd命令的权限:
-rwsr-xr-x 1 root root 37100 2011-02-15 06:12 /usr/bin/passwd
可以看出,这个命令有一个特殊权限 s ,存在与文件所有者权限位上,这就是一类特殊的权限SetUid。可以这样理解:当一个用户执行passwd命令时,在程序执行的瞬间,权限提升到了root,执行结束后就释放root权限。
在这里以touch命令做一解释:
首先给touch命令SetUid特殊权限:
$sudo chmod g+s /bin/touch 或 $sudo chmod 6755 /bin/touch
看一下touch命令权限:
修改前:-rwxr-xr-x 1 root root 42592 2010-06-11 15:11 /bin/touch
修改后:-rwsr-sr-x 1 root root 42592 2010-06-11 15:11 /bin/touch
看到touch命令权限用户和组都有了特殊权限 s ,SetUid ,SetGid。
$mkdir text
$cd text
$touch file1
看一下file1权限:
-rw-r–r– 1 root root 0 2011-04-29 13:11 file1
看出用户和组都变为root。
恢复touch命令原有权限:$sudo chmod 755 /bin/touch,再创建file2文件,对比:
-rw-r–r– 1 root root 0 2011-04-29 13:11 file1
-rw-r–r– 1 ubuntu ubuntu 0 2011-04-29 13:14 file2
可以看出,具有setuid权限的touch命令,创建的文件用户和群组都是root,而在创建该文件的时候我们并没有使用到root账户却创建出了root权限的文件。
作为系统管理员,应该严格限制SetUid权限的使用。

下面介绍下SetGid和sticky bit
setgid: 该权限只对目录有效. 目录被设置该位后, 任何用户在此目录下创建的文件都具有和该目录所属的组相同的组.
sticky bit: 该位可以理解为防删除位. 一个文件是否可以被某用户删除, 主要取决于该文件所属的组是否对该用户具有写权限. 如果没有写权限, 则这个目录下的所有文件都不能被删除, 同时也不能添加新的文件. 如果希望用户能够添加文件但同时不能删除文件, 则可以对文件使用sticky bit位. 设置该位后, 就算用户对目录具有写权限, 也不能删除该文件.
下面说一下如何操作这些标志:
操作这些标志与操作文件权限的命令是一样的, 都是 chmod. 有两种方法来操作,
1) chmod u +s temp — 为temp文件加上setuid标志. (setuid 只对文件有效)
chmod g +s tempdir — 为tempdir目录加上setgid标志 (setgid 只对目录有效)
chmod o +t temp — 为temp文件加上sticky标志 (sticky只对文件有效)
2) 采用八进制方式. 对一般文件通过三组八进制数字来置标志, 如 666, 777, 644等. 如果设置这些特殊标志, 则在这组数字之外外加一组八进制数字. 如 4666, 2777等. 这一组八进制数字三位的意义如下,
abc
a – setuid位, 如果该位为1, 则表示设置setuid 4xxx
b – setgid位, 如果该位为1, 则表示设置setgid 2xxx
c – sticky位, 如果该位为1, 则表示设置sticky 1xxx

设置完这些标志后, 可以用 ls -l 来查看. 如果有这些标志, 则会在原来的执行标志位置上显示. 如
rwsrw-r– 表示有setuid标志
rwxrwsrw- 表示有setgid标志
rwxrw-rwt 表示有sticky标志
那么原来的执行标志x到哪里去了呢? 系统是这样规定的, 如果本来在该位上有x, 则这些特殊标志显示为小写字母 (s, s, t). 若无执行权限则显示为大写字母 (S, S, T)
要删除一个文件,你不一定要有这个文件的写权限,但你一定要有这个文件的上级目录的写权限。也就是说,你即使没有一个文件的写权限,但你有这个文件的上级目录的写权限,你也可以把这个文件给删除,而如果没有一个目录的写权限,也就不能在这个目录下创建文件。
如何才能使一个目录既可以让任何用户写入文件,又不让用户删除这个目录下他人的文件,sticky就是能起到这个作用。stciky一般只用在目录上,用在文件上起不到什么作用。
在一个目录上设了sticky位后,(如/tmp,权限为1777)所有的用户都可以在这个目录下创建文件,但只能删除自己创建的文件,这就对所有用户能写的目录下的用户文件启到了保护的作用。(我当时/tmp没有设sticky位,而在文件上设了,这也就是为什么我为什么设了sticky位,还能删除自己创建的文件的原因了)

setuid setgid可能带来安全风险,如何查找系统中属于root用户的setuid文件?
运行find正则来查找
/usr/bin/find/ -user root -perm -4000 -print ‘从/根目录开始查找root用户setuid的文件
/usr/bin/find / -user root -perm -4000 -print | /bin/mail -s “Setuid root files” netadmin 结果邮寄
/usr/bin/find / \( -perm -4000 -o -perm -2000 \) > setuidfile ‘查找出的结果导入到文件

另外可以在fstab里面禁止分区使用nosettuid参数进行限制 尽管可以设置 但实际没有效果
在调用mount命令时使用-o nosuid选项,在个别文件系统上禁止setuid和setgid的执行。比较好的想法是,把这个选项用在包含用户主目录的目录上,或者在安装从不太可信的管理域来的文件系统时使用。

这里再介绍下find -perm参数:
$sudo find / -type f -perm -6000

-号表示有1的位置一定要正确匹配,其他无所谓。这里要转成二进制来说,首先6000转成三位的二进制是下面这个样子
110 000 000 000
也就是要求前两个11必须匹配,后面的无所谓。
110 000 000 000
110 110 000 000
都可以。
$sudo find / -type f -perm +6000 > /tmp/setuid.bak

+号的意思是,只要有一个1匹配就行了,也就是说前2位中,只要有一个1就行。
$sudo find / -perm -6000 -o -perm -2000
命令find选项“-perm”为指定文件权限,SetUID权限位对应数字标识4,SetGID权限位对应数字标识为2 ,后面写为“000”标识对所有者所属组, 其他人三类用户的权限不限制;“-o”表示or,就是文件具有SetUID或者具有SetGID都在
搜索之后,生成的搜索结果存放在文件/tmp/setuid.bak中。
另外,如果在一些数据存放的分区想禁用SetUID功能,还可以做如下设置,编辑配置文件/etc/fstab ,找到要设置的分区(如/home)所对应的设置行:
vi /etc/fstab
LABEL=/home /home ext3 defaults 1 2
在设置“defaults”后,添加“nosuid”选项,并重新挂载/home分区
vi /etc/fstab
LABEL=/home /home ext3 defaults,nosuid 1 2
mount -o remount /home
设置后,分区/home上任何可执行文件即使被设置了SetUID权限也无法执行(读者可自行拷贝一个SetUID命令至/home目录下执行试验),在一些存放数据、用来备份等功能的分区上做此设置,可以保护系统安全。

补充: (angelus)

SGID位,文件也是可以被设置为SGID的,比如一个可执行文件为赋予SGID,它就具有所有组的特权,任意存取所有组所能使用的系统资源,复制到拥有

SGID位目录的文件,只有在复制时加上-p参数,才能保留原来的组群设置

还有sticky-bit权限,简单说就是文件的其他用户即使有写权限也无法删除.移动

等,只能被文件所有者删除,移动等

在系统中典型例子就是/tmp(系统临时文件目录)避免不守法用户恣意乱删其他用户放置的文件

SUID占用属主x(执行)位,SGID占用组x位,sticky-bit占用其他x位,

如果该位有x权限,就用小写s,没有就用大写S

用数值设定特殊权限,需要4位8进制数,第一个表示特殊权限,后三位表示基本权限

只说第一位8进制代表权限

0: 不设置特殊权限
1: 只设置sticky
2 : 只设置SGID
3: 只设置SGID和sticky
4 : 只设置SUID
5 : 只设置SUID和sticky
6 : 只设置SUID和SGID
7 : 设置3种权限



(责任编辑:IT)