您的当前位置:首页正文

Linux——权限管理

2024-11-24 来源:个人技术集锦

1、ACL权限

在普通权限中,用户对文件只有三种身份,就是属主、属组和其他人;每种用户身份拥有读(read)、写(write)和执行(execute)三种权限。但是在实际工作中,这三种身份实在是不够用,我们举个例子来看看。先看看示意图,如下图所示:

1.1、开启ACL权限

在CentOS 6.x系统中ACL权限默认是开启的,不需要手工开启。不过,如果你的操作系统不是CentOS 6.x,那该如何查看ACL权限是否开启了呢?可以这样查看:

    [root@localhost ~]# mount
    /dev/sda1 on /boot type ext4 (rw)
    /dev/sda3 on / type ext4 (rw)
    …省略部分输出…
    #使用mount命令可以看到系统中已经挂载的分区,但是并没有看到ACL权限的设置
    [root@localhost ~]# dumpe2fs -h /dev/sda3
    #dumpe2fs是查询指定分区文件系统详细信息的命令
    选项:
        -h: 仅显示超级块中的信息,而不显示磁盘块组的详细信息
    ...省略部分输出...
    Default mount options:   user_xattr acl
    ...省略部分输出...

使用mount命令可以查看到系统中已经挂载的分区,而使用dumpe2fs命令可以查看到这个分区文件系统的详细信息。大家可以看到,我们的ACL权限是/dev/sda3分区的默认挂载选项,所以不需要手工挂载。不过我的Linux系统如果没有不过我的Linux系统如果没有默认挂载,则可以手工挂载吗?当然可以,执行如下命令:

    [root@localhost ~]# mount -o remount, acl /
    #重新挂载根分区,并加入ACL权限

使用mount命令重新挂载,并加入ACL权限。不过使用此命令是临时生效的。要想永久生效,需要修改/etc/fstab文件,命令如下:

    [root@localhost ~]# vi /etc/fstab
    UUID=c2ca6f57-b15c-43ea-bca0-f239083d8bd2  /   ext4   defaults, acl       1  1
    #加入ACL权限
    [root@localhost ~]# mount -o remount /
    #重新挂载文件系统或重启系统,使修改生效

1.2、ACL权限设置

1.2.1、ACL权限管理命令

我们知道了ACL权限的作用,也知道了如何开启ACL权限,接下来学习如何查看和设定ACL权限。命令如下:

    [root@localhost ~]# getfacle 文件名
    #查看ACL权限
    [root@localhost ~]# setfacl 选项 文件名
    #设定ACL权限
    选项:
        -m:     设定ACL权限。如果是给予用户ACL权限,则使用“u:用户名:权限”格式赋予;
                如果是给予组ACL权限,则使用“g:组名:权限”格式赋予
        -x:     删除指定的ACL权限
        -b:     删除所有的ACL权限
        -d:     设定默认ACL权限。只对目录生效,指目录中新建立的文件拥有此默认权限
        -k:     删除默认ACL权限
        -R:     递归设定ACL权限。指设定的ACL权限会对目录下的所有子文件生效

1.2.2、给用户和用户组添加ACL权限

    例子1:设定用户ACL权限
    [root@localhost ~]# useradd zhangsan
    [root@localhost ~]# useradd lisi
    [root@localhost ~]# useradd st
    [root@localhost ~]# groupadd tgroup
    #添加需要试验的用户和用户组,省略设定密码的过程
    [root@localhost ~]# mkdir /project
    #建立需要分配权限的目录
    [root@localhost ~]# chown root:tgroup /project/
    #改变/project目录的属主和属组
    [root@localhost ~]# chmod 770 /project/
    #指定/project目录的权限
    [root@localhost ~]# ll -d /project/
    drwxrwx--- 2 root tgroup 4096 1月  19 04:21 /project/
    #查看一下权限,已经符合要求了
    #这时st学员来试听了,如何给她分配权限
    [root@localhost ~]# setfacl -m u:st:rx /project/
    #给用户st赋予r-x权限,使用“u:用户名:权限”格式
    [root@localhost /]# cd /
    [root@localhost /]# ll -d project/
    drwxrwx---+ 3 root tgroup 4096 1月  19 05:20 project/
    #使用ls –l查询时会发现,在权限位后面多了一个“+”,表示此目录拥有ACL权限
    [root@localhost /]# getfacl project
    #查看/project目录的ACL权限
    # file: project                ←  文件名
    # owner: root                  ←  文件的属主
    # group: tgroup                ←  文件的属组
    user::rwx                       ←  用户名栏是空的,说明是属主的权限
    user:st:r-x                    ←  用户st的权限
    group::rwx                      ←  组名栏是空的,说明是属组的权限
    mask::rwx                       ←  mask权限
    other::---                      ←  其他人的权限

我想给用户组赋予ACL权限可以吗?当然可以,命令如下:

    例子2:设定用户组ACL权限
    [root@localhost /]# groupadd tgroup2
    #添加测试组
    [root@localhost /]# setfacl -m g:tgroup2:rwx project/
    #为组tgroup2分配ACL权限,使用“g:组名:权限”格式
    [root@localhost /]# ll -d project/
    drwxrwx---+ 2 root tgroup 4096 1月  19 04:21 project/
    #属组并没有更改
    [root@localhost /]# getfacl project/
    # file: project/
    # owner: root
    # group: tgroup
    user::rwx
    user:st:r-x
    group::rwx
    group:tgroup2:rwx          ←  用户组tgroup2拥有了rwx权限
    mask::rwx
    other::---

1.2.3、最大有效权限mask

mask是用来指定最大有效权限的。mask的默认权限是rwx,如果我给st用户赋予了r-x的ACL权限,mj需要和mask的rwx权限“相与”才能得到st的真正权限,也就是r-x“相与”rwxtj出的值是r-x,所以st用户拥有r-x权限。如果把mask的权限改为r–,和st用户的权限相与,也就是r–“相与”r-x得出的值是r–,st用户的权限就会变为只读。大家可以这么理解:用户和用户组所设定的权限必须在mask权限设定的范围之内才能生效,mask权限就是最大有效权限。

不过我们一般不更改mask权限,只要给予mask最大权限rwx,那么任何权限和mask权限相与,得出的值都是权限本身。也就是说,我们通过给用户和用户组直接赋予权限,就可以生效,这样做更直观。

补充:逻辑与运算的运算符是“and”。可以理解为生活中所说的“并且”。也就是相与的两个值都为真,结果才为真;有一个值为假,与的结果就为假。比如A相与B,结果如下表所示:

修改最大有效权限的命令如下:

    例子3:修改mask权限
    [root@localhost /]# setfacl -m m:rx project/
    #设定mask权限为r-x,使用“m:权限”格式
    [root@localhost /]# getfacl project/
    # file: project/
    # owner: root
    # group: tgroup
    user::rwx
    group::rwx                   #effective:r-x
    mask::r-x
    #mask权限变为r-x
    other::---

1.2.4、默认ACL权限和递归ACL权限

    例子5:默认ACL权限
    [root@localhost /]# setfacl -m d:u:st:rx /project/
    #使用“d:u:用户名:权限”格式设定默认ACL权限
    [root@localhost project]# getfacl project/
    # file: project/
    # owner: root
    # group: tgroup
    user::rwx
    user:st:r-x
    group::rwx
    group:tgroup2:rwx
    mask::rwx
    other::---
    default:user::rwx              ←  多出了default字段
    default:user:st:r-x
    default:group::rwx
    default:mask::rwx
    default:other::---
    [root@localhost /]# cd project/
    [root@localhost project]# touch bcd
    [root@localhost project]# mkdir d2
    #新建子文件和子目录
    [root@localhost project]# ll
    总用量 8
    -rw-r--r--  1 root root   0 1月  19 05:20 abc
    -rw-rw----+ 1 root root   0 1月  19 05:33 bcd
    drwxr-xr-x  2 root root 4096 1月  19 05:20 d1
    drwxrwx---+ 2 root root 4096 1月  19 05:33 d2
    #新建的bcd和d2已经继承了父目录的ACL权限

大家发现了吗?原先的abc和d1还是没有ACL权限,因为默认ACL权限是针对新建立的文件生效的。

    例子6:递归ACL权限
    [root@localhost project]# setfacl -m u:st:rx -R /project/
    #-R 递归
    [root@localhost project]# ll
    总用量 8
    -rw-r-xr--+ 1 root root   0 1月  19 05:20 abc
    -rw-rwx---+ 1 root root   0 1月  19 05:33 bcd
    drwxr-xr-x+ 2 root root 4096 1月  19 05:20 d1
    drwxrwx---+ 2 root root 4096 1月  19 05:33 d2
    #abc和d1也拥有了ACL权限

1.2.5、删除ACL权限

我们来看看怎么删除ACL权限,命令如下:

    例子7:删除指定的ACL权限
    [root@localhost /]# setfacl -x u:st /project/
    #删除指定用户和用户组的ACL权限
    [root@localhost /]# getfacl project/
    # file: project/
    # owner: root
    # group: tgroup
    user::rwx
    group::rwx
    group:tgroup2:rwx
    mask::rwx
    other::---
    #st用户的权限已被删除
    例子8:删除所有ACL权限
    [root@localhost /]# setfacl -b project/
    #会删除文件的所有ACL权限
    [root@localhost /]# getfacl project/
    # file: project/
    # owner: root
    # group: tgroup
    user::rwx
    group::rwx
    other::---
    #所有ACL权限已被删除

2、文件特殊权限——SetUID、SetGID、Sticky BIT

2.1、文件特殊权限之SetUID

2.1.1、什么是SetUID

在Linux系统中我们已经学习过r(读)、w(写)、x(执行)这三种文件普通权限,但是我们在查询系统文件权限时会发现出现了一些其他权限字母,比如:

    [root@localhost ~]# ll /usr/bin/passwd
    -rwsr-xr-x 1 root root 25980 2月  222012 /usr/bin/passwd

大家发现了吗?在属主本来应该写x(执行)权限的位置出现了一个小写s,这是什么权限?我们把这种权限称作SetUID权限,也叫作SUID的特殊权限。这种权限有什么作用呢?我们知道,在Linux系统中,每个普通用户都可以更改自己的密码,这是合理的设置。问题是,普通用户的信息保存在/etc/passwd文件中,用户的密码实际保存在/etc/shadow文件中,也就是说,普通用户在更改自己的密码时修改了/etc/shadow文件中的加密密码,但是,看下面的代码:

    [root@localhost ~]# ll /etc/passwd
    -rw-r--r-- 1 root root 1728 1月  19 04:20 /etc/passwd
    [root@localhost ~]# ll /etc/shadow
    ---------- 1 root root 1373 1月  19 04:21 /etc/shadow

/etc/passwd文件的权限是644,意味着只有超级用户root可以读/写,普通用户只有只读权限。/etc/shadow文件的权限是000,也就是没有任何权限。这意味着只有超级用户可以读取文件内容,并且可以强制修改文件内容;而普通用户没有任何针对/etc/shadow文件的权限。也就是说,普通用户对这两个文件其实都是没有写权限的,那为什么普通用户可以修改自己的权限呢?

其实,普通用户可以修改自己的密码的秘密不在于/etc/passwd和/etc/shadow这两个文件,而在于passwd命令。我们再来看看passwd命令的权限:

    [root@localhost ~]# ll /usr/bin/passwd
    -rwsr-xr-x. 1 root root 25980 2月  222012 /usr/bin/passwd

passwd命令拥有特殊权限SetUID,也就是在属主的权限位的执行权限上是s。可以这样来理解它:当一个具有执行权限的文件设置SetUID权限后,用户在执行这个文件时将以文件所有者的身份来执行。passwd命令拥有SetUID权限,所有者为root(Linux中的命令默认所有者都是root),也就是说,当普通用户使用passwd命令更改自己的密码的时候,实际上是在用passwd命令所有者root的身份在执行passwd命令,root当然可以将密码写入/etc/shadow文件,所以普通用户也可以修改/etc/shadow文件,命令执行完成后,该身份也随之消失。

SetUID的功能可以这样理解:

  • 只有可以执行的二进制程序才能设定SetUID权限。
  • 命令执行者要对该程序拥有x(执行)权限。
  • 命令执行者在执行该程序时获得该程序文件属主的身份(在执行程序的过程中变为文件的属主)。
  • SetUID权限只在该程序执行过程中有效,也就是说身份改变只在程序执行过程中有效。

举个例子,有一个用户lamp,她可以修改自己的权限,因为passwd命令拥有SetUID权限;但是她不能查看/etc/shadow文件的内容,因为查看文件的命令(如cat)没有SetUID权限。命令如下:

    [root@localhost ~]# su - lamp
    [lamp@localhost ~]$ passwd
    更改用户 lamp 的密码 。
    为 lamp 更改 STRESS 密码。
    (当前)UNIX 密码:                       ←  输入旧密码
    新的 密码:                                 ←  输入新密码
    重新输入新的 密码:
    passwd: 所有的身份验证令牌已经成功更新
    #lamp可以修改自己的密码
    [lamp@localhost ~]$ cat /etc/shadow
    cat: /etc/shadow: 权限不够
    #但是不能查看/etc/shadow文件的内容

我们画一张示意图来理解上述过程,如上图所示:

  • passwd是系统命令,可以执行,所以可以赋予SetUID权限。
  • lamp用户对passwd命令拥有x(执行)权限。
  • lamp用户在执行passwd命令的过程中,会暂时切换为root身份,所以可以修改/etc/shadow文件。
  • 命令结束,lamp用户切换回自己的身份。

cat命令没有SetUID权限,所以就使用lamp用户身份去访问/etc/shadow文件,当然没有相应权限了。
如果把/usr/bin/passwd命令的SetUID权限取消,普通用户是不是就不能修改自己的密码了呢?试试吧:

    [root@localhost ~]# chmod u-s /usr/bin/passwd
    #属主取消SetUID权限
    [root@localhost ~]# ll /usr/bin/passwd
    -rwxr-xr-x. 1 root root 25980 2月  222012 /usr/bin/passwd
    [root@localhost ~]# su - lamp
    [lamp@localhost ~]$ passwd
    更改用户 lamp 的密码 。
    为 lamp 更改 STRESS 密码。
    (当前)UNIX 密码:                   ←  看起来没有什么问题
    新的 密码:
    重新输入新的 密码:
    passwd: 鉴定令牌操作错误              ←  但是最后密码没有生效

这个实验可以说明SetUID的作用了吧,不过记得一定要把/usr/bin/passwd命令的SetUID权限加回来。

2.2、文件特殊权限之SetGID

那什么是SetGID呢?当s标志在属主的x位置时是SetUID,那么s标志在属组的x位置时是SetGID,简称为SGID。比如:

    [root@localhost ~]# ll /usr/bin/locate
    -rwx--s--x 1 root slocate 35612 8月  242010 /usr/bin/locate
  • 只有可执行的二进制程序才能设置SetGID权限。
  • 命令执行者要对该程序拥有x(执行)权限。
  • 命令执行者在执行程序的时候,组身份升级为该程序文件的属组。
  • SetGID权限同样只在该程序执行过程中有效,也就是说,组身份改变只在程序执行过程中有效。

和passwd命令类似,普通用户在执行locate命令的时候,会获取locate属组的组身份。locate命令是在系统中按照文件名查找符合条件的文件的,不过它不是直接搜索系统的,而是搜索/var/lib/mlocate/mlocate.db这个数据库的。

2.3、文件特殊权限之Sticky BIT

  • 粘着位目前只对目录有效。
  • 普通用户对该目录拥有w和x权限,即普通用户可以在此目录中拥有写入权限。
  • 如果没有粘着位,那么,因为普通用户拥有w权限,所以可以删除此目录下的所有文件,包括其他用户建立的文件。一旦被赋予了粘着位,除了root可以删除所有文件,普通用户就算拥有w权限,也只能删除自己建立的文件,而不能删除其他用户建立的文件。
    [root@localhost ~]# ll -d /tmp/
    drwxrwxrwt 4 root root 4096 1月  20 06:17 /tmp/
    [root@localhost ~]# useradd lamp
    [root@localhost ~]# useradd lamp1
    #建立测试用户lamp和lamp1,省略设置密码过程
    [root@localhost ~]# su – lamp
    #切换为lamp用户
    [lamp@localhost ~]$ cd /tmp/
    [lamp@localhost tmp]$ touch ftest
    #建立测试文件
    [lamp@localhost tmp]$ ll ftest
    -rw-rw-r-- 1 lamp lamp 0 1月  20 06:36 ftest
    [lamp@localhost tmp]$ su - lamp1
    密码:                                   ←  输入lamp1用户的密码
    #切换成lamp1用户
    [lamp1@localhost ~]$ cd /tmp/
    [lamp1@localhost tmp]$ rm -rf ftest
    rm: 无法删除"ftest": 不允许的操作
    #虽然/tmp/目录的权限是777,但是拥有SBIT权限,所以lamp1用户不能删除其他用户建立的文件

2.4、特殊权限设置

说了这么多,到底该如何设置特殊权限呢?其实还是依赖chmod命令的,只不过文件的普通权限只有三个数字,例如,“755”代表属主拥有读、写、执行权限;属组拥有读、执行权限;其他人拥有读、执行权限。如果把特殊权限也考虑在内,那么权限就应该写成“4755”,其中“4”就是特殊权限SetUID了,“755”还是代表属主、属组和其他人的权限。这几个特殊权限这样来表示:

  • 4代表SetUID。
  • 2代表SetGID。
  • 1代表SBIT。

举个例子,我们手工赋予一下特殊权限:

    [root@localhost ~]# touch ftest
    [root@localhost ~]# chmod 4755 ftest
    #赋予SetUID权限
    [root@localhost ~]# ll ftest
    -rwsr-xr-x 1 root root 0 1月  20 23:54 ftest
    #查看一下,属主的x位变成了s
    [root@localhost ~]# chmod 2755 ftest
    #赋予SetGID权限
    [root@localhost ~]# ll ftest
    -rwxr-sr-x 1 root root 0 1月  20 23:54 ftest
    #查看一下,属组的x位变成了s
    [root@localhost ~]# mkdir dtest
    [root@localhost ~]# chmod 1755 dtest/
    #SBIT只对目录有效,所以建立测试目录,并赋予SBIT权限
    [root@localhost ~]# ll -d dtest/
    drwxr-xr-t 2 root root 4096 1月  20 23:56 dtest/
    #查看一下,其他人的x位变成了s

我们可以把特殊权限设置为“7777”吗?命令执行是没有问题的,这样会把SetUID、SetGID、SBIT权限都赋予一个文件,命令如下:

    [root@localhost ~]# chmod 7777 ftest
    #一次赋予SetUID、SetGID和SBIT权限
    [root@localhost ~]# ll ftest
    -rwsrwsrwt 1 root root 0 1月  20 23:54 ftest
    [root@localhost ~]# chmod 0755 ftest
    #取消特殊权限
    [root@localhost ~]# ll ftest
    -rwxr-xr-x 1 root root 0 1月  20 23:54 ftest

我们讲过,在赋予权限的时候可以采用字母的方式,这对特殊权限来讲是同样适用的。比如我们可以通过“u+s”赋予SetUID权限,通过“g+s”赋予SetGID权限,通过“o+t”赋予SBIT权限。命令如下:

    [root@localhost ~]# chmod u+s, g+s, o+t ftest
    #设置特殊权限
    [root@localhost ~]# ll ftest
    -rwsr-sr-t 1 root root 0 1月  20 23:54 ftest
    [root@localhost ~]# chmod u-s, g-s, o-t ftest
    #取消特殊权限
    [root@localhost ~]# ll ftest
    -rwxr-xr-x 1 root root 0 1月  20 23:54 ftest

最后,还有一个大家要注意的问题,特殊权限只针对具有可执行权限的文件有效,不具有x权限的文件被赋予了SetUID和SetGID权限会被标记为S, SBIT权限会被标记为T,仔细想一下,如果没有可执行权限,则设置特殊权限无任何意义。命令如下:

    [root@localhost ~]# chmod 7666 ftest
    [root@localhost ~]# ll ftest
    -rwSrwSrwT 1 root root 0 1月  20 23:54 ftest

大家也可以这样理解:S和T代表“空的”,没有任何意义。

3、文件系统属性chattr权限

3.1、设定文件系统属性chattr

chatrr只有root用户可以使用,用来修改文件系统的权限属性,建立凌驾于rwx基础权限之上的授权。命令格式如下:

    [root@localhost ~]# chattr [+-=] [选项] 文件或目录名
    选项:
        +:  增加权限
        -:  删除权限
        =:  等于某权限
        i:  如果对文件设置i属性,那么不允许对文件进行删除、改名,也不能添加和修改数据;
            如果对目录设置i属性,那么只能修改目录下文件中的数据,但不允许建立和删除文件
        a:  如果对文件设置a属性,那么只能在文件中增加数据,但是不能删除和修改数据;如果
            对目录设置a属性,那么只允许在目录中建立和修改文件,但是不允许删除文件
        e:  Linux中的绝大多数文件都默认拥有e属性,表示该文件是使用ext文件系统进行
            存储的,而且不能使用“chattr -e”命令取消e属性

4、系统命令sudo权限

4.1、 sudo用法

sudo使用简单,管理员root使用visudo命令即可编辑其配置文件/etc/sudoers进行授权。命令如下:

    [root@localhost ~]# visudo
    …省略部分输出…
    root   ALL=(ALL)      ALL
    # %wheel       ALL=(ALL)      ALL          ←  此行是注释的,没有生效
    #这两行是系统为我们提供的模板,我们参照它写自己的就可以了
    …省略部分输出…

解释一下文件的格式:

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

4个参数的具体含义如下:

  • 用户名/组名:代表root给哪个用户或用户组赋予命令,注意组名前加“%”。
  • 用户可以用指定的命令管理指定IP地址的服务器。如果写ALL,则代表用户可以管理任何主机;如果写固定IP,则代表用户可以管理指定的服务器。如果我们在这里写本机的IP地址,则不代表只允许本机的用户使用指定命令,而代表指定的用户可以从任何IP地址来管理当前服务器。
  • 可使用的身份:就是把来源用户切换成什么身份使用,(ALL)代表可以切换成任意身份。这个字段可以省略。
  • 授权命令:代表root把什么命令授权给普通用户。默认是ALL,代表任何命令,这当然不行。如果需要给哪个命令授权,则只需写入命令名即可。不过需要注意,一定要写成绝对路径。

4.2、sudo举例

例子1,授权用户lamp可以重启服务器,则由root用户添加如下行:

    [root@localhost ~]# visudo
    lamp        ALL= /sbin/shutdown –r now

指定组名用百分号标记,如%admgroup,多个授权命令之间用逗号分隔。用户lamp可以使用sudo -l查看授权的命令列表。

    [root@localhost ~]# su – lamp
    #切换成lamp用户
    [lamp@localhost ~]$ sudo -l
    [sudo] password for lamp:          ←  需要输入lamp用户的密码
    User lamp may run the following commands on this host:
    (root) /sbin/shutdown -r now
    #可以看到lamp用户拥有了shutdown –r now的权限

提示输入密码为lamp普通用户的密码,是为了验证操作服务器的用户是不是lamp用户本人。lamp用户需要执行时,只需使用如下命令:

    [lamp@localhost ~]$ sudo /sbin/shutdown -r now
显示全文