权限管理

ACL权限

对于一个文件,有所有者,所属组,其他人三个身份 . 不同身份的人对这个文件有不同的权限

ACL权限简介与开启

  • 任何文件都只能有一个所属组
  • ACL权限专门解决身份不够用的情况
  • 解决方法 : 不关注三个身份 , 直接给用户赋予权限
  • ACL 是 Access Control List 的缩写,称为访问控制列表,包含了对一个对象或一条记录可进行何种操作的权限定义。
  • 例如一个文件对象的 ACL 为 Alice: read,write; Bob: read,这代表 Alice 对该文件既能读又能写,而 Bob 只能读取。
  • ACL允许你给任何的用户或用户组设置任何文件/目录的访问权限

查看分区ACL权限是否开启

1
2
3
dumpe2fs -h /dev/sda
# 支持 :
# Default mount options: user_xattr acl
  • dumpe2fs命令是查询指定分区详细文件系统信息的命令
  • -h : 仅显示超级块中信息,而不显示磁盘块组的详细信息

临时开启分区ACL权限

1
2
# 重新挂载根分区,并挂载加入acl权限
mount -o remounnt,acl /

永久开启分区ACL权限

1
2
3
4
5
# 修改UUID , 添加acl
vim /etc/fstab

# 重新挂载文件系统或重启动系统,使修改生效
mount -o remount

查看与设定ACL权限 setfacl和getfacle

查看ACl命令

  • get file Access Control List
1
2
# 查看acl权限
getfacle 文件名

设定ACL权限的命令

  • set file Access Control List
1
setfacl 选项 文件名

选项 :

  • -m : 设定ACL权限
  • -x : 删除指定的ACL权限
  • -b : 删除所有的ACL权限
  • -d : 设定默认ACL权限。
  • -k : 删除默认ACL权限
  • -R : 递归设定ACL权限。

准备工作 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 创建文件夹
mkdir project_dir

# 创建两个用户
useradd user1
useradd user2

# 创建一个组
groupadd group1

# 将两个用户加入group1
gpasswd -a user1 group1
gpasswd -a user2 group1

# 将project_dir的所属者从root改为group1
chgrp group1 project_dir

# 设置project_dir的权限为770
chmod 770 project_dir

ll
# drwxrwx--- 2 root group1 4096 Aug 25 13:01 project_dir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 首先添加一个用户A , A等待被赋予权限
useradd testing_user
# 设置密码
passwd

# 针对于project_user文件 给用户testing_user赋予rx权限
# 给用户赋予r-x权限,使用 " u:用户名:权限 "格式
setfacl -m u:testing_user:rx project_dir

ll
# drwxrwx---+ 2 root group1 4096 Aug 25 13:01 project_dir
# +表示,该文件除了普通权限之外,还拥有ACL权限

# 获取project_user文件的ACL权限
getfacl project_dir
## file: project_dir (文件)
## owner: root (所有者是谁)
## group: group1 (所属组是谁)

# user::rwx (所有者的权限)
# user:testing_user:r-x
# group::rwx (所属组的权限)
# mask::rwx (见后续 : 最大有效权限)
# other::--- (其他人的权限)

user:testing_user:r-x : 既不是所有者,也不是所属组 , 但他确实对文件/目录具有权限r-x

给用户组设置ACL权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 给文件设置ACL权限
setfacl -m u:testing_user:rx project_dir

# 给组设置ACL权限
setfacl -m g:group1:rwx project_dir

ll
# drwxrwx---+ 2 root group1 4096 Aug 25 13:01 project_dir

getfacl project_dir
## file: project_dir
## owner: root
## group: group1

# user::rwx
# user:testing_user:r-x
# group::rwx
# group:group1:rwx
# mask::rwx
# other::---

给组赋予权限,使用 g:组名:权限格式

group:group1:rwx : 既不是所有者,也不是所属组 , 但他确实对文件/目录具有权限r-x

最大有效权限与删除ACL权限

最大有效权限mask

  • mask是用来指定最大有效权限的。

  • 赋予的ACL权限并不是真正的权限,是需要和mask的权限相与才能得到用户的真正权限

    简单来说就是mask和ACL都有的权限才是真正的权限

  • 所以,我们可以通过调整最大权限mask来控制ACL的权限

    所以 ,mask就是给一个天花板 , 我们主要是通过mask来防止我们在设置ACL权限时设置得过高.

  • 使用setfacl -m m:rx 文件名修改最大有效权限
    (设定mask权限为-x。使用m:权限格式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
getfacl project_dir
# user:testing_user:r-x
# mask::rwx

# 修改最大有效权限
setfacl -m m:rx project_dir

getfacl project_dir
## file: project_dir
## owner: root
## group: group1

# user::rwx
# user:testing_user:r-x
# group::rwx #effective:r-x
# group:group1:rwx #effective:r-x
# mask::r-x
# other::---

#effective:r-x : 说明了真正的有效权限为r-x

删除ACL权限

1
2
3
4
5
6
7
8
# 删除指定用户的ACL权限
setfacl -x u:用户名 文件名

# 删除指定用户组的ACL权限
setfacl -x g:组名 文件名

# 删除文件的所有的ACL权限
setfacl -b 文件名

默认ACL权限和递归ACL权限

递归权限 :

递归权限是父目录在设定ACL权限时,所有的子文件和子目录也会拥有相同的ACL权限。

1
setfacl -m u:用户名:权限 -R 文件名

示例:

1
setfacl -m u:user1:rx -R project_dir

默认ACL权限 :
默认ACL权限的作用是如果给父目录设定了默认ACL权限,那么父目录中所有新建的子文件**都会继承父目录的ACL权限

1
setfacl -m d:u:用户名:权限 文件名

示例:

1
setfacl -m d:u:user1:rx -R project_dir

默认ACL权限递归权限只能用于目录

文件特殊权限

SetUID

SetUID的功能

  • 只有可以执行的二进制程序才能设定SUID权限

  • 命令执行者要对该程序拥有x(执行)权限

  • 命令执行者在执行该程序时获得该程序文件所有者的身份

    • 在执行程序的过程中灵魂附体为文件的所有者
    • 简单来说 : 当前用户U,想要执行某个可执行文件F,文件F拥有SUID权限,并且所有者是root.当用户U执行文件F的时候,用户U就会暂时性获得root身份
  • SetUID权限只在该程序执行过程中有效,也就是说身份改变只在程序执行过程中有效

  • SUID权限的意义:

    • 普通用户可以修改自己的密码,而密码是放在了/etc/passwd文件里面 ,
    • 但是这个文件的权限是020,只有root才有权限能修改.
    • 这时候就需要借用root权限来修改了
    1
    2
    ll /etc/shadow
    # --w------- 1 root root 992 Aug 25 13:09 /etc/shadow
    • passwd命令拥有 SetUID 权限,所以普通可以修改自己的密码

      1
      2
      ll /usr/bin/passwd
      # -rwsr-xr-x. 1 root root 30768 Nov 23 2015 /usr/bin/passwd
    • cat命令没有 SetUID 权限,所以普通用户不能查看/etc/shadow文件内容

      1
      2
      ll /bin/cat
      # -rwxr-xr-x 1 root root 45224 Jun 19 2018 /bin/cat

设定SetUID的方法

1
2
3
 ll /usr/bin/passwd
# -rwsr-xr-x. 1 root root 30768 Nov 23 2015 /usr/bin/passwd
# 这里有一个s

这里的s出现在哪里,就表示是拥有什么权限:

  • -rwsr-xr-x : SUID权限
  • -rwr-xsr-x : SGID权限
  • -rwr-xr-xs : SBID 权限
  • 4代表SUID

    1
    2
    chmod 4755 文件名
    chmod u+s 文件名
  • 2代表SGID

    1
    chmod 2755 文件名
  • 1代表SBID

    1
    chmod 1755 文件名

示例 :

1
2
3
4
5
6
touch file1
# -rw-r--r-- 1 root root 0 Aug 26 03:25 file1

chmod 4755 file1
ll
# -rwsr-xr-x 1 root root 0 Aug 26 03:24 file1

取消SetUID的方法

1
2
chmod 755 文件名
chmod u-s 文件名

示例:

1
2
3
chmod 644 file1
ll
# -rw-r--r-- 1 root root 0 Aug 26 03:24 file1

chmod 755 文件名 和chmod u-s 文件名 的区别

1
2
3
4
5
6
7
8
9
10
touch file1
# -rw-r--r-- 1 root root 0 Aug 26 03:25 file1

chmod u+s file1
ll
# -rwSr--r-- 1 root root 0 Aug 26 03:24 file1

chmod u-s file1
ll
# -rw-r--r-- 1 root root 0 Aug 26 03:24 file1

我们发现chmod 4755 file1chmod u+s file1的结果不一样:

  • -rwsr-xr-x
  • -rwSr–r–

大写的S其实是报错的 , 因为一开始file1并没有执行权限

危险的SetUID

  • 关键目录应严格控制写权限。比如/,/usr/ ,/bin/
  • 用户的密码设置要严格遵守密码三原则
  • 对系统中默认应该具有 SetUID 权限的文件作一个列表,定时检查有没有这之外的文件被设置了 SetUID 权限

SetGID

SetGID针对文件的作用

  • 只有可执行的二进制程序才能设置SGID权限
  • 命令执行者要对该程序拥有ⅹ(执行)权限
  • 命令执行在执行程序的时候,组身份升级为该程序文件的属组
  • SetGID权限同样只在该程序执行过程中有效,也就是说组身份改变只在程序执行过程中有效
1
2
3
4
5
ll /usr/bin/locate
# -rwx--s--x 1 root slocate ....

ll /var/lib/mlocate/mlocate.db
# -rw-r---- 1 root slocate ....
  • /usr/bin/locate是可执行二进制程序,可以赋予SGID
  • 执行用户lamp对/usr/bin/locate命令拥有执行权限执行/usr/bin/ocate命令时,组身份会升级为 slocate组,而
    slocate组对/var/ib/locate/locate db数据库拥有r权限,所以普通用户可以使用 locate命令查询 locate
    db数据库
  • 命令结束,lamp用户的组身份返回为lamp组
1
2
chmod 2755 文件名
chmod g+s 文件名

SetGID针对目录的作用

  • 普通用户必须对此目录拥有r和x权限,才能进入此目录
  • 普通用户在此目录中的有效组会变成此目录的属组
  • 若普通用户对此目录拥有w权限时,新建的文件的默认所属组是这个目录的所属组

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
whoami
# root

mkdir test
chmod 2777 test

ll -d test
# drwxrwsrwx 2 root root 4096 Aug 26 04:21 test
# 目录有s权限 , 所有者和所属组都是root

su - blog_user
# 切换用户

# 在test目录下新建一个file1
cd test
touch file1
ll
# -rw-rw-r-- 1 blog_user root 0 Aug 26 04:22 file1
# 所有者是blog_user,但是所属组是root
# 新建的文件的默认所属组是这个目录的所属组

SetUID 和 SetGID 的区别

  • SetUID是变成可执行文件的所有者 , SetGID是变成可执行文件的所属组
  • SetGID能针对文件和目录 , SetUID只能针对文件

取消 SetGID

1
2
chmod 755 文件名
chmod g-s 文件名

Sticky BIT

SBIT粘着位作用

  • 粘着位目前只对目录有效
  • 普通用户对该目录拥有w和x权限,即普通用户可以在此目录拥有写入权限
  • 作用:
    • 如果没有粘着位,因为普通用户拥有w权限,所以可以删除此目录下所有文件,包括其他用户建立的文件。
    • 一但赋予了粘着位,除了root可以删除所有文件,普通用户就算拥有w权限,也只能删除自己建立的文件,但是不能删除其他用户建立的文件
1
2
3
ll -d /tmp
# drwxrwxrwt. 5 root root 4096 Aug 26 04:21 /tmp
# 存在t : 每个用户只能删除自己创建的文件

设置与取消粘着位

1
2
3
4
5
6
7
# 设置粘着位
chmod 1755 目录名
chmod o+t 目录名

# 取消粘着位
chmod 7777 目录名
chmod o-t 目录名

SUID, SGID, SBIT 的区别

权限作用对象不同

  • SUID 只针对可执行文件 , 权限号为4
  • SGID 针对可执行文件和目录 , 权限号为2
  • SBIT 只针对目录 , 权限号为1

所以,特殊权限号为7是没有意义的(但可以设置),因为不管是文件还是目录 , 肯定有部分权限不能生效

1
chmod 7555 文件名

文件系统属性chattr权限

  • change file attributes on a linux file system(改变文件属性)

  • 用于防止文件误删除

  • ```bash
    char [+-=] [选项] 文件或目录名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    - +:增加权限

    -:删除权限

    =:等于某权限

    - **chattr对root用户也生效**

    - 选项:

    - `i `:
    - 如果对文件设置i属性,那么不允许对文件进行删除、改名,也不能添加和修改数据;(**只能看**)
    - 如果对目录设置i属性,那么只能修改目录下文件的数据,但不允许建立和删除文件。(**只能修改现有文件**)
    - `a`:add
    - 如果对文件设置a属性,那么只能在文件中增加数据,但是不能删除也不能修改数据;(**不能删除现有数据,但是能加**)
    - 如果对目录设置a属性,那么只允许在目录中建立和修改文件,但是不允许删除(**只能新建和修改文件**)

    > i属性比a属性更为严格
    >
    > - 对于文件来说 , a可以追加数据
    > - 对于目录来说 , a可以新建文件



    #### 查看文件系统属性

    ```bash
    lsattr 选项 文件名
  • -a : 显示所有文件和目录

  • -d : 若目标是目录 , 仅列出目录本身的属性 , 而不是子文件的

示例:

对文件操作 : 只能看

1
2
3
4
5
6
7
8
9
10
11
12
13
chattr +i file1

lsattr -a file1
# ----i--------e- file1
# 拥有i属性

# 只能看
cat file1
# 123456
echo hyl >> file1
# -bash: file1: Operation not permitted
rm -rf file1
# rm: cannot remove `file1': Operation not permitted

对目录操作 : 只能修改现有文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mkdir dir2
touch di2/file2
echo 123456 >> file2

chattr +i dir2

rm -rf dir2
# rm: cannot remove `dir2/file2': Operation not permitted
rm -rf dir2/file2
# rm: cannot remove `dir2/file2': Operation not permitted

echo 7777 >> dir2/file2
cat dir2/file2
# 123456
# 7777

chattr -i dir2/
rm -rf dir2/file2

系统命令sudo权限

  • root把本来只能超级用户执行的命令赋予普通用户执行。
  • sudo的操作对象是系统命令
1
2
3
visudo
# 此命令用户赋予普通用户权限
# 实际修改的是 /etc/sudoers文件
  • root ALL =(ALL) ALL : 给某个用户赋予权限
  • %wheel ALL=(ALL) ALL : 给某一组赋予权限
1
2
3
4
5
root    ALL =(ALL)    ALL
# 用户名 被管理主机的地址=(可使用的身份) 授权命令(绝对路径)

%wheel ALL=(ALL) ALL
# %组名 被管理主机的地址=(可使用的身份) 授权命令(绝利路径)

root ALL =(ALL) ALL:
允许 某个用户 在某台计算机上 执行某条命令

  • 这里的在某台计算机上似乎很难理解
  • 如果一个网站是分布式服务器,每个服务器有IP地址
  • 那么就要将这些服务器的IP地址全都加进去 , 保证命令能在这些服务器上执行.

说人话:

1
user1    192.168.0.156=/sbin/shutdown -r now

给user1用户在输入的IP指定的机器(192.168.0.156)里运行shutdown -r now命令的权限

示例 :

  1. 授权user1用户可以重启服务器

    1
    user1     ALL=/sbin/shutdown -r now
    • user1 ALL=/sbin/shutdown表示user1能执行shutdown的所有选项
    • user1 ALL=/sbin/shutdown -r now表示user1只能执行shutdown的-r选项
  2. user1的使用方法:

    • 不能直接写:

      1
      shutdown -r now
    • 必须使用sudo:

      1
      sudo /sbin/shutdown -r now
  3. 查看user1可用的sudo命令:

    1
    sudo -l