# linux的文件权限及符号
# 普通权限
r
-读
w
-写
x
-执行。
注意:x权限对于目录来说是进入目录的权限。比如用root创建一个目录,去掉x权限,普通用户即使有r权限,也无法进入该目录。
# 特殊权限
有三个:SUID
,SGID
,Sticky
,其中SUID
,SGID
在ls
命令中显示为s
或大写S
,SUID
显示为t
或大写T
。
# SUID
内核在确定进程的访问权限时,会看进程的euid和egid(effective id,有效id)。一个文件如果设置了SUID,它的euid等于该文件所属用户的uid,如果未设置,则等于当前用户的uid,gid同理。
比如用户bob的uid是1003,gid是1003,文件myfile的权限如下:
-rw-rw-r-- 1 bob bob 3 Jan 23 07:32 myfile
此时myfile的所属用户是bob,未设置SUID,则euid=bob的uid=1003。
如果给myfile设置了SUID位,当另一个用户tom(uid为1005)来运行myfile时,原本uid应为tom的1005,但由于设置了SUID,myfile的所属用户是bob,所以此时euid=bob的uid=1003
root@ubuntu01:/tmp# chmod u+s myfile
root@ubuntu01:/tmp# ls -al myfile
-rwSrw-r-- 1 bob bob 3 Jan 23 07:32 myfile
最常见的一个例子:用户的密码保存在/etc/shadow,但此文件只有root才能写,普通用户要修改密码时就通过SUID位临时获取root权限,写入密码。
root@ubuntu01:/tmp# ls -al /usr/bin/passwd
-rwsr-xr-x 1 root root 54256 May 16 2017 /usr/bin/passwd
# 用户位设置了SUID
除了passwd
命令外,ping
,crontab
,mount
等命令都有设置,可通过find / -perm /4000
来查看系统内设置了SUID的文件
需注意的是SUID只对二进制文件
有效,且是临时获取一下权限,进程结束时就释放了。
做个小实验验证下:
编辑文件setuid.c,添加如下代码:
#include <stdio.h>
#include <unistd.h>
#include <time.h>
int main () {
int real = getuid();
int euid = geteuid();
FILE *fp = NULL;
char buff[20];
time_t now = time(NULL);
// 打印用户的uid
printf("The REAL UID =: %d\n", real);
// 打印运行时的uid
printf("The EFFECTIVE UID =: %d\n", euid);
// 格式化一下当前时间
strftime(buff, 20, "%Y-%m-%d %H:%M:%S", localtime(&now));
// 将时间写入只有root权限的文件中
fp = fopen("/root/test.txt", "a");
fputs(("%s",buff), fp);
fputs("\n", fp);
fclose(fp);
// 打印下结果
printf("%s fputs current time to test.txt\n",buff);
}
这段代码很简单:打印下用户的uid和运行时的uid(即内核认可的euid),并将当前的时间写到root目录的test.txt文件中。
首先编译下:
root@ubuntu01:/tmp# gcc -o setuid setuid.c
查看下权限:
root@ubuntu01:/tmp# ls -al setuid
-rwxr-xr-x 1 root root 9120 Jan 23 08:00 setuid
直接运行,可以看到root目录下增加了test.txt,uid是0,euid也是0,且/root/下有一个test.txt,里面写入了当前时间:
root@ubuntu01:/tmp# ./setuid
The REAL UID =: 0
The EFFECTIVE UID =: 0
2019-01-23 08:04:40 fputs current time to test.txt
root@ubuntu01:/tmp# cat /root/test.txt
2019-01-23 08:04:40
切换到bob用户来测试下:
root@ubuntu01:/tmp# su bob
bob@ubuntu01:/tmp$ ./setuid
The REAL UID =: 1003
The EFFECTIVE UID =: 1003
Segmentation fault (core dumped)
可以看到,uid和euid都是1003,由于普通用户无权限写入/root/test.txt,所以报错Segmentation fault
了。
此时设置setuid的SUID,再用bob用户来运行试试:
# 设置SUID
root@ubuntu01:/tmp# chmod u+s setuid
root@ubuntu01:/tmp# ls -al setuid
-rwsr-xr-x 1 root root 9120 Jan 23 08:00 setuid
# 切换到bob来运行
root@ubuntu01:/tmp# su bob
bob@ubuntu01:/tmp$ ./setuid
The REAL UID =: 1003
The EFFECTIVE UID =: 0
2019-01-23 08:10:14 fputs current time to test.txt
bob@ubuntu01:/tmp$ exit
exit
# 看下是否写入到了/root/test.txt
root@ubuntu01:/tmp# cat /root/test.txt
2019-01-23 08:04:40
2019-01-23 08:10:14
可以看到当前的uid是1003,但运行时的uid变成0了,且将时间写到了/root/test.txt 中。
# SGID
sgid对文件设置时和suid的用途一致,对目录设置时,其作用是:在该目录下创建的文件将继承该目录属组的权限,而非创建者本身
。
可做个列子验证下:
1.在tmp目录下创建一个sgid目录,且设置SGID:
root@ubuntu01:/tmp# mkdir sgid
root@ubuntu01:/tmp# chmod o+w sgid
root@ubuntu01:/tmp# chmod g+s sgid
root@ubuntu01:/tmp# ls -al | grep sgid
drwxr-srwx 2 root root 4096 Jan 23 08:39 sgid
2.切换到bob用户,在sgid目录下创建一个文件
root@ubuntu01:/tmp# su bob
bob@ubuntu01:/tmp$ cd sgid
bob@ubuntu01:/tmp/sgid$ touch test
3.查看下权限
bob@ubuntu01:/tmp/sgid$ ls -al test
-rw-rw-r-- 1 bob root 0 Jan 23 08:41 test
可以看到该文件的属组是root
# Sticky
Sticky又称SBIT,其作用是:在该目录创建的文件或目录只有创建者才有权限删除
。
最常见的例子就是/tmp
目录了,所有用户都可以在该目录下创建文件或文件夹,其他用户可以查看,但无法删除。
可以做如下实验:
使用普通用户bob在/tmp目录下创建一个文件test,且权限为777。
切换到另一个普通用户scboy,可以对test进行读写,但无法删除,提示:
rm: cannot remove 'test': Operation not permitted
# 设置SUID,SGID,Sticky
SUID权限位是4,SGID权限位是2,Sticky权限位是1,同时设置SUID和SGID,则为6。
例子: 1.设置myfile的SGID位,用户权限是rwx,组权限是r,其他权限r
# 设置
root@ubuntu01:/tmp# chmod 2744 myfile
# 查看下
root@ubuntu01:/tmp# ls -al myfile
-rwxr-Sr-- 1 bob bob 3 Jan 23 07:32 myfile
2.设置test目录的Sticky为,用户权限是rwx,组权限是rwx,其他权限rwx
root@ubuntu01:/tmp# mkdir test
root@ubuntu01:/tmp# chmod 1777 test
root@ubuntu01:/tmp# ls -al /tmp | grep test
drwxrwxrwt 2 root root 4096 Jan 23 08:53 test
# ACL
如果某个目录配置了ACL权限,通过ls命令查看时,在权限部分会看到有个+
号。
# 安装acl
# CentOS/Fedora/RHEL 中:
yum install acl
# Ubuntu/Debian 中:
apt install acl
查看文件系统是否支持 ACL
root@ubuntu01:/tmp# dumpe2fs -h /dev/md126p2 | grep acl
dumpe2fs 1.42.13 (17-May-2015)
Default mount options: user_xattr acl
加载 ACL 功能
如果 UNIX LIKE 支持 ACL 但是文件系统并不是默认加载此功能,可自己进行添加
root@ubuntu01:/tmp# mount -o remount,acl /
同样也可以将acl加到/etc/fstab中,默认开机加载。
LABEL=/ / ext3 defaults,acl 1 1
# 测试下
1.用root在/tmp下创建一个acldir目录,给普通用户添加访问权限
mkdir acldir
setfacl -m u:bob:x ./acldir/
这时bob就可以进入acldir了
2.查看下该目录的acl信息
root@ubuntu01:/tmp# getfacl ./acldir/
# file: acldir/
# owner: root
# group: root
user::rwx
user:bob:--x
group::r-x
mask::r-x
other::r-x
3.添加组acl权限
setfacl -m g:test:rx ./acldir/
4.删除acl权限
setfacl -x u:bob ./acldir
setfacl -x g:test ./acldir
# 其他特殊符号
- 有时候用ls命令看某个目录或文件时,在权限部分的末尾有个
.
点号,这是开启了selinux时会有的,表示带有SELinux的安全上下文https://blog.csdn.net/xinlongabc/article/details/46801641 - 一个文件如果有多种访问措施,用
+
标记;如果同时用了selinux和acl,用+
标记;如果只有acl,用+
标记。 - 在mac系统中用ls查看时,可能会看到含有
@
符号,这个符号是osx特有的,表示某个文件或目录的一种特有属性,可用xattr
命令来查看。