目录
1.1 拥有者(user)、用户组(group)、其他人(other)身份说明
可以直接从第五节跳到第六节,因为第五节是扩展性内容,可能看完了第五节,已经忘记前面内容。
五、 Linux中ll列出的文件权限最后一位小数点的意义:SELinux
5.4 用策略制定特定进程读取特定文件:强制访问控制(MAC)
5.3.2 getfacl:获取某个文件或目录的ACL设置规范
一、Linux的账号与用户组
1.1 拥有者(user)、用户组(group)、其他人(other)身份说明
- 拥有者:一个人的私人空间。
由于 Linux 是个多人多任务的系统,因此可能会常常会有很多人同时使用这部主机来进行工作的情况发生,为了考虑个人隐私,以及每个人喜好的工作环境,因此,【文件拥有者】就相当重要了。即某个存在只有自己可以使用。 - 用户组:一群人放在同一集合中。
群组最有用的功能之一,是在一台主机上进行(多个)团队开发资源的时候。例如,假设有两组专题在我的主机中,第一个专题组别为projecta,里面的成员有class1,class2,class3三个;第二个专题组别为projectb,里面的成员有class4,class5,class6。这两个专题之间是有竞争性的,但却要交同一份报告。每组的成员之间必须要能够互相修改对方的数据,但是其他组的组员不能看到本组自己的文件内容。 - 其他人:就是其他人。
1.2 三者之间的关系
- 我有一个秘密,用户组内的其他人都不告诉,也包括陌生人(其他人)。-rwx------
- 我有一个秘密,只告诉自己人,但不告诉其他人。-rwxrwx---
- 我有一个秘密,只告诉陌生人,不告诉自己人,-rwx---rwx
- 我有一个秘密,但我是大嘴巴,谁都说,-rwxrwxrwx
- 我知道一个问题,但除了上天(root)谁都不知道,----------
1.3 实际操作:增删改查
范例1:创建四个用户zyx_1/zyx_2/zyx_3/zyx_4
[root@study ~]# useradd zyx_1
[root@study ~]# useradd zyx_2
[root@study ~]# useradd zyx_3
[root@study ~]# useradd zyx_4范例2:删除用户zyx_4
[root@study ~]# userdel -r zyx_4范例3:创建群组groupA/groupB/groupC
用户组有三个概念:初始用户组、有效用户组、次要用户组
- 初始用户组:创建一个用户时,用户自带的用户组叫初始用户组(默认初始用户组名是用户名),useradd -g groupname username可以给用户设置初始用户组参数,也可以后面用usermod -g groupname username来修改初始用户组参数。
- 次要用户组:有一些项目任务时,我们会创建一个群组,然后root可以用usermod -G groupname username将用户组设置为次要用户组,可以用通用指令groups查看用户支持的所有群组。
- 有效用户组:无论是初始用户组,还是次要用户组,一个用户在一个时间只能是处于一个用户组状态,这种状态下的用户组是有效用户组。用户可以用usermod -g将次要用户组切换成初始用户组,这时候新建一个文件通过ls -l查看文件可以看出当前的有效用户组。usermod和useradd都是root only,而一般用户也可以用newgrp暂时切换(开启一个子进程,exit退出)用户的有效用户组。
[root@study ~]# groupadd groupA
[root@study ~]# groupadd groupB
[root@study ~]# groupadd groupC范例4:删除群组groupC
[root@study ~]# groupdel groupC范例5:用usermod将用户zyx_1/zyx_2加入群组groupA,将用户zyx_3加入群组groupB
- usermod:可以修改用户的有效群组,即用户可能有多个群组,而正在使用的只能有一个。
- chowner:可以针对文件或目录,修改拥有者。
- chgrp:可以针对文件或目录,修改用户组。
[root@study ~]# usermod -g groupA zyx_1
[root@study ~]# usermod -G groupA zyx_2
[root@study ~]# usermod -g groupB zyx_3范例6:查看新建的用户信息
[root@study ~]# ll /home
总用量 8
drwx------. 15 zyx_1 groupA 4096 7月 7 08:43 zyx_1
drwx------. 3 zyx_2 groupA 78 7月 6 18:58 zyx_2
drwx------. 3 zyx_3 groupB 78 7月 6 18:58 zyx_31.4 通过文件查看其信息
先查看这些要查看文件的信息
[root@study ~]# ll /etc/passwd /etc/shadow /etc/group /etc/default/useradd /etc/login.defs
-rw-r--r--. 1 root root 119 11月 5 2016 /etc/default/useradd
-rw-r--r--. 1 root root 1043 7月 6 18:58 /etc/group
-rw-r--r--. 1 root root 2028 11月 5 2016 /etc/login.defs
-rw-r--r--. 1 root root 2292 7月 6 18:59 /etc/passwd
----------. 1 root root 1609 7月 6 19:34 /etc/shadow[root@study ~]# cat /etc/passwd # 包括所有用户的信息
root:x:0:0:root:/root:/bin/bash
................
zyx_1:x:1002:1505::/home/zyx_1:/bin/bash
zyx_2:x:1003:1505::/home/zyx_2:/bin/bash
zyx_3:x:1004:1506::/home/zyx_3:/bin/bash[root@study ~]# cat /etc/shadow # 包括所有用户的密码,由某种加密方式加密
root:$6$3ZkbwlaAMHvE3Ql6$PI0dj.3ASV4E4gl1W/cfGVoqnj5w68YNtEo.vyKvwyXfvciqs.yUyXA.KnHwI0A.sB2GsjY992v39aPvN/EJU1::0:99999:7:::
.............................
zyx_1:$6$aSxtUXIZ$wWLYhWYKO/b/0YlhUoTLeTsCqH0f1GtC0PGrNvg8FUiqSvDjNa7vI9OU0/EgjFHRiGZnZtK461Csw7guBRWVD/:18814:0:99999:7:::
zyx_2:$6$JB7C8C56$foRYRv5lqziREQWzk7Csx7l66sKD0rXP/9xAFPgFOf1e7EMhCS.6dR456CWQv7zdsUx4Dow.MWQXdUdwVmoqE1:18814:0:99999:7:::
zyx_3:$6$such3Bs4$rLo55W7popszXaKTCpAE4OX4Kh3luItOwOaEhzShr4f4JW27OvMgBnUIN/MyZcQO3pBbilMMStrEpz9IXvZpX/:18814:0:99999:7:::
[root@study ~]# cat /etc/groupA # 包括所有的用户组
root:x:0:
...........
groupA:x:1505:
groupB:x:1506:
zyx_1:x:1507:
zyx_2:x:1003:
zyx_3:x:1004:[root@study ~]# cat /etc/default/useradd # 创建用户时的默认值
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes[root@study ~]# cat /etc/login.defs
MAIL_DIR /var/spool/mail # 使用者邮箱默认目录
PASS_MAX_DAYS 99999 # /etc/shadow的第5字段,需要修改密码日数
PASS_MIN_DAYS 0 # /etc/shadow 的第4字段,不可设置密码日数
PASS_MIN_LEN 5 # 密码的最短字符数,已被pam替代,7已经放弃该参数
PASS_WARN_AGE 7 # /etc/shadow 的第6字段,过期会警告的天数
UID_MIN 1000 # 使用者的最小UID
UID_MAX 60000 # 使用者的最大UID
SYS_UID_MIN 201 # 保留给使用者自行设置的系统账号最小值、
SYS_UID_MAX 999 # 保留给使用者自行设置的系统账号最大值
GID_MIN 1000 # 使用者的最小GID
GID_MAX 60000 # 使用者的最大GID
SYS_GID_MIN 201 # 保留给使用者自行设置的系统账号最小值 GID
SYS_GID_MAX 999 # 保留给使用者自行设置的系统账号最大值 GID
CREATE_HOME yes # 在useradd加-M及-m时,是否主动建立使用者家目录
UMASK 077 # 使用者家目录建立的umask,因此权限会是700
USERGROUPS_ENAB yes # 使用userdel删除初始用户时,若其对应初始用户组没有其他用户,是否会删除初始用户组
ENCRYPT_METHOD SHA512 # 密码加密的机制使用的是SHA512[root@study ~]# cat /etc/shells # 所有用户可选择的shell
/bin/sh
/bin/bash # 默认使用的shell
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh1.5 相关的指令说明:针对用户&针对文件和目录
1.5.1 针对用户
| 指令 | 描述 |
|---|---|
| useradd(only root) | 创建用户,并且可以同时修改用户信息,以及打印用户信息 |
| usermod(only root) | 修改用户信息,并且可以修改-g用户的初始用户组,以及用-G添加用户的次要群组 |
| userdel(only root) | 删除用户,不带-r不会删除家目录,只会删除账号信息。 |
| passwd(anyone) | 给新创建的用户创建密码权限,这样就可以登录这些账号。 |
| groupadd(only root) | 创建群组,并且可以修改群组信息,以及打印群组信息 |
| groupmod(only root) | 修改用户组信息 |
| groupdel(only root) | 删除群组 |
| groups(anyone) | 列出某个用户的所有支持的群组 |
| umask(anyone) | 设置用户的文件或目录的默认权限 |
1.5.2 针对文件和目录
| 指令 | 描述 |
|---|---|
| chown(anyone) | 修改文件或目录的所有者 |
| chgrp(anyone) | 修改文件或目录的群组 |
| chmod(anyone) | 修改文件或目录的权限等信息 |
二、Linux中权限的表现形式
2.1 数组类型改变文件权限
权限分数对照:r:4;w:2;x:1(这其实是八进制:100、010、001)。
每种身份(owner/group/others)各自的三个权限(r/w/x)分数是需要累加的,例如当权限为:[-rwxrwx---]分数则是:
- owner/user = rwx = 4+2+1 = 7;
- group = rwx = 4+2+1 = 7;
- others = --- = 0+0+0 = 0。
那么该文件的权限就是770。
范例1:利用数字类型改变文件权限。

2.2 字符类型改变文件权限

在 Linux的[$man chmod]中描述的有点太复杂,意思是不再是直接将权限像【数字类型改变权限】那样,直接设定权限好三个身份的权限,而是可以 [单独](或[同时]) 对三个身份的权限进行增删。
用chmod进行字符型权限修改需要注意:
- 用u,g,o分别表示user、group、others三种身份,a表示 all即全部的身份。
- Linux 选择用[+]表示增,用[-]表示删,当然也可以设定,用[=]表示设定。
- 如果是对三种身份单独处理,即u,g,o,中间用逗号分隔。
范例2:设定 .bashrc 的权限成为 [-rwxr-xr-x] 。
方法一:使用设定。

方法二:使用增删(加减)

范例2:删除 .bashrc 的所有身份的写权限,用a代替全部身份进行删。

注意:如果想要修改目录及其所有子目录及子文件权限,需要加上选项-R.
三、文件的rwx权限与目录的rwx权限
3.1 权限对于文件的意义
- r(read):可读取此文件的实际内容,如读取文本文件的文字内容等;
- w(write):可以编辑、新增或是修改该文件的内容(但不包括删除该文件,是否可以删除由目录的w权限决定);
- x(execute):该文件具有可以被系统执行的权限。
- 在windows中,一个文件是否具有可执行的能力是藉由 [扩展名] 来判断,例如:.exe、.bat、.com等;
- 但是Linux底下,文件是否能够被执行,则是藉由是否具有 [x] 这个权限决定的,与文档名没有绝对关系。
- 需要注意的是文件的x权限,默认情形下是没有的,如果有那一定是某个用户后加的,为什么?因为文件大多是不需要执行的,而就算有需要执行权限,目前可知的可执行文件类型,Linux几乎都有内置的指令去读取内容(用r权限)并执行此文件。例如shell文件,如果自身没有x权限,自身是不能被自己执行的。但是Linux的内置指令sh和source却可以只要利用其r权限就可以读取其内容,然后运行。
虽然上面说了文件的执行权限的问题,为了便于思考,所以针对x权限用不同的身份去实例化功能。其实文件可以不用加上x去执行,用内置指令即可,但我们还是确认下x权限的效果。
范例1:以【zyx_1身份】在/tmp目录下新建一个【可以被执行的shell文件test.sh】,查看该文件权限,然后以【绝对路径】运行该文件,如果不能运行就,想办法让其运行
[root@study ~]# su zyx_1 # 切换身份到zyx_1
[zyx_1@study root]$ cd /tmp # 切换到目录 /tmp
[zyx_1@study tmp]$ vim test.sh # 编辑可执行文件test.sh内容是: echo "this is a zyx_1 shell file"
[zyx_1@study tmp]$ ll test.sh # 看其权限都没有x的权限
-rw-r--r--. 1 zyx_1 groupA 34 7月 7 09:58 test.sh
[zyx_1@study tmp]$ /tmp/test.sh # 运行结果,没有x的权限不能执行
bash: /tmp/test.sh: 权限不够
[zyx_1@study tmp]$ chmod u+x test.sh # 给他加上x的权限,可以执行
[zyx_1@study tmp]$ /tmp/test.sh
this is a zyx_1 shell file
[zyx_1@study tmp]$ ll test.sh # 看其权限
-rwxr--r--. 1 zyx_1 groupA 34 7月 7 09:58 test.sh
范例2:切换到【zyx_2】(用户组成员)身份,运行此文件,如果不能运行,想办法运行此文件。
[zyx_1@study tmp]$ su zyx_2 # 切换到身份zyx_2
密码:
[zyx_2@study tmp]$ /tmp/test.sh # 尝试运行test.sh,但用户组权限不够
bash: /tmp/test.sh: 权限不够
[zyx_2@study tmp]$ ll test.sh # 观察其权限,用户组没有x的权限
-rwxr--r--. 1 zyx_1 groupA 34 7月 7 09:58 test.sh
[zyx_2@study tmp]$ chmod g+x test.sh # 以zyx_2的身份修改其权限
chmod: 更改"test.sh" 的权限: 不允许的操作
[zyx_2@study tmp]$ su zyx_1 # 切换回zyx_1或root
密码:
[zyx_1@study tmp]$ chmod g+x test.sh # 修改用户组权限加上x
[zyx_1@study tmp]$ ll test.sh # 可以看到群组权限中有x
-rwxr-xr--. 1 zyx_1 groupA 34 7月 7 09:58 test.sh
[zyx_1@study tmp]$ su zyx_2 # 切回zyx_2
密码:
[zyx_2@study tmp]$ /tmp/test.sh # 运行成功
this is a zyx_1 shell file范例3:切换到【zyx_3】(其他人)身份,运行此文件,如果不能运行,想办法运行此文件。
[zyx_2@study tmp]$ su zyx_3 # 切换到zyx_3身份
密码:
[zyx_3@study tmp]$ /tmp/test.sh # 运行发现权限不足
bash: /tmp/test.sh: 权限不够
[zyx_3@study tmp]$ ll test.sh # 其他人没有x权限
-rwxr-xr--. 1 zyx_1 groupA 34 7月 7 09:58 test.sh
[zyx_3@study tmp]$ su zyx_1 # 切回zyx_1
密码:
[zyx_1@study tmp]$ chmod o+x test.sh # 修改其他人权限+x
[zyx_1@study tmp]$ ll test.sh
-rwxr-xr-x. 1 zyx_1 groupA 34 7月 7 09:58 test.sh
[zyx_1@study tmp]$ su zyx_3 # 切回zyx_1
密码:
[zyx_3@study tmp]$ /tmp/test.sh # 运行成功
this is a zyx_1 shell file上面的三个范例,都是围绕着各个身份的针对x权限,通过切换身份赋予user、group、other 利用指令chmod对/tmp/test.sh这个文件x的权限。其实可以直接一次用chmod赋予他们所有身份x的权限。
范例4:以zyx_1身份在/tmp下新建一个文件test2.sh,然后将user、group、other都赋予x的权限。
[zyx_3@study tmp]$ su zyx_1 # 切换到zyx_1
密码:
[zyx_1@study tmp]$ vim test2.sh # 新建一个文件test2.sh
[zyx_1@study tmp]$ ll test2.sh
-rw-r--r--. 1 zyx_1 groupA 31 7月 7 11:18 test2.sh
[zyx_1@study tmp]$ chmod a+x test2.sh # 修改权限,全部加上x权限
[zyx_1@study tmp]$ ll test2.sh
-rwxr-xr-x. 1 zyx_1 groupA 31 7月 7 11:18 test2.sh范例5:切换到root,用groupadd新建一个群组groupC,将zyx_1,zyx_2,zyx_3用指令usermod加入群组groupC,然后,将这个test2.sh文件的用chmod群组切换成groupC,那么就只要将这个群组的权限加上x,这三个用户就可以运行?
[root@study ~]# groupadd groupC # 新建用户组groupC
[root@study ~]# usermod -g groupC zyx_1 # 修改三个群组成员的有效用户组为groupC
[root@study ~]# usermod -g groupC zyx_2
[root@study ~]# usermod -g groupC zyx_3
[root@study ~]# ll /home
drwx------. 15 zyx_1 groupC 4096 7月 7 11:18 zyx_1
drwx------. 5 zyx_2 groupC 107 7月 7 10:39 zyx_2
drwx------. 5 zyx_3 groupC 107 7月 7 10:50 zyx_3
[root@study tmp]# ll test2.sh # 观察/tmp/test2.sh权限
-rwxr-xr-x. 1 zyx_1 groupC 31 7月 7 11:18 test2.sh
[root@study tmp]# chmod u-x,o-x test2.sh # 修改文件权限只有用户组有x权限
[root@study tmp]# ll test2.sh
-rw-r-xr--. 1 zyx_1 groupC 31 7月 7 11:18 test2.sh
[root@study tmp]# su zyx_1 # 切换到zyx_1
[zyx_1@study tmp]$ /tmp/test2.sh # 运行发现是按照用户权限,不是群组权限
bash: /tmp/test2.sh: 权限不够 # 使用者没有x权限,权限不足
[zyx_1@study tmp]$ su zyx_2 # 切换到zyx_2
密码:
[zyx_2@study tmp]$ /tmp/test2.sh # 运行是按照群组权限
i am a zyx_1 shell file
[zyx_2@study tmp]$ su zyx_3 # 切换到zyx_3
密码:
[zyx_3@study tmp]$ /tmp/test2.sh # 运行时按照群组权限
i am a zyx_1 shell file
结果表示:用户权限的优先级高于用户组。
3.2 权限对于目录的意义
- r(read contents in directory):具有读取目录结构列表的权限;
- w(modify contents of directory):表示你具有异动该目录结构列表的权限,也就是这些权限;
- 建立新的文件与目录;
- 删除已经存在的文件与目录(不论该文件的权限为何!);
- 将已存在的文件或目录进行更名;
- 搬移该目录内的文件、目录位置。
- x(access directory):表示用户能否进入该目录。(目录当然不可以被执行)。
- 所谓工作目录(work directory)就是你目前所在的目录,举例来说,当你登入Linux时,你所在的家目录就是你当下的工作目录,而变换目录的指令是 [cd](change directory)。
[root@study ~]# ll /home
drwx------. 15 zyx_1 groupA 4096 7月 7 08:43 zyx_1查看新建的用户可以看出用户家目录都是只有自己有绝对权限(当然还有root)。
假设:老师用root身份,给学生zyx_1与zyx_2用mkdir与chgrp安排了一个项目ProjectA,给学生zyx_3安排了一个项目ProjectB。并赋予项目组成员对于各自项目组完全的权限。
[root@study ~]# cd /tmp
[root@study tmp]# mkdir PjA
[root@study tmp]# mkdir PjB
[root@study tmp]# ll -d PjA PjB
drwxr-xr-x. 2 root root 6 7月 7 13:14 PjA
drwxr-xr-x. 2 root root 6 7月 7 13:14 PjB
[root@study tmp]# chmod g=rwx,o=---- PjA
[root@study tmp]# chgrp groupA PjA
[root@study tmp]# chmod g=rwx,o=---- PjB
[root@study tmp]# chgrp groupB PjB
[root@study tmp]# ll -d PjA PjB
drwxrwx---. 2 root groupA 6 7月 7 13:14 PjA
drwxrwx---. 2 root groupB 6 7月 7 13:14 PjB
范例1:用【zyx_1】在/tmp/PjA下新建一个shell文件zyx_1_file1.sh,内容:echo "This is a zyx_1 shell",并新建一个目录zyx_1_dir,里面新建一个shell文件dir_shell.sh,内容,echo "This is a zyx_1's shell in zyx_1\'s dir"。
[root@study tmp]# su zyx_1 # 切换到用户zyx_1
[zyx_1@study tmp]$ cd ./PjA # 进入zyx_1的项目PjA
[zyx_1@study PjA]$ vim zyx_1_file.sh # 新建一个shell
[zyx_1@study PjA]$ mkdir zyx_1_dir # 新建一个文件夹
[zyx_1@study PjA]$ vim zyx_1_dir/dir_shell.sh # 新建一个文件夹下的shell
[zyx_1@study PjA]$ ll zyx_1_file.sh zyx_1_dir/dir_shell.sh -d zyx_1_dir
drwxr-xr-x. 2 zyx_1 groupA 26 7月 7 13:42 zyx_1_dir
-rw-r--r--. 1 zyx_1 groupA 48 7月 7 13:42 zyx_1_dir/dir_shell.sh
-rw-r--r--. 1 zyx_1 groupA 29 7月 7 13:40 zyx_1_file.sh从上面文件的权限可以看出:
- 在没有用chmod进行修改的前提下,没有用户对文件有x的权限;
- 在默认情形下,组员zyx_2对此文件没有读的权限,对目录也没有改变文件的权限。
范例2:用【zyx_2】身份去查看与运行以及编辑zyx_1_file.sh,看看是否可以进行;查看目录zyx_1_dir并进入目录,查看与运行以及编辑dir_shell.sh并新建一个文件newfile。
[zyx_1@study PjA]$ su zyx_2 # 切换身份到 zyx_2
密码:
# **********从现在开始只看群组权限******************
[zyx_2@study PjA]$ ll zyx_1_file.sh zyx_1_dir/dir_shell.sh -d zyx_1_dir
drwxr-xr-x. 2 zyx_1 groupA 26 7月 7 13:42 zyx_1_dir
-rw-r--r--. 1 zyx_1 groupA 48 7月 7 13:42 zyx_1_dir/dir_shell.sh
-rw-r--r--. 1 zyx_1 groupA 29 7月 7 13:40 zyx_1_file.sh
[zyx_2@study PjA]$ cat zyx_1_file.sh # 用r权限,尝试读取zyx_1_file.sh
echo "This is a zyx_1 shell" # 有r权限,所以读取成功
[zyx_2@study PjA]$ /tmp/PjA/zyx_1_file.sh # 用x权限,运行该程序
bash: /tmp/PjA/zyx_1_file.sh: 权限不够 # 没有x权限,所以运行失败
[zyx_2@study PjA]$ vim zyx_1_file.sh # 用w权限,尝试编辑
# 没有w权限,所以只读模式,但是我用:W!强制写入了
[zyx_2@study PjA]$ /tmp/PjA/zyx_1_dir/dir_shell.sh # 用x权限,运行zyx_1_dir/dir_shell.sh
bash: /tmp/PjA/zyx_1_dir/dir_shell.sh: 权限不够 # 没有x权限,所以运行失败
[zyx_2@study PjA]$ touch zyx_1_dir/newfile # 用w权限,在目录zyx_1_dir下新建文件
touch: 无法创建"zyx_1_dir/newfile": 权限不够 # 没有w权限,所以新建失败可以看得出,虽然是同一项目,但是双方有很多权限的限制去操作整个项目,这就很烦了,要是甲编辑的文件,让乙处理,但是发现权限不够,而甲已经下班了,三天后上班,那不伤死了。
现在是要求zyx_1与zyx_2都对PjA这个项目有着完全的权限。
方法一:每个用户每次新建文件直接用chmod直接修改目录与zyx_1_file.sh文件的权限
范例3:用zyx_1身份在项目组PjA中新建文件newfile1.sh修改其权限为-rw-rw----,新建文件夹newdir1并修改其权限为drwxrwx---,然后分别用zyx_2的身份去读取、写入echo "here is newfile1"并用指令sh运行,然后在newdir1下新建文件cbzyx_2(create by zyx_2)。
[root@study ~]# su zyx_1 # 切换身份到zyx_1
[zyx_1@study root]$ cd /tmp/PjA # 切换到工作目录
[zyx_1@study PjA]$ vim newfile1.sh # 新建并编辑一个shell文件
[zyx_1@study PjA]$ mkdir newdir1 # 创建一个目录
[zyx_1@study PjA]$ ll newfile1.sh -d newdir1 # 查看其默认权限
drwxr-xr-x. 2 zyx_1 groupA 6 7月 8 09:42 newdir1
-rw-r--r--. 1 zyx_1 groupA 24 7月 8 09:42 newfile1.sh
[zyx_1@study PjA]$ chmod 770 newfile1.sh # 由zyx_1修改权限给群组成员完全权限
[zyx_1@study PjA]$ chmod 770 newdir1 # 并且其他人无权限
[zyx_1@study PjA]$ ll newfile1.sh -d newdir1 # 查看修改后的权限
drwxrwx---. 2 zyx_1 groupA 6 7月 8 09:42 newdir1
-rwxrwx---. 1 zyx_1 groupA 24 7月 8 09:42 newfile1.sh
[zyx_1@study PjA]$ su zyx_2 # 切换身份到zyx_2
密码:
[zyx_2@study PjA]$ cat newfile1.sh # 读取zyx_1的shell文件
echo "Here is newfile1"
[zyx_2@study PjA]$ vim newfile1.sh # 编辑shell文件
[zyx_2@study PjA]$ sh newfile1.sh # 运行shell文件
Here is newfile1
zyx_1 file has been wrote by zyx_2 # 这是编辑写入那一行
[zyx_2@study PjA]$ vim newdir1/cbzyx_2 # 并在文件夹下新建并编辑文件
[zyx_2@study PjA]$ ll newdir1/cbzyx_2 # 观察zyx_2新建的文件
-rw-r--r--. 1 zyx_2 groupA 0 7月 8 10:29 newdir1/cbzyx_2从运行结果可知,通过chmod对每个新建的文件和目录修改权限,可以达到让项目组内成员具有完全权限。但是可以发现这种方式十分的麻烦。就好像zyx_2后面新建的文件cbzyx_2,还是要用chmod修改权限。
方法二:用umask修改文件与目录默认权限,umask代表着默认的权限,文件用666 (就这么规定的,可以参考上面对文件x权限的解释)去减其参数,目录用777去减参数。
[zyx_1@study PjA]$ umask 007 # 修改zyx_1的umask值,那么新建的文件权限是-rw-rw----,目录权限是drwxrwx---
[zyx_1@study PjA]$ vim zyx_1_file2.sh # 新建一个文件
[zyx_1@study PjA]$ ll zyx_1_file2.sh # 观察其权限
-rw-rw----. 1 zyx_1 groupA 25 7月 7 14:33 zyx_1_file2.sh
[zyx_1@study PjA]$ mkdir zyx_1_dir2 # 新建文件夹
[zyx_1@study PjA]$ ll -d zyx_1_dir2 # 查看其权限
drwxrwx---. 2 zyx_1 groupA 6 7月 7 14:35 zyx_1_dir2可以发现上面的内容与方法一想要的,基本相同,除了文件的x权限,但是这个在上面文件的x权限部分已经说明过了,就是文件没有必要有x权限。
相关权限说明:umask是针对用户的,所以使用了umask之后,这个用户以后所有建立的目录与文件的默认权限都是这样的。
从上面的内容可以看出,我们所有的修改都是基于zyx_1,zyx_2的有效用户组是groupA,但是大多数的情形下,我们的用户组是不一定的,而且我们一般不愿意因为一个方面就将自己定死了,我可能同时处理多个项目,那怎么办?
方法三:用下面才会介绍的隐藏权限SGID(为什么不用SUID?因为SUID仅对二进制文件有效)。
范例4:步骤如下:
- PjA这个项目的拥有者是root,而当前用户组是groupA,现在我们用usermod -g将zyx_1的初始用户组修改成zyx_1(初始用户组),zyx_2的有效用户组修改成zyx_2。
- 前面的内容是直接用usermod -g 修改初始用户组的,所以这里我们先用usermod -G将groupA作为zyx_1与zyx_2的次要用户组。
- 将zyx_1,zyx_2的umask都设成002,虽然这样被修改的用户组是zyx_1和zyx_2。但是由于SGID的特性,目录PjA当前用户组groupA包括用户zyx_1,zyx_2,那么此时用户zyx_1,zyx_2,在处理目录PjA的内容时,它们的有效用户组就会变成groupA。
- 然后通过chmod将这个项目PjA的权限加上一个SGID(数字权限为2)的权限,即设置这个项目PjA的权限是2770。
root@study ~]# usermod -g zyx_1 zyx_1 # 修改zyx_1的初始用户组
[root@study ~]# usermod -g zyx_2 zyx_2 # 修改zyx_2的初始用户组
[root@study ~]# usermod -G groupA zyx_1 # 将GroupA作为zyx_1的次要用户组
[root@study ~]# usermod -G groupA zyx_2 # 将GroupA作为zyx_2的次要用户组
[root@study ~]# chmod 2770 /tmp/PjA ##### # 修改PjA的权限,给其加上SGID,就是前面那个2
[root@study ~]# su zyx_1 # 切换到zyx_1
[zyx_1@study root]$ umask 002 # 调整默认权限
[zyx_1@study root]$ groups # 查看所有支持zyx_1的用户组
zyx_1 groupA
[zyx_1@study root]$ cd ~ # 切换到zyx_1家目录
[zyx_1@study ~]$ vim testfile # 新建一个文件
[zyx_1@study ~]$ ll testfile # 发现此文件有效用户组是zyx_1
-rw-rw-r--. 1 zyx_1 zyx_1 0 7月 8 12:20 testfile
[zyx_1@study ~]$ cd /tmp/PjA # 切换到项目目录PjA下
[zyx_1@study PjA]$ vim testSGID # 新建一个文件
[zyx_1@study PjA]$ ll testSGID ##### # 发现此文件有效用户组是groupA(SGID特性)
-rw-rw-r--. 1 zyx_1 groupA 0 7月 8 12:30 testSGID
四、隐藏权限SUID、SGID、SBIT
4.1 SUID对二进制程序的意义
当s这个权限出现在[用户拥有者]的x权限上时,此时就被称为Set UID,简称为SUID。基本上SUID有这样的限制与功能:
- SUID 权限仅对二进制程序(binary program)有效;(对目录与一般文件无效)
- 执行者对于该程序需要具有 x 的可执行权限;
- 本权限仅在执行该程序的过程中有效(run-time);
- 执行者将具有该程序拥有者(owner)的权限。
注意:SUID仅可用在binar program上,不能够用在shell script上。因为shell script 只是将很多的binary执行档叫进来执行而已。所以SUID的权限,还是要看shell script呼叫进来的程序的设定。
4.2 SGID对文件和目录的意义
当s这个权限出现在[群组]的x的权限上时,此时就被称为Set GID,简称为SGID。与SUID(仅对二进制程序有用)不同,SGID可以针对文件或目录来设定,SGID有如下功能:
- SGID对二进制程序有用;
- 程序执行者对于该程序,具有x的权限;
- 程序执行者在执行的过程中会获得该程序群组的支持。
除了binary program之外,事实上,SGID也能够用在目录上。当一个目录设定了SGID的权限后,它将具有以下的功能:
- 用户若对于此目录具有 r 与 x 的权限时,该用户能够进入此目录;
- 用户在此目录下的有效群组(effective group)将会变成该目录的群组;
- 用途:若用户在此目录下具有w的权限(可以新建文件),则使用者所新建的文件,该新文件的群组与此目录的群组相同。
范例可以看第二节中权限对目录的意义的方法三来体会其中意义。
4.3 SBIT对目录公共环境资源私有化的意义
这个Sticky Bit,简称SBIT 目前只针对目录有效,对于文件已经无效。其对于目录的作用是:
- 当用户对于此目录具有 w,x权限,即具有写入的权限时;
- 当用户在该目录下建立文件或目录时,仅有自己与root才有权利删除该文件。
一般情形下,你的文件放在我的目录下,那么我就可以删除这个文件。但是用了SBIT后你的文件我就删除不了了。
范例1:当用户 甲 在目录 A 下是[群组或其他人]的身份,并且拥有该目录的w权限,即用户甲可对该目录内 [任何人] 建立的目录或文件均可进行“删除/更名/搬运”等动作。
不过如果 A 目录被加上了 SBIT权限时,则甲只能够针对 [自己] 建立的目录或文件进行删除/更名/移动 等动作。
4.4 SUID、SGID、SBID的表现形式
数字形态更改权限的方式为三个数字的组合,那么如果在这三个数字之前加一个数字的话,最前面对的数字就代表着几个权限了:1)4为SUID;2)2为SGID;3)1为SBIT。
假设要经一个文件权限为 [-rwsr-xr-x] 时,由于s在用户权力,所以是SUID,因此在原先的755之前还有加上个4,也就是说:[chmod 4755 filename] 来设定,此外,还有大S与大T的产生。

最后一条7666是-rwSrwSrwT为什么是大写?
因为s与t都是取代x这个权限的,但是我们下达的是7666,即666应是-rw-rw-rw都没有x的权限,所以S,T代表的是[无效],即SUID 是表示:本权限仅【在执行的过程中】有效;但是666导致文件无法被执行,故【用大写表示无效】。
可以直接从第五节跳到第六节,因为第五节是扩展性内容,可能看完了第五节,已经忘记前面内容。
五、 Linux中ll列出的文件权限最后一位小数点的意义:SELinux
本节如果不想太烦,只想知道怎么操作SELinux可以直接跳到
5.1 文件模式位后面一位的描述
[root@study ~]# ll ~/.bashrc
-r-xr-xr-x. 1 root root 176 12月 29 2013 /root/.bashrc只有在Linux开启了SELinux(SEcurity-Enhanced Linux,增强型安全Linux)才会有这个点。Linux一般是默认开启这个功能的,但是如果关闭SELinux,新建的文件或目录就不会有这个小数点,而以前基于这种安全模式创建的文件和目录依然会存在。
文件模式位:英文为,file mode bits,即-rw-rw-rw-这些权限位。而这个小数点刚好就位于文件模式位后面。
这个位置的意义是:是否有一个可替换的访问措施应用到这个文件上,例如ACL。
- 当文件模式位后面附加的是一个空格,表示的是没有可替换的访问措施。
- 当文件模式位后面附加的是一个可打印字符时,表示系统存在这样一个访问措施。
- 当文件模式位后面附加的是一个'.'(一个小数点)表示当前文件使用了SELinux 安全模式,而没有使用其他可选的访问方式。
- 当文件结合了其他访问控制措施,用"+"字符标记。如ACL
- 当文件没有SELinux,只应用了ACL,也会被标记成'+'
- 当文件应用SELinux,且应用了ACL,也会被标记成'+'
5.2 SELinux的意义
SELinux是Linux为了系统安全建立的一种增强型安全体系,是由美国国家安全局(NSA)开发的2.6版本的Linux内核中提供的强制访问控制(mandatory access contro,MAC)系统。
故SELinux是在进行进程、文件等详细权限配置时依据的一个内核模块。由于启动网络服务的也是进程,因此刚好SELinux可以作为控制网络服务能否读写系统资源的移到关卡。
强制访问控制,英文是mandatory access control,缩写成MAC,在计算机安全领域中指一种由操作系统约束控制,目标是限制主体或发起者访问对象或目标执行某种操作的能力。
SELinux进行的限制:限制一个进程只能访问那些在他的任务中所需要的的文件。
在真正理解SELinux的意义前,我们先对传统的权限与账号的管理方式进行描述。
5.3 传统的文件权限与账号的关系:自主访问控制(DAC)
系统账号主要分为系统管理员(root)与一般用户。一般用户能否使用系统资源与rwx的权限有关,而root身份可以有设置,但是它会无视这些设置,root具有上帝权限。
这种读写文件系统的方式称为自主访问控制(Discretionary Access Control,DAC)。基本上,就是依据进程的拥有者与文件资源的rwx来决定有读写的权限。这种方式有一些缺点:
- root拥有最高的权限:如果不小心某个进程被有心人士获取,且该进程是root权限,那么这个进程就可以在系统上执行任何资源的读写,如果在这个进程下写入一些破坏性shell,那么将会威胁到整个系统。
- 用户可以获取进程来修改文件资源的访问权限:如果用户为了操作方便,将文件或目录的权限设置为777,你写入的是一个简单的打印"hello world"shell,而被其他人修改成,将你的数据库内容全部删除,你跟谁去哭?
例如,系统资源都是通过进程来读写的,那么/var/WWW/html/被某个不熟练的人员如果设置为777,万一你的主机作为服务器,启动了WWW服务器软件,那么该软件所接触的进程将可以写入该目录,而该进程却是对整个Internet提供服务的。只要有心人接触到这个进程,那么外部的人很可能就会向你的系统写入一些莫名其妙的内容,比如说一个shell,内容是删除当前目录及上层目录的所有内容,某个工作人员,因为不知道其是什么功能,直接运行测试一下,可想而知,到最后真的变成“一无所有”。
5.4 用策略制定特定进程读取特定文件:强制访问控制(MAC)
强制访问控制,英文是mandatory access control,缩写成MAC,在计算机安全领域中指一种由操作系统约束控制,目标是限制主体或发起者访问对象或目标执行某种操作的能力。
也就是可以针对特定的进程与特定的文件资源来管理权限。换种说法是,在不同的进程即使身份是root,也不定拥有着所有的权限,而是要根据不同进程进行设定。这样一来,控制的对象就变成了【进程】而不是【用户】。
例如,WWW服务器软件的进程为 httpd这个程序,而基于SELinux的默认情况下,httpd仅能在/var/www/这个目录下读写文件。如果【httpd这个进程】想要到其他目录去读取数据时,除非规则设置要开放外,目标目录也要设置成httpd可读取的类型才行。

上面左图是没有SELinux的DAC读写结果,apache这个root所主导的进程,可以在这三个目录内作任何文件的新建与修改,相当危险。
右边则是加上SELinux的MAC管理的结果,SELinux仅会对apache这个【进程】开放部分目录的使用权,其他非正规目录就不会让apache使用。虽然传统权限上/tmp是任何用户都能访问操作的目录,但是这次不是针对传统的用户,而是针对进程。
5.4 SELinux的运行模式
5.4.1 SELinux处理过程的三个对象
有点像y=f(x),x是进程,f是策略,y是目标。经由策略处理的进程,获得对目标的处理。
- 主体(Subject):SELinux主要管理的是进程;
- 目标/对象(Object):进程读写的资源一般是文件系统;
- 策略(Policy):由于整个系统进程那么多,所以SELinux基于某些服务制定了基本的读写安全性的默认的策略(Policy)。并且这些策略内提供了多个规则(rule,就是常说的SELinux的三种模式,下面会介绍),让你来选择是否启用该控制规则。
5.4.2 三个主要的策略
在CentOS7.x中,提供了三个主要的策略:
- targeted:针对网络服务限制较多,对本机限制较少,是默认的策略;
- minimum:由targeted自定义而来,仅针对选择的进程来保护;
- mls:完整的SELinux限制,限制方面较为严格。
5.4.3 安全上下文(Security context)
安全上下文(Security context)有点类似文件系统的rwx,安全上下文的内容与设置是非常重要的,如果设置错误,你的某些服务(主体的进程)就无法读取文件系统(目标资源),也就会一直出现【权限不足】的错误信息了。
【主体】获取【目标】的资源访问权限的过程:

参考内容:Red Hat
- 当应用或进程(称为主体)发出访问对象(如文件)的请求时,必须要通过SELinux策略内的规则后才能放行;
- 然后与目标资源进行安全上下文的对比。
- SELinux 会检查访问向量缓存(AVC,Access vector cache),其中缓存有主体和对象的访问权限。
- 如果 SELinux 无法根据缓存对权限做出访问决定,它会将请求发送到安全服务器。安全服务器随即检查【应用或进程】(主体)和【文件】(目标)的安全环境,确认其是否匹配 SELinux 策略数据库的安全环境。之后便根据检查授予权限或拒绝。
- 如果被拒绝,/var/log.messages 中将会显示消息"avc: denied"。
- 若安全上下文对比成功,则获取了对目标的权限。最终是否能够对目标进行存取,还是要参考目标的rwx权限。
安全上下文的位置:安全上下文是放置到文件的inode内的,因此主体进程想要读取目标文件资源时,同样需要读取inode,这inode内就可以比对安全上下文以及rwx等权限制是否正确,而基于适当的读取权限依据。
安全上下文的内容:可以通过ls -Z观察文件的安全上下文。
[root@study ~]# ll -Z
-rw-------. root root system_u:object_r:admin_home_t:s0 anaconda-ks.cfg
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 crontab
lrwxrwxrwx. root root unconfined_u:object_r:admin_home_t:s0 crontab2 -> /etc/crontab
-rw-r--r--. root root system_u:object_r:admin_home_t:s0 initial-setup-ks.cfg安全上下文主要用冒号分为三个字段,这三个字段的意义为:
identify:role:type
身份识别:角色:类型
身份识别(identify):用于账号方面的身份识别。-u结尾是表示user。
- unconfined_u:不受限的用户,也就是说该用户来自于不受SELinux限制的进程。
- 一般用户使用可登录账号获取bash之后,默认的bash环境是不受SELinux管制的,因为bash并不是什么特别的网络服务。因此,这个一般用户不受SELinux限制的bash进程所产生的文件,其身份识别大多就是unconfined_u这个不受限的用户。
- system_u:系统用户,大都是系统自己产生的文件。
- 如果是网络服务所产生的文件,或是通过系统服务运行过程所产生的文件,则大部分的识别就会是system_u。
- 网络服务所产生的的文件:
- 系统服务所产生的文件:
- 如果是网络服务所产生的文件,或是通过系统服务运行过程所产生的文件,则大部分的识别就会是system_u。
角色(role):通过角色字段可以知道这个数据是属于进程、文件资源还是代表用户。-r结尾表示是role。
- object_r:代表的是文件和目录等资源,这应该是是最常见的;(注意这里object_r代表的是角色,与object这个SELinux寻找的目标是不同意义的,虽然目标object可能是object_r类型)。
- system_r:代表的就是进程,不过,一般用户,也会被指定为system_r。
类型(type):一个主体进程与目标之间是否具有可以读写的权限与类型字段有关,而类型字段在文件与进程方面的定义又有所不同,不同位置的定义分别是:
- type:在文件资源(Object)上面称为类型(Type);
- domain:在主体进程(Subject)则称为域(Domain)。
- domain与需要与type搭配,则该进程才能够顺利读取文件资源。
为了能够继续探讨,所以先通过指令ps -eZ打印进程的安全上下文信息,查看下
安全上下文在系统【进程的SELinux的相关信息】:
[root@study ~]# ps -eZ | egrep -n 'systemd|kthreadd|ksoftirqd/0|sshd|bash'
2:system_u:system_r:init_t:s0 1 ? 00:00:16 systemd
3:system_u:system_r:kernel_t:s0 2 ? 00:00:00 kthreadd
4:system_u:system_r:kernel_t:s0 3 ? 00:00:06 ksoftirqd/0
65:system_u:system_r:syslogd_t:s0 500 ? 00:00:05 systemd-journal
69:system_u:system_r:udev_t:s0-s0:c0.c1023 542 ? 00:00:00 systemd-udevd
104:system_u:system_r:systemd_logind_t:s0 745 ? 00:00:04 systemd-logind
128:system_u:system_r:sshd_t:s0-s0:c0.c1023 1134 ? 00:00:00 sshd
194:unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2681 pts/0 00:00:00 bash
196:unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 18140 pts/0 00:00:00 bash
252:unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 35684 pts/1 00:00:00 bash
253:unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 38772 pts/1 00:00:00 bash
这些数据在targeted策略下的对应如下:
| 身份识别 | 角色 | 对应在 targeted 的意义 |
|---|---|---|
| unconfined_u | unconfined_r | 一般可登录用户的进程,基本没有受限的进程的意思。大多数都是用户已经顺利登陆系统(不论是网络还是本机登陆来获取可用的shell)后,所用来操作系统的进程。如bash,X window 相关软件等。 |
| system_u | system_r | 由于为系统账号,因此是非交互式的系统运作进程,大多数的系统进程均是这种类型。 |
然后为了考察类型(type)的重要性,我们来接着探讨:
在默认的targeted策略中,identify与role不重要,重要的是type与domain。这两者之间的关系可以通过使用crond以及它的配置文件来说明。即通过/usr/sbin/crond、/etc/crontab、/etc/cron.d等文件来说明。首先,先看看这几个东西的安全上下文内容。
# 查看所有进程的安全上下文,然后通过关键字cron从中找到domain是crond_t的安全上下文
[root@study ~]# ps -eZ | grep cron
system_u:system_r:crond_t:s0-s0:c0.c1023 1157 ? 00:00:01 crond
system_u:system_r:crond_t:s0-s0:c0.c1023 1161 ? 00:00:00 atd
# 这个安全上下文的类型名称为*****crond_t******
# 在来看其执行文件配置文件、配置文件等的安全上下文内容
[root@study ~]# ll -Zd /usr/sbin/crond /etc/crontab /etc/cron.d
drwxr-xr-x. root root system_u:object_r:system_cron_spool_t:s0 /etc/cron.d
-rw-r--r--. root root system_u:object_r:system_cron_spool_t:s0 /etc/crontab
-rwxr-xr-x. root root system_u:object_r:crond_exec_t:s0 /usr/sbin/crond
当执行/usr/sbin/crond(一个可执行文件)之后,这个程序变成的进程的domain类型会是crond_t,而这个crond_t能够读取的配置文件则为 system_cron_spool_t 这种的类型。
因此无论是/etc/cron.d还是/var/spool/cron都会是相关的SELinux类型(/var/spool/cron为user)
- 通过指令 [#|| -Zd /usr/sbin/crond] 可以发现:
- 首先触发一个可执行的目标文件,即具有crond_exec_t这个类型(Type)的/usr/sbin/crond文件。
- 可以通过指令 [#ps -eZ | grep cron] 找到的那个最后一个字段值是crond的那一行可以发现:
- 类型(Type)crond_exec_t会让这个文件所产生的主体进程(Subject)具有crond_t这个域(domain);
- 策略针对这个域已经制定了许多了规则,其中包括这个域可以读取的目标资源类型,比如,crond_t被设置为可以读取类型 system_cron_spool_t 的目标文件(Object_r),
- /etc/cron.d/与/etc/crontab的Type是 system_cron_spool_t。所以这两个文件可以被进程crond【看见】。由于配置文件放在/etc/cron.d/目录下,所以就能够被crond这个程序所【看见】。
- SELinux决定的是你能否【看见】,但最终能否真正的处理,还要看你【看见】的目标的rwx。
从上面可以看出domain与type基本上是决定性作用。而且可以发现:
- 策略内必须制定非常详细的domain/type相关性,目录还可以稍微接受,10000个文件还不烦死;
- 若文件的type设置错误,那么即使权限设置为777,那也没有办法读取目标资源,这样就可以避免文件被设置为777带来的危险。
实例1:新建一个普通文件testfile,然后将其放到 /etc/cron.d,然后强制重启cron,然后看一下日志文件/var/log/cron,看看有没有什么问题。
[root@study ~]# vim testfile
[root@study ~]# mv testfile /etc/cron.d
[root@study ~]# ll /etc/cron.d/testfile
-rw-r--r--. 1 root root 0 7月 10 14:06 /etc/cron.d/testfile
[root@study ~]# systemctl restart crond
[root@study ~]# tail /var/log/cron
Jul 10 14:07:04 study crond[91969]: ((null)) Unauthorized SELinux context=system_u:system_r:system_cronjob_t:s0-s0:c0.c1023 file_context=unconfined_u:object_r:admin_home_t:s0 (/etc/cron.d/testfile)
Jul 10 14:07:04 study crond[91969]: (root) FAILED (loading cron table)
从结果来看启动配置文件/etc/cron.d没有办法被crond这个服务所读取,原因就是安全上下文不匹配。
实例2:查看一下crond与bash这两个进程是否受限制。
[root@study ~]# ps -eZ | egrep 'cron|bash'
system_u:system_r:crond_t:s0-s0:c0.c1023 1161 ? 00:00:00 atd
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2681 pts/0 00:00:00 bash
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 69839 pts/1 00:00:00 bash
system_u:system_r:crond_t:s0-s0:c0.c1023 91969 ? 00:00:00 crond
从结果来看,crond是受限主体进程,而bash因为是本机进程,就是不受限(unconfined_t)类型。
5.4.4 SELinux的三种状态/模式
- enforcing(默认):强制模式,代表SELinux运行中,表示禁止违反安全策略,限制domain/type;(可以参考下面的cron主体进程)
- permissive:警告模式,代表SELinux运行中,不过仅会有警告信息,并不会实际限制domain/type的读写。这种模式可以用来作为SELinux的debug之用;
- disabled:关闭模式,关闭SELinux。(可以参考下面的bash主体进程)
[root@study ~]# ps -eZ | egrep 'cron|bash'
system_u:system_r:crond_t:s0-s0:c0.c1023 1161 ? 00:00:00 atd
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 2681 pts/0 00:00:00 bash
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 69839 pts/1 00:00:00 bash
system_u:system_r:crond_t:s0-s0:c0.c1023 91969 ? 00:00:00 crond
从结果来看,crond是受限主体进程,而bash因为是本机进程,就是不受限(unconfined_t)类型。
SELinux的配置文件:/etc/selinux/config
- 可以修改SELinux的状态/模式;
- 也可以修改SELinux的策略。
[root@study ~]# more /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of three two values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
注意点:
- SELinux运行时,只能够被切换成强制(Enforcing)或宽容(Permissive)模式,这是因为SELinux是整合到内存中的,不能够直接关闭SELinux,修改文件修改为关闭(Disabled),要生效只能重启系统。
- 如果要从Disabled转换成启动SELinux,必须等待一些时间,因为必须要等待系统针对SELinux的文件写入上下文的信息,因此启动过程会花费很长一段时间。
- 如果已经载Enforcing模式,但是可能由于一些设置的问题导致SELinux让一些服务无法正常地运行,此时可以将SELinux调成宽容模式。
5.5 SELinux的相关命令
5.5.1 SELinux 三种状态/模式的修改 与 策略的规则的查询和开关
- getenforce:确认当前的SELinux的状态。
[root@study ~]# getenforce Enforcing - setenforce:修改当前的SELinux的状态,1代表enforcing,0代表permissive。
- 通过指令修改,只能更改enforcing和permissive模式;
[root@study ~]# setenforce 0 [root@study ~]# getenforce Permissive - 通过指令进行的修改,在系统重启后,会被重置;
- 通过修改/etc/selinux/config,可以修改成enforcing、permissive、disabled;
[root@study ~]# vim /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=disabled # 在这里修改成disabled,需要重启 # SELINUXTYPE= can take one of three two values: # targeted - Targeted processes are protected, # minimum - Modification of targeted policy. Only selected processes are protected. # mls - Multi Level Security protection. SELINUXTYPE=targeted [root@study ~]# shutdown -h now # 重启 # *******重启之后********* [root@study ~]# getenforce Disabled [root@study ~]# sestatus SELinux status: disabled # 还要再编辑/etc/selinux/config,设成SELinux开启模式,enforcing或permissive都可以,然后重启 - 通过修改/etc/selinux/config,会成为永久状态,除非再次修改/etc/selinux/config文件。
- 通过指令修改,只能更改enforcing和permissive模式;
- sestatus:可以查看SELinux的是否启动,SELinux的挂载点与根目录、策略、目前模式等。
[root@study ~]# sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 28 - getsebool:查询SELinux的策略的全部的规则的启动与否,getsebool -b与sestatus -b都可以。
[root@study ~]# getsebool -a abrt_anon_write --> off abrt_handle_event --> off abrt_upload_watch_anon_write --> on antivirus_can_scan_system --> off antivirus_use_jit --> off auditadm_exec_content --> on authlogin_nsswitch_use_ldap --> off authlogin_radius --> off authlogin_yubikey --> off awstats_purge_apache_log_files --> off boinc_execmem --> on cdrecord_read_content --> off .........# 还有很多,可以看到根httpd、ftpd、sambda - seinfo:承接上面的getsebool的各种规则,可以知道每个规则要进行限制的内容,包括所有SELinux身份识别种类、角色种类、类型种类,以及各种不知道的种类,不加参数可以列出各个种类的统计。不过seinfo需要安装。
- sesearch:可以列出SELinux的各个对象,可以读取的目标类型以及可以对目标类型进行的操作。
crond这个进程的SELinux的类型是域crond_t,可以通过sesearch找出crond_t对应可以找出的各种类型的目标类型。以及这个目标类型的类型。
这样就可以知道为什么有些文件读取不了了。不过这个命令是与seinfo一起安装的。[root@study ~]# sesearch [-A] [-s 主体类型如进程crond] [-t 目标类型] [-b 取布尔值的SELinux规则名] 选项与参数: -A:列出后面数据中,允许[读取或放行]的相关信息。 -t:后面还要接类型,例如-t httpd_t -b:后面还要接SELinux的规则,例如 -b httpd_enable_ftp_server - semanage:可以知道各种策略的规则到底是什么用处。
[root@study ~]# semanage boolean -l|grep httpd_enable_homedirs SELinux boolean类型规则 State Default Description httpd_enable_homedirs (关 , 关) Allow httpd to enable homedirs
5.5.2 SELinux 安全上下文的修改相关指令
- chcon:手动修改文件的 SELinux 类型
- restorecon:让文件恢复正确的SELinux类型
- semanage:默认目录的安全上下文的查询与修改
六、ACL:权限的设计
6.1 ACL的意义
ACL是Access Control List的缩写,中译为【访问 控制列表】。主要目的是提供传统的用户,用户组,其他人的rwx权限之外的详细权限设置。
ACL可以针对单一用户、单一文件或目录来进行rwx的权限设置。
传统(上面的)权限的集合关系的缺陷,虽然rwx作为独立的权限,可以对用户、群组、其他人、以及对文件、目录的应用,进行独立的规定,但是r、w、x这些权限的意义有时候显得过于僵硬了。
例如:甲乙丙共同进行一个项目A,而经理a负责这个项目的检查:
- 如果让这个经理a加入项目群组A,那么经理a就对这个目录有权限rwx的完整权限。如果他发现项目内容不顺眼,因为w权限,所以他可以随意删除项目A中的文件,他要是把项目重要内容删了,你能求谁?
- 如果让这个经理a以其他人的身份,而root赋予这个项目2775的权限,让他有其他人的权限,那么就开放了其他人的缺口,这个项目就很危险了。
我们没有办法灵活地根据自己的实际需要,指定自己的权限规则。而ACL的存在就是为了解决这个问题。
6.2 ACL的支持
现在所有常见的Linux文件系统的挂载参数中(ext2、ext3、ext4、xfs等)都包含ACL功能。所以你无须进行任何操作,ACL就可以被使用,不过如果不确定系统是否真的支持ACL的话,那么就来检查一下内核挂载时显示的信息吧!
[root@study ~]# dmesg |grep -i acl
[ 1.528410] systemd[1]: systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
[ 2.289473] SGI XFS with ACLs, security attributes, no debug enabled
可以在打印出来的内容中找到ACL,可以看出XFS支持ACL。
6.3 ACL的设置技巧:getfacl、setacl
6.3.1 setfacl:设置某个目录或文件的ACL规范
setfacl [-bkdR] [{-m|-x} acl_spec] [{-M|-X} acl_file] file ...setfacl设置文件或目录的ACL。在命令行,一个命令序列后面跟一个文件序列(文件序列后面还可以跟另一个命令序列)
以下是一些对命令setfacl的描述:
- -m和-x选项后面跟一个ACL条目。多个ACL条目由逗号分隔。
- -M和-X从一个文件或从标准输入读取ACL。
- --set 和--set-file 选项设置文件或目录的ACL,那么以前的ACL会被覆盖,这个操作的ACL条目必须包括权限。
- -m(--modify)和-M(---modify-file)选项修改文件或目录的ACL,这个操作的ACL条目必须包括权限。
- -x(--remove)和-X(--remove-file)选项删除ACL条目。移除"does not exist"(ACL不存在)的条目不是一个error。
- 当用-M和-X选项读取文件时,setfacl接受getfacl的输出。文件的每行最多有一个ACL条目。一行中井号#后面的内容会被判断为注释。
ACL的应用的必要条件:
- 如果setfacl被用在一个不支持ACL的文件系统,则setfacl对文件模式的权限位(file mode permission bits)进行操作。
- 如果ACL不完全符合权限位,setfacl会修改文件模式权限位以尽可能地反映ACL,setfact会写入一个错误信息给stdout,并返回一个大于0的退出状态(exit status)。
- 只有文件的owner和能够使用CAP_FOWNER的进程(在当前Linux中,只有root是唯一具有CAP_FOWNER功能的用户)有修改文件ACL的权利。即只有文件拥有者和root才能修改文件ACL。
setfacl的语法与常用权限:
setfacl [-bkdR] [{-m|-x} acl_spec] [{-M|-X} acl_file] file ...
-b(--remove-all) # 删除所有存在的ACL参数。但owner、group、others的基本ACL条目被保留
-x(--remove) # 删除后续文件的acl_spec,[{-m|-x} acl_spec]是一种结构,表示-m与-x不能共存
-m(--modify) # 修改后续文件的acl_spec,[{-m|-x} acl_spec]是一种结构,表示-m与-x不能共存
-k(--remove-default) # 删除默认的ACL条目。
-R(--recursive) # 递归设置ACL,即包括子目录和文件都被这样设置。
-d(--default) # 设置默认的ACL条目,输入集中的一般ACL条目将会被升级为默认ACL条目,而输入集中的已经是默认ACL条目的项将被丢弃。(如果发生这种情形将发出警告)。
ACL条目的形式
ACL条目的映射规则d等价于default,u等价于user,g等价于group,m等价于mask,o等价于other。
setfacl程序识别以下的ACL条目格式:
[d:][u:] uid [:权限]等效于[default:][user:] uid [:权限] :表示指定用户的权限,如果uid为空,则为文件所有者的权限
[d:][g:] gid [:权限]等效于[default:][group:] gid [:权限] :表示指定用户组的权限,如果gid为空,则为文件用户组的权限
[d:][o:][:权限]等效于[default:][other:][:权限] : 表示指定others的权限
[d:][m:][:权限]等效于[default:][mask:][:权限] : m/mask表示有效权限(effective permission)
# 用户或用户组所设置【ACL权限】必须要存在于mask的权限设置范围内才会生效
示例1:设置umask为022,用root在/tmp下新建一个文件aclfile和一个目录acldir,在里面新建文件与目录,并用ll列出权限,然后用setfacl设置用户zyx_1对aclfile的权限为rx,然后通过user字段值为空,设置【文件拥有者】对文件acldir的权限是rwx。然后用ll查看文件及目录属性。
[root@study ~]# umask
0022
[root@study ~]# cd /tmp
[root@study tmp]# touch aclfile
[root@study tmp]# ll aclfile
-rw-r--r--. 1 root root 0 7月 12 08:03 aclfile
# 针对【单一用户zyx_1】设置权限,取代了针对【群组】和【其他人】身份设置权限
[root@study tmp]# setfacl -m u:zyx_1:rx aclfile
[root@study tmp]# ll aclfile
-rw-r-xr--+ 1 root root 0 7月 12 08:03 aclfile
# u:后面为空则表示当前用户
[root@study tmp]# setfacl -m u::rwx aclfile
[root@study tmp]# ll aclfile
-rwxr-xr--+ 1 root root 0 7月 12 08:03 aclfile
5.3.2 getfacl:获取某个文件或目录的ACL设置规范
getfacl,选项几乎与setfacl相同。所以这里只演示下getfacl查询文件的ACL结果。
[root@study tmp]# getfacl aclfile
# file: aclfile # 结果中会说明:文件名
# owner: root :文件拥有者
# group: root :文件群组
user::rwx # 使用者权限
user:zyx_1:r-x # ACL的价值体现:特殊身份的权限设置
group::r-- # 群组权限只有r
mask::r-x # 此文件默认的有效权限
other::r-- # 其他人的权限只有r
范例2:特定的单一用户组的权限设置:【g:用户组名:权限】
[root@study tmp]# setfacl -m g:groupA:rx aclfile
[root@study tmp]# getfacl aclfile
# file: aclfile
# owner: root
# group: root
user::rwx
user:zyx_1:r-x
group::r--
group:groupA:r-x # 增加了这个特定群组的权限设定
mask::r-x
other::r--
m/mask表示有效权限(effective permission),用户或用户组所设置的ACL权限必须要存在于mask的权限设置范围内才会生效
[root@study tmp]# setfacl -m m:r aclfile
[root@study tmp]# getfacl aclfile
# file: aclfile
# owner: root
# group: root
user::rwx
user:zyx_1:r-x #effective:r-- # 虽然特设zyx_1为rx,但是由于mask的限制,只有r有效
group::r--
group:groupA:r-x #effective:r-- # 虽然特设groupA为rx,但是由于mask的限制,只有r有效
mask::r-- # 所有用户可以设置的ACL权限只有r
other::r--