在 Linux 中权限一共有6种:
- 基本权限 rwx
- 默认权限 umask
- ACL 权限
- sudo 权限
- 文件特殊权限SetUID、SetGID、Sticky BIT
- 文件系统属性 chattr 权限
基本的 rwx 权限也就是读写执行,这是最常见的权限管理,能够满足大部分的权限需求。但当我们对权限管理需要更加细化,或者更加详细的时候就需要利用到其他的权限了。
ACL 权限
ACL 概述
ACL 用来解决用户对文件身份不足的问题。基本解决思路就是单独给用户分配一个对文件的权限。
开启 ACL
在 CentOS7.x 以下的版本使用如下指令:
dumpe2fs -h /dev/sda3
选项:
-h 仅显示超级块中的信息,而不显示磁盘块组的详细信息
...省略部分输出...
Default mount options: user_xattr acl
...省略部分输出...
这代表开启了,只有在 ext4 文件系统上可以使用这个指令,在 xfs 文件系统上无法使用。 若没有开启,手工开启分区的 ACL 权限:
# 重新挂载根分区,并挂载加入 acl 权限
mount -o remount, acl /
或者修改 /etc/fstab 文件,永久开启 ACL 权限:
vi /etc/fstab
UUID=52e8b4d4-a07f-4565-bf27-646c49572b57 / ext4 defaults,acl 0 0
mount -o remount /
ACL 基本命令
getfacl 文件名 查询文件的ACL权限
setfacl 选项 文件名 设定ACL权限
选项:
-m 设定ACL权限
-b 删除ACL权限
-x:用户 删除单个用户的ACL权限
setfacl -m u:用户名:权限 文件名
setfacl -m g:组名:权限 文件名
setfacl -m u:aa:7 /test 给 aa 用户赋予 test 目录的读写执行的ACL权限
setfacl -m u:cc:rx -R soft/ 赋予递归ACL权限,只能赋予目录
-R 递归
setfacl -m d:u:aa:rwx -R /test ACL默认权限。默认权限只能赋予目录
例如:
[root@localhost ~]# setfacl -m u:aa:7 test
[root@localhost ~]# getfacl test
# file: test
# owner: root
# group: root
user::rw-
user:aa:rwx aa用户对test的acl权限
group::r--
mask::rwx
other::r--
另外命令中递归与默认的区别如下:
setfacl -m u:cc:rx -R soft/ 只对已存在的文件生效
setfacl -m d:u:aa:rwx -R /test 只对以后新建的文件生效
注意: 如果给目录赋予 acl 权限,两条命令都要输入
ACL 权限递归赋予的风险
ACL 权限,一旦使用递归赋予之后,不可避免的出现权限溢出问题,这会造成一些安全隐患。所谓的权限溢出就是,例如给一个目录递归赋予执行权限,那么他里面的所有文件都会拥有执行权限,而对于文件来说执行权限是比较大的权限了。如果我们想要单独给目录 5 权限,文件给 4 权限,这里我们就需要一个一个改了。
最大有效权限 mask
使用 mask 的值和用户 acl 权限、组权限进行逻辑与,得到的有效权限,即限制能够获取的最大权限。建议不要去改动这个值,不然容易搞混。
# 设定mask权限为---。使用“m:权限”格式
[root@localhost ~]# setfacl -m m:0 test
[root@localhost ~]# getfacl test
# file: test
# owner: root
# group: root
user::rw-
# aa用户虽然有rwx权限,但是mask为0,所有他的实际有效权限也为0;组权限也一样。
user:aa:rwx #effective:---
group::r-- #effective:---
mask::---
other::r--
删除 ACL 权限
# 删除指定用户和用户组的ACL权限
setfacl -x u:aa /test
# 删除文件的所有ACL权限
setfacl -b /test
sudo 授权
这是给普通用户赋予部分管理员权限,例如
/sbin/ 和 /usr/sbin/ 在此目录下命令只有超级用户才能使用,通过 sudo 授权可以让普通用户也能使用。
原则:
- 赋予的权限越详细,普通用户得到的权限越小。
- 赋予的权限越简单,普通用户得到的权限越大。
root 身份
visudo 赋予普通用户权限命令,命令执行后和vi一样使用
...省略部分内容...
# 用户名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)
root ALL=(ALL) ALL
# 组名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)
%wheel ALL=(ALL) ALL
| 参数名 | 用法意义 |
|---|---|
| 用户名/组名 | 代表 root 给哪个用户或用户组赋予命令,注意组名前门加 % |
| 被管理主机的地址 | 用户可以用指定命令管理指定 IP 地址的服务器。如果写 ALL,代表可以管理任何主机,如果写固定 IP,代表用户可以管理指定的服务器。对于一台独立服务器,这里写 ALL 和你服务器的 IP 地址作用是一样的。若写的是本机的 IP 地址,这代表指定的用户可以从任何 IP 地址来管理当前服务器。 |
| 可使用身份 | 就是把来源用户切换成什么身份使用,(ALL)代表可以切换成任意身份。可以省略,省略代表 root。 |
| 授权命令 | 代表 root 把什么命令授权给普通用户。默认为 ALL 代表任何命令,这里一定要写命令的绝对路径。 |
例子
- 如果授权用户 user1 可以重启服务器,则 root 用户可以添加如下行:
# 使用root用户授权
[root@localhost ~]# visudo
user1 ALL= /sbin/shutdown -r now
# user1查看可用的授权
[user1@localhost ~]$ sudo -l
# user1通过以下命令执行授权命令
[user1@localhost ~]$ sudo shutdown -r now
- 授权一个用户管理你的 Web 服务器,首先需要授权用户管理 Apache 至少需要哪些基本授权(适用于CentOS6.x):
- 可以使用 Apache 管理脚本
- 可以修改 Apache 配置文件
- 可以更新网页内容
假设 Apache 管理脚本程序为
/etc/rc.d/init.d/httpd满足条件一:
[root@localhost ~]# visudo
user1 ALL= /etc/rc.d/init.d/httpd reload, \
/etc/rc.d/init.d/httpd configtest
# \ 代表一行未完成。
满足条件二:
[root@localhost ~]# visudo
user1 ALL= /usr/bin/vim /etc/httpd/conf/httpd.conf
授权用户 user1 可以用 root 身份使用 vim 编辑 Apache 配置文件。
注意:授权命令一定要细化到选项和参数,不然上面的 vim 编辑 Apache 配置文件的命令改为,user1 ALL= /usr/bin/vim 这样的话,那么普通用户就可以以 root 的身份运行 vim 去查看编辑任何文件,这是非常危险的。
条件三则只需要将网页存放的目录修改权限,授权 user1 具有写权限或者更改目录所有者为 user1即可。
- 授权 aa 用户可以添加其他普通用户 在 visudo 下面添加下面的命令:
aa ALL= /usr/sbin/useradd 赋予 aa 添加用户权限。
#aa ALL= /usr/bin/passwd 赋予改密码权限,这样添加是不行的,这样 root 本身的密码也能被修改。
aa ALL= /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd "", !/usr/bin/passwd root
#上面这样就取消了用户修改 root 密码的权限。
文件特殊权限SetUID、SetGID、Sticky BIT
SetUID、SetGID不建议手工赋予,因为如果赋予不当,会有相当大的安全隐患,所以了解即可。
下面是三种权限的标示位:
| 类别 | 字符表示 | 数字表示 | 叠加位置 |
|---|---|---|---|
| SetUID | s | 4 | User的 x 位 |
| SetGID | s | 2 | Group的 x 位 |
| Sticky BIT | t | 1 | Other的 x 位 |
若字符表示为大写的话,则表示该文件没有 x 权限。
SetUID
SetUID的功能为:
- 只有可执行的二进制程序才能设定 SUID 权限(给没有 x 权限的文件赋予会用 S 表示,若有 x 权限,则会用 s 表)
- 命令执行者要对该程序拥有 x (执行)权限
- 命令执行者在执行该程序时获得该程序文件属主的身份(在执行程序的过程中灵魂附体为文件的属主)
- SetUID 权限只在该程序执行过程中有效,就是说身份改变只在程序执行过程中有效

SetUID 的危险之处
例如:
[root@localhost ~]# chmod u+s /usr/bin/vim
[root@localhost ~]# ll /usr/bin/vim
-rwsr-xr-x. 1 root root 2337192 8月 9 2019 /usr/bin/vim
如果这样操作的话,那么任何普通用户都可以通过 vim 来读取和修改整个系统的任意文件,相当于 root 了。
SetUID建议
- 关键目录应严格控制写权限。如
/、/usr等; - 用户的密码设置严格遵守密码三原则;
- 对系统中默认应该具有 SetUID 权限的文件做一列表,定时检查有没有这之外的文件被设置了 SetUID 权限。
- 可以考虑写一个检测 SetUID 的脚本
SetGID
SGID 既可以针对文件生效,也可以针对目录生效。
SetGID 针对文件
针对文件时起作用如下:
- 只有可执行的二进制程序才能设定 SGID 权限(给没有 x 权限的文件赋予会用 S 表示,若有 x 权限,则会用 s 表)
- 命令执行者要对该程序拥有 x (执行)权限
- 命令执行者在执行该程序时,组身份变为该程序文件属组的身份
- SetGID 权限只在该程序执行过程中有效,就是说身份改变只在程序执行过程中有效
例如 locate 命令,该命令是通过访问数据库 /var/lib/mlocate/mlocate.db 来进行搜索的,其相关权限如下:
[root@localhost ~]# ll /var/lib/mlocate/mlocate.db
-rw-r-----. 1 root slocate 952666 5月 9 14:33 /var/lib/mlocate/mlocate.db
[root@localhost ~]# ll /usr/bin/locate
-rwx--s--x. 1 root slocate 40520 4月 11 2018 /usr/bin/locate
可以发现,普通用户对于该数据库是没有任何权限的,但是 slocate 组有读权限,所以东用户执行 locate 命令时,他的所属组变为 slocate 这时就可以对数据库进行访问了。
SetGID 针对目录
若 SGID 针对目录设置,含义如下:
- 普通用户必须对此目录拥有 r 和 x 权限,才能进入此目录
- 普通用户在此目录中的有效组会变成此目录的属组
- 若普通用户对此目录拥有 w 权限时,新建的文件的默认属组是这个目录的属组。
注意: 这个针对目录并不是太有用,反而有风险,若要设置 SGID 权限必须要给该目录 777 权限,这是有一定风险的。
Sticky BIT
Sticky BIT 粘着位,SBIT 目前仅针对目录有效,作用如下:
- 粘着位目前只对目录有效
- 普通用户对该目录拥有 w 和 x 权限,即普通用户可以在此目录拥有写入权限
- 如果没有粘着位,因为普通用户拥有 w 权限,所以可以删除此目录下的所有文件,包括其他用户建立的文件。一旦赋予了粘着位,除了 root 可以删除所有文件,普通用户就算拥有 w 权限,也只能删除自己建立的文件,但是不能删除其他用户建立的文件。
设定文件特殊权限
特殊权限为权限码的首位,分别为:
- 4 代表 SUID
- 2 代表 SGID
- 1 代表 SBIT
例如:
[root@localhost ~]# chmod 4755 abc
[root@localhost ~]# ll abc
-rwsr-xr-x. 1 root root 0 5月 11 14:19 abc
文件系统属性 chattr 权限
修改 chattr 权限
chattr [+-=] [选项] 文件或目录名
选项:
+: 增加权限
-: 删除权限
=: 等于某权限(很少用)
i: 如果对文件设置 i 属性,那么不允许对文件进行删除、改名,也不能添加和修改数据;如果对目录设置 i 属性,那么只能修改目录下文件的数据,但不允许建立和删除文件
a: 如果对文件设置 a 属性,那么只能在文件中增加数据,但是不能删除也不能修改数据(不能用vim编辑,只能用ehco);如果对目录设置 a 属性,那么只允许在目录中建立和修改文件,但是不允许删除
e: 表示改文件是使用 ext 文件系统进行存储的,而且不能使用 chattr -e 命令取消 e 属性
查看文件系统属性 lsattr
lsattr 选项 文件名
选项:
-a 显示所有文件和目录
-d 若目标是目录,仅列出目录本身属性,而不是子文件的