linux用户用户组与ACL

使用者ID:UID与GID

在使用Linux的过程中,经常会遇到各种用户ID(user identifier, UID)和组ID(group identifier, GID),Linux也是通过对这些ID的管理实现的自主访问控制(discretionary access control, DAC)。

用户ID(英语:user identifier,一般缩写为User ID或UID),全称用户标识符,在类UNIX系统中是内核用来辨识用户的一个无符号整型数值,亦是UNIX文件系统与进程的必要组成部分之一。[1]

虽然我们登录Linux主机时使用的是账户,但是对于Linux系统而言,它只认识ID。而ID与账户的对应就记录在/etc/passwd文件中。可以通过命令id查看各个id与账户名的对应关系:
image_192

从上图中我们可以看到,我的用户名是wang,它的UID是1000,GID也是1000

UID范围

在不同系统中,UID值范围也有所不同,但一般来说UID是由一个16bit的无符号整数表示的,其范围在0-65535之间。

UID 账户
0 root,超级用户的UID总为0
65535 nobody,总是UID的最大值
1~999 一般约定是系统保留范围,由系统使用
1000~65534 一般用户UID

UID与GID分类

值得注意的是,以下的分类都是针对进程而言的,只有进程才会有下述几种ID。

中文 英文 解释
有效用户ID与有效组ID Effective UID, EUID, Effective GID, GID 在创建和访问文件时发挥作用。具体来说,创建文件时,系统内核将根据创建文件的进程的EUID与EGID设定文件的所有者/组属性,而在访问文件时,内核亦根据访问进程的EUID与EGID决定其能否访问文件。
真实用户ID与真实用户组 Real UID, RUID, Real GID, RGID 用于辨识进程的真正所有者,且会影响到进程发送信号的权限。
暂存用户ID Saved UID, SUID 特权权限运行的进程暂时需要做一些不需特权的操作时使用,这种情况下进程会暂时将自己的有效用户ID从特权用户(常为root)对应的UID变为某个非特权用户对应的UID,而后将原有的特权用户UID复制为SUID暂存;之后当进程完成不需特权的操作后,进程使用SUID的值重置EUID以重新获得特权。
文件系统用户ID File System UID, FSUID 在Linux中使用,且只用于对文件系统的访问权限控制,在没有明确设定的情况下与EUID相同(若FSUID为root的UID,则SUID、RUID与EUID必至少有一亦为root的UID),且EUID改变也会影响到FSUID。设立FSUID是为了允许程序(如NFS服务器)在不需获取向给定UID账户发送信号的情况下以给定UID的权限来限定自己的文件系统权限。

访问文件

举例而言,假设我要执行以下命令,sudo vim /etc/apt/sources.list,我当前的用户是wang,那么这个这个进程的RUID就是1000(对应wang这个账户),而sudo指使使用root权限,因此该进程的EUID就是0root账户)。我们查看/etc/apt/sources.list文件的所有者和所有组,它的所有者是root,组是root。因此我们必须使用sudo进行提权,也即是修改进程的EUID0,这样才能够访问/etc/apt/sources.list文件,但是RUID依然是1000

创建文件

再举例创建文件。如下图所示:
image_193
文件的所有组和所有者依然与进程的EUID和EGID指定,而非RUID和RGID。

父子进程

子进程继承了父进程所有的各种UID和GID。

权限控制

这里描述的权限控制是指Linux中基于用户和用户组以及r\w\x权限的控制,其中r表示可读,w表示可写,x表示可执行。

Linux一般把文件存取的身份分为三个类别:owner/group/others,且三种身份都各有read/write/execute权限。

查看/etc/shadow的详细信息如下图所示:
image_194
分析如下:

权限 链接数 所有者 所有组 文件大小 文件最后被修改的时间 文件名
-rw-r----- 1 root shadow 1.6K May 9 2021 /etc/shadow

对权限进行详细分析如下,每个文件的权限都有10个字符表示,其中-表示无对应权限,这十个字符可分为四组,第一组就是第一个字符;表示文件类型,第二组就是第2、3、4个字符,是所有者拥有的权限,依次是r/w/x;第5、6、7个字符表示组权限,依次是r/w/x;第8、9、10个字符表示其他人的权限,依次是r/w/x。如果所在位置为-,则表示无对应权限。

对应上述/etc/shadow文件的权限为,所有者即root拥有读写权限,组shadow只有读权限,其他人没有任何权限。

rwx与421

在Linux系统中,可以使用chmod命令来改变文件的权限,例如:sudo chmod 640 /etc/shadow。这个含义就是将文件/etc/shadow的所有者权限改为6即rw;组权限改为4即r;其他人权限改为0即无任何权限。之所以6表示rw,4表示r,这是因为Linux是通过位来表示权限的。

因为文件拥有三种不同的权限r/w/x,Linux就使用3bit作为权限记录,如果是只读的那么就是100,如果是只写的就是010,如果是只可执行的就是001,可读可写的呢就是110啦。读者自行将二进制转换为十进制,就会发现6就表示110,也就是可读可写不可执行的意思啦。

当然,这里描述的3bit权限位并不是实际上Linux的权限实现机制,而是为了读者方便理解记忆,数字与权限的对应关系。实际的权限记录比较复杂。

关于权限的一些问题

  1. 一个文件可有只写权限但是不可读吗?
    答案是可以的,如下图所示。
    image_195

  2. 一个文件不具有可执行权限就一定不可执行吗?有了可执行权限就一定可以执行吗?
    答案是不一定。
    image_196
    image_197

  3. 目录的rwx

  • 目录的只读访问不允许使用cd进入目录,必须要有执行的权限才能进入。
  • 只有执行权限只能进入目录,不能看到目录下的内容,要想看到目录下的文件名和目录名,需要可读权限。
  • 一个文件能不能被删除,主要看该文件所在的目录对用户是否具有写权限,如果目录对用户没有写权限,则该目录下的所有文件都不能被删除,文件所有者除外
  • 目录的w位不设置,即使你拥有目录中某文件的w权限也不能写该文件

进程UID与文件权限类型的匹配

根据前文我们已经知道,对文件的访问和创建等操作需要检查的都是EUID,而不是RUID。即使RUID是普通用户,而EUIDroot则就拥有了对root所能访问的所有文件的权限。对应/etc/shadow我们就检查对应的root权限是读写,因此该进程就可以对/etc/shadow进行读写操作。如果,该进程的EUID不是root,但是是属于shadow组的,那么就只有读权限,否则没有任何权限。

Set-UID提权[2]

在一个典型的计算机系统中,用户需要使用超级用户的权限来完成诸如修改密码的操作。一种方式是通过守护进程(Windows下成为服务)方式来实现,另一种方式是通过设置Set-UID权限的方式来实现。

Set-UID程序和其他unix程序唯一的区别就在于他有一个特殊的标志位:Set-UID比特位。使用这个比特位的目的是告诉操作系统,当运行这个程序时应当与未设置该位的程序相区分。

我们在前文中提过,权限匹配是通过EUID来实现的。对于非Set-UID程序而言,进程的EUID是和RUID一致的,当它被一个用户ID为5000的用户运行时,RUIDEUID都是5000。而当执行一个Set-UID程序时,RUIDEUID的值是不一样的,RUID的值取决于执行该程序的用户ID,而EUID则取决于Set-UID程序文件的所有者。

设置Set-UID

image_198

提权测试

image_199

ACL(Access Control List)规则

前文所述的规则又称为UGO(user,group,others)规则,这套机制比较简单。在自主访问控制中,还有ACL规则,作为补充。在Linux系统中,ACL用于设定用户针对文件的权限。

ACL主要有两种命令进行控制,getfaclsetfacl

# 例子源于https://blog.csdn.net/pwl999/article/details/110878563
[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
// 查看/prpject目录的ACL权限
#file: project <-文件名
#owner: root <-文件的属主
#group: tgroup <-文件的属组
user::rwx <-用户名栏是空的,说明是属主的权限
user:st:r-x <-用户st的权限
group::rwx <-组名栏是空的,说明是属组的权限
mask::rwx <-mask权限
other::--- <-其他人的权限

// 大家可以看到,st 用户既不是 /prpject 目录的属主、属组,也不是其他人,我们单独给 st 用户分配了 r-x 权限。这样分配权限太方便了,完全不用先辛苦地规划用户身份了。

推荐阅读

参考文献


  1. 用户ID--维基百科 ↩︎

  2. 杜文亮. 计算机安全导论:深度实践[M]. 高等教育出版社, 2020. ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章