Linux 文件权限、用户与组
😊
1 文件
1.1 文件类型
文件类型在 /usr/include/bits/stat.h 中进行定义。
该文件中共定义了 7 种类型的文件:目录文件、字符设备文件、块设备文件、常规文件、管道文件、符号连接文件、套接字文件。
1  | 
  | 
| 文件类型 | 符号 | 解释 | 
|---|---|---|
| 常规文件 (Regular)  | 
- | 
普通的文本文件、可执行文件、图像、影音文件等。 | 
| 目录文件 (Directory)  | 
d | 
即目录,目录也属于文件,用来管理子目录及其文件。 | 
| 字符设备文件 (Character device)  | 
c | 
Linux 将设备当做文件来处理,操作一个设备就像操作一个文件一样。设备文件一般放在 /dev 目录下。字符设备是每次只读取一个字符,如串口、终端或打印机等。 | 
| 块设备文件 (Block device)  | 
b | 
块设备文件:对该类型的文件访问,是以块大小为单位进行访问的。 | 
| 符号链接文件 (Symbolic link)  | 
l | 
可以链接其他文件或目录,分为软链接和硬链接。可以链接不同文件系统文件、不存在的文件等。系统会对符号链接的读写转换为对源文件/目录的读写,删除符号连接不会影响源文件。使用 ln 命令创建连接。 | 
| 套接字文件 (Socket)  | 
s | 
这种文件类型用于进程间的网络通信。也可以用在同一台主机上的进程通信。 | 
| 管道文件 (FIFO)  | 
p | 
用于进程间的通信,有时也叫做命名管道(IPC机制私用)。一个进程像命名管道中写入数据,另一个进程从命名管道中读取数据,数据读写时先入先出 FIFO。 | 
有些材料中,将字符设备文件、块设备文件、套接字文件、管道文件称为特殊文件(Special file)。
文件类型的查看可以使用 ls -l(等价于 ll),或 ls -F。
1  | [root@centos7 ~]  | 
如上表,第一列表示文件类型,常见的 - 表示常规文件、d 表示目录、l 表示链接等。说明:
.:表示当前目录。..:表示上一级目录,即父目录。.xxx:文件名之前有个点.的文件是隐藏文件,使用-a参数才能看到。
如果不想一列一列的显示看文件类型的话,可以使用 ls -F 在每一项后面添加一个后缀来进行显示:
1  | [root@centos7 ~]  | 
后缀表示文件类型如下(常规文件无后缀):

参考:
- 《Linux 高级程序设计中文第三版—第六章》
 - Introduction to Linux A Hands on Guide—Chapter 3. About files and the file system
 
1.2 文件权限
Linux 一般将文件可存取的身份分为三个类别,分别是 owner/group/others,且三种身份有各自的 read/write/execute 权限。Linux 下的用户是按照 组 来进行组织的。
Linux 是多用户多任务的操作系统,不同的用户对同一文件的访问权限可能是不同的。本章节先简单介绍 owner/group/others,详细内容将在第 3 章节介绍。
owner:文件的拥有者。group:组,每个用户都处在某个组中。如在一个开发项目中,这个组中的所有用户对开发项目都有一样的权限。但是组内的成员对自己的文件都可以设置不同的访问权限。注意:一个组内可以有对个用户,一个用户也可以属于多个分组。others:这是相对owner来说的,不和当前用户在同一个group的用户,都可以称之为others。
Linux 系统中用户信息存储在
/etc/passwd中,对应的账号密码保存在/etc/shadow中,Linux 所有的组名都记录在/etc/group内。shadow文件只有 root 有权限访问。
下面开始介绍文件权限:
1  | [root@centos7 ~]  | 
可以将 ls -al 列出来的文件内容分成 8 个组进行介绍:
文件权限
[ 1 ]。第一组共 11 个字符(最后一个
.在 OS 2.6 版本开始添加)。![22.png]()
文件类型在上一小节已经介绍,需要说明的是
-表示无权限。启用 SELinux
[ 2 ],可参考SELinux 入门,后续章节介绍。硬链接的个数
[ 3 ]:表示链接该目录/文件的硬链接的个数。拥有者身份、拥有者所属的组
[ 4 , 5 ]。文件/目录大小
[ 6 ],单位是byte。文件创建或最近一次修改日期
[ 7 ],要想看创建的详细时间可以使用ls --full-time查看。目录/文件名称
[ 8 ]:需要说明的是.表示当前目录,..表示父目录。
关于文件权限:
- 特殊文件(字符设备文件、块设备文件、套接字文件、管道文件)没有可执行权限 
x,只有读写权限。 root不受文件权限约束。以.开头的文件会默认隐藏。- 对文件的写权限,并不代表可以删除文件。本章节说的读写执行仅是针对文件的内容而言。
 
关于目录权限:
- 读权限 
r:表示可以罗列该目录下的子目录、文件。即可以使用ls命令等。 - 写权限 
w:- 创建子目录、文件。
 - 删除文件、子目录(不管文件权限如何)。
 - 更名已存在的文件、子目录。
 - 移动文件、子目录的位置。
 
 - 执行权限 
x:表示是否可进入到目录,即是否可使用cd命令,这是非常值得注意的点。 - 目录的读权限 
r表示可以有权查看目录名称,执行权限x表示可以cd到目录里面去,并且可以查看目录相关权限。 - 目录中的子目录、文件的权限受到目录的约束。
 
上面关于目录权限最后一条约束,举例说明:
如果某个目录权限对其他用户不可读写、执行 ---,如下:
1  | drwxr-x---. 4 root root 115 Jul 11 20:13 program  | 
该目录下 test.c 文件属于  alvin 用户,并具有可读写执行 rwx 权限:
1  | [root@centos7 ~]  | 
但是 alvin 用户无权使用 ls/cat 等命令查看该文件,除非目录放开权限。
1  | [root@centos7 ~]  | 
如果此时 program 开放对 others 的可执行权限,然后再用 alvin 查看该文件内容:
1  | [root@centos7 ~]  | 
除了 UNIX 权限外,Linux 还支持访问控制表(ACL)。ACL 支持更详细更精确的 权限和安全控制方式,其代价是复杂度变大以及更大的磁盘存储开销。
1.3 文件权限修改
更改权限的三个常用命令:
chgrp(change group):改变文件所属群组。chown(change owner):改变文件拥有者、所属组。chmod(change mode):改变文件的权限,SUID,SGID, SBIT 等等的特性。
chgrp语法。1
chgrp [-R] groupname dirname/filename # -R,表示递归地将目录下所有的子目录和文件都改变组
chown语法。1
chown [-R] 账号名称[:组名] dirname/filename
举例说明:
如下,可以看到
program属于 root 用户,所在组名称也为 root,但是没有可执行权限。1
2[root@centos7 ~]
drw-r-x--x. 4 root root 134 Jul 17 21:09 program将目录所属用户改为
alvin用户。1
2
3
4[root@centos7 ~]
[root@centos7 ~]
drw-r-x--x. 4 alvin root 134 Jul 17 21:09 program切换到
alvin用户,并使用ls查看该目录下的文件。1
2
3
4
5
6
7
8
9
10
11
12
13
14[alvin@centos7 root]$ ls -l /home/program/
ls: cannot access /home/program/test.c: Permission denied
ls: cannot access /home/program/test.i: Permission denied
ls: cannot access /home/program/test.s: Permission denied
ls: cannot access /home/program/test.o: Permission denied
ls: cannot access /home/program/test.exe: Permission denied
ls: cannot access /home/program/testdiretory: Permission denied
total 0
-????????? ? ? ? ? ? test.c
d????????? ? ? ? ? ? testdiretory
-????????? ? ? ? ? ? test.exe
-????????? ? ? ? ? ? test.i
-????????? ? ? ? ? ? test.o
-????????? ? ? ? ? ? test.s可以看到,虽然
alvin具有可读权限能顺利罗列出该目录下的文件/子目录名称。但是不具有可执行权限,不能查看文件相关的属性,全是一堆问号?。chmod语法。1
chmod -R xyz filename/dirname // x:用户对象,y:权限操作,z:权限类型
文件权限的设定有两种方法:数字或符号。
数字权限。文件在
owner/group/others下分别有r/w/x权限,对应的分数为:r = 4w = 2x = 1
如[-rwxrw-r-x]对应的数字权限为765。符号权限。
命令 用户对象 权限操作 权限类型 文件/目录名 chmodu:user,即 owner。g:即 group。o:即 others。a:所有人。+:加入权限。-:除去权限。=:设定权限。r/w/xfilename/dirname 数字权限举例:
1
2
3
4
5
6
7
8
9// 现在权限是 744
[root@centos7 ~]
-rwxr--r--. 1 alvin root 140 Jul 17 21:59 test.c
// 将权限修改为 777
[root@centos7 ~]
[root@centos7 ~]
-rwxrwxrwx. 1 alvin root 140 Jul 17 21:59 test.c字符权限举例:
1
2
3
4
5
6
7
8
9
10
11// 去除 owner 的可执行权限、group 用户的写权限、others 的读权限
[root@centos7 ~]
[root@centos7 ~]
-rw-r-x-wx. 1 alvin root 140 Jul 17 21:59 test.c
// 如果要让所有人可读写 test.c 文件
[root@centos7 ~]
[root@centos7 ~]
-rw-rwxrwx. 1 alvin root 140 Jul 17 21:59 test.c
1.4 SELinux
2 文件目录特殊权限
Windows 系统中,新建的文件和目录时通过继承上级目录的权限获得的初始权限,而 Linux 不同,它是通过使用 umask 默认权限来给所有新建的文件和目录赋予初始权限的。
2.1 特殊权限 SUID、SGID
我们查看如下:
1  | [root@centos7 ~]  | 
可以看到文件、目录下面除了有常规的 r/w/x 权限之外,还有 s/t 等权限,称之为特殊权限。
| 特殊权限 | 描述 | 
|---|---|
| Set UID(SUID) | 当 s 权限出现在文件 owner 的可执行权限上,此时称该文件具有 Set UID 权限,简称 SUID 权限。SUID 权限有以下约束和功能:1、SUID 权限仅对二进制文件有效。 2、执行该二进制文件的用户(执行者)必须对该文件有可执行权限。 3、执行者将会在运行该文件的期间,拥有该文件 owner 的权限。举例说明: 如上 /usr/bin/passwd 文件对 others 有可执行权限,且该文件 owner 的可执行权限位为 s,所以当用户 alvin 运行程序的期间,也就拥有了该文件所属的 root 的权限。所以 alvin 这个时候就可以改密码,更新 /etc/shadow 中相应的信息。 | 
| Set GID(SGID) | 当 s 权限出现在文件 group 的可执行权限上,此时称该文件具有 Set GID 权限,简称 SGID 权限。SGID 权限有以下约束和功能: 1、SGID 可作用于二进制程序。 2、执行该二进制文件的用户(执行者)必须对该文件有可执行权限。 3、执行者将会在运行该文件的期间,拥有该文件 group 的权限。1、SGID 可作用于目录。 2、若访问的用户对该目录有 r,x 权限,可以进入该目录。进入该目录后,该用户在该目录下的有效群组将会变为该目录所属的群组。3、若用户具有 w 权限,新建文件时,该文件所属的 group 和这个群组所属的 group 相同。 | 
| Sticky Bit(SBIT) | SBIT 只对目录有效。 有以下作用:当用户对于此目录具有 w,x 权限,当用户在该目录下建立文件或目录时,仅有自己与 root 才有权力删除该文件。典型的就是 /tmp 目录。 | 
设置 SUID/SGID/SBIT 权限:
在 1.3 章节我们说过,文件/目录权限有两种设定方式:数字、字符。
| 权限形式 | 描述 | 
|---|---|
| 数字 | 给文件/目录设定特殊权限,仅需在原 rwx 权限前再加一个数字即可。4 为 SUID 2 为 SGID 1 为 SBIT 举例:如一个文件当前权限位 [-rwxr-xr-x],如果要给该文件加上 SUID 权限,可以使用 chmod 4755 即可。特殊情况说明:如果权限位出现大写 S/T,则表示该权限位置上的权限无效,也不具有相应的特殊权限。如 chmod 7666 /test,SUID 不可作用于目录,且该目录也没有可执行权限等一系列问题。 | 
| 字符 | 这种形势下,给文件/目录加特殊权限如同加常规权限一样,如 chmod u=rwxs,go=x test。 | 
关于 SUID 需要进行说明一下:
进程运行时,有 RUID(真实 UID)、EUID(有效 UID)、SUID(设置 UID)、SSUID(saved SUID)之分。
- 进程真实 UID:RUID。运行程序文件的 UID,并非文件 
owner。 - 进程有效 UID:EUID。执行具有 
SUID权限的程序时,运行该程序的用户将继承此程序的所有者owner的权限。 - 文件 SUID:只可以用于只可执行的文件,使运行该文件的用户具有该文件 
owner的权限。 - 保存 SUID:Saved SUID,由 Linux 的 
exec()函数保存,可以把 SSUID 理解为exec()函数里面的一个局部变量。在《Unix高级环境编程 第3版》的 8.11节里面定义的。 
对于 /usr/bin/passwd 文件来说,假如以 alvin(UID = 1001) 运行时,该进程的真实 UID RUID = 1001、有效 UID EUID = 0。有效 UID 即为该文件 owner 的 UID。
1  | [root@centos7 ~]  | 
但是 alvin 文件已经具有 root 权限了,为什么不能修改其他用户的密码?这个就是 passwd 程序内部处理逻辑,也就是当真实 UID RUID = 0,才允许修改其它用户密码,否则只能修改当前用户密码。这部分在分析进程、内核学习时再进行详细分析,先给自己留个坑。
参考材料:
- 《鸟哥的 Linux 私房菜 第四版 6.4.3》
 - Linux/Unix用户权限下放
 - Linux root用户如何禁止普通用户使用passwd命令?
 - linux下进程的实际用户ID(有效组)和有效用户ID(有效组ID)
 - Linux进程控制之uid/euid/suid
 
2.2 umask 默认权限
每个登录系统的用户创建文件/目录时,这些文件和目录都有对应的默认权限。文件/目录默认权限由用户掩码 user file-creation mode mask(umask)来控制,系统也封装了 umask 这个工具。umask 显示的权限是要拿掉的权限。
系统开放给目录的默认基本权限是 777,开放给文件的默认基本权限是 666。而具体到每个用户下创建文件/目录权限由 umask 决定。
计算公式:
创建文件的默认权限 = 文件基本权限(rw-rw-rw-) - umask或创建文件的默认权限 = 666 & (~umask)。创建目录的默认权限 = 目录基本权限(rwxrwxrwx) - umask或创建目录的默认权限 = 777 & (~umask)。
使用 umask 查看默认权限掩码时,可以有两种方式显示默认权限:
字符形式。直接显示的是目录默认权限。
1
2[root@centos7 alvin]
u=rwx,g=rx,o=rx数字形式。以八进制显示当前
umask的值。因为文件权限rwx三种权限,所以系统也就采用 8 进制来进行描述了。1
2[root@centos7 ~]
0022
注意:以八进制模式显示 umask 时,可以注意到它显示了 12 bits(0002 或 0022)。umask 的第一个数字(前 3 bits)代表一个特殊权限(spicky 位、SGID、SUID、SBIT 位)。如果第一个数字设定为 0,则代表没有设置特殊位。
umask 的第一个数字代表特殊权限(sticky 位)。umask 的最后三位数字分别代表从用户拥有者(u)、组群所有者(g)和其它(o)中删除的权限。
1  | [root@centos7 alvin]  | 
举例说明:
1  | // umask 查看当前用户掩码值(八进制)  | 
umask 的值在 /etc/bashrc 和 /etc/login.defs 或 /etc/profile 文件中指定,root 为 022,一般用户为 002。这几个文件做以下区分居具体见 Shell 部分——“bash 环境配置文件”。
2.3 隐藏权限
隐藏权限是指在使用 ll 指令列出的前 10 个 -rwxrwxrwx. 权限之外的权限,必须使用 lsattr 才能查看到。相关权限使用 chattr 进行设置,Ext2/Ext3/Ext4 的 Linux 传统文件系统上能支持完整的 chattr 指令参数,使用 XFS 的CentOS 上仅支持部分参数。

对于 chattr 常用的参数是 a/i,对于 lsattr 可不指定参数。
1  | // 查看原始权限,无隐藏权限  | 
rename 改名指令的格式:
1  | rename 要修改的字符串 目标字符串 要修改的文件  | 
3 用户与组
3.1 用户介绍
系统中的每个账号对应一个 ID,称作 User ID(UID)。系统通过 UID 来管理账号,而账号名称是方便使用者而存在的。所有账号信息保存在 /etc/passwd 中。
平时我们查看文件属性列出来的账号名称( owner/group)都是通过 UID/GID 从 /etc/passwd 文件中找到对应的账号/组名称的。
用户登录系统的大概流程中,会使用终端输入的账号名称,到 /etc/passwd 中找,如果存在就继续读出 UID、GID 和账号的家目录。然后就是拿着 UID 到 /etc/shadow 中进行密码认证。
3.2 /etc/passwd 结构
/etc/passwd 的结构要从行和列两个角度来看,每一行表示一个账号,每一行有 7 列。
1  | [root@centos7 ~]  | 
第 1 列:账号名称。
第 2 列:密码。早期 Unix 系统将密码放在该列,为了安全性考虑,后来账号密码已经放到
/etc/shadow中。 目前该列使用x表示。第 3 列:UID。
1
ID 范围 ID 相关特性 0 
(系统管理员)UID == 0表示该账号属系统管理员。Linux 上默认将 root 的 UID 设置为0。1~999 
(系统账号)保留给系统使用的 1D,其实除了0之外,其他的 UID 权限与特性并没有不一样。 
默认 1000 以下的数字让给系统作为保留账号只是一个习惯。![25.png]()
1000~60000 
(普通账号)用户新建的普通账号。这个 UID 的大小范围限制在 /etc/login.defs文件中进行定义。第 4 列:GID。用户所在群组的 ID,
GID的信息保存在/etc/group中,相当于 UID 之于/etc/passwd。第 5 列:账号信息说明。这个字段几乎没啥作用,就是简单用来为当前账号做说明、备注等。
第 6 列:用户家目录。该列指定当前账号的家目录。
第 7 列:账号的 shell 路径。该列指定账号登录系统后 shell 的路径。有的系统账号是用来运行系统服务的,则相应的 shell 路径会指定为
/sbin/nologin,表示该账号不可以使用 shell。
3.3 /etc/shadow 结构
进程的运行和用户权限有关,而权限和 UID/GID 相关,所以进程需要读取 /etc/passwd 来获取不同账号的权限(该文件的权限为 -rw-r--r--.  以保证其他用户可读)。
早期的用户密码是保存在 /etc/passwd 的第二列,但是由于安全性问题,后来已经将账号密码加密后保存至 /etc/shadow 的第二列中,该文件对其他用户不可访问,只有 root 能访问。
1  | [root@centos7 ~]  | 
文件中每行代表一个用户,每一行有 8 个字段。用户的各个字段用:冒号分隔。/etc/shadow 中各个字段的含义如下:

| 字段/列 | 说明 | 
|---|---|
| 1 | 账号名称。对应于 /etc/passwd 中的账号。 | 
| 2 | 账号密码。该字段保存的是账号加密后的密码。使用 authconfig --test | grep hashing  查看当前系统使用的加密算法,CentOS 7.x 使用的是 sha512。 | 
| 3 | 上次更改密码的时间戳。该时间戳的单位是天 days。时间戳的起始日期为 1970-01-01 00:00:00。如 19560 即为 2023-07-22。 | 
| 4 | 密码不可被更改的天数。该字段指定密码在规定天数内不可以被更改。如果该字段为 0,表示密码可以随时更改。 | 
| 5 | 下次改密在多少天后。该字段表示在上次改密的基础上,指定天数后必须修改密码,否则账号将会被禁用。实际可以理解为账号的有效期。99999 为 273 年。 | 
| 6 | 密码到期前几天提示警告。在密码到期前可以设置密码到期提示,一般系统设置为 7 天。 | 
| 7 | 密码过期后多少天账号失效。如果该字段等于 n,表示字段 5 指定的时间之后的第 n+1 天该账号就将会被禁用。在这个 n 天内登录账号就会强制提示更改密码了。 | 
| 8 | 账号失效日期。该时间戳的单位是天 days。时间戳的起始日期为 1970-01-01 00:00:00。如 19560 即为 2023-07-22。 | 
| 9 | 该字段保留,看以后有没有新功能加入。 | 
密码找回方法:
- 普通用户的密码找回:可以通过 root 找好修改密码,root 账号无需知道以前的旧密码就可以更改。
 - root 密码找回:重新启动系统时进入维护模式,系统会主动的给予 root 权限的 bash 接口, 此时再以 
passwd修改密码即可;或以 Live CD 开机后挂载根目录去修改/etc/shadow, 将里面的 root 的密码字段清空,再重新启动后 root 将不用密码即可登入!登入后再赶快以passwd指令去设定 root 密码即可。 
3.4 用户组
账号的信息和密码分别保存在 /etc/passwd、/etc/shadow 中。群组的信息和密码存放在 /etc/group、/etc/gshadow 中。
/etc/passwd 的第 4 个字段为 GID,使用该字段到 /etc/group 中找到对应的群组信息。
3.5 /etc/group 结构
文件中同样每行代表一个用户组,每一行有 4 个字段。用户的各个字段用:冒号分隔。/etc/group 中各个字段的含义如下:
1  | [alvin@centos7 root]$ cat /etc/group  | 
| 字段/列 | 说明 | 
|---|---|
| 1 | 群组名称。 | 
| 2 | 组管理员的密码。为了安全性考虑,该字段已经移至 /etc/gshadow 中。该字段目前使用 x 表示。用户组密码主要是用来指定组管理员的,由于系统中的账号可能会非常多,root 用户可能没有时间进行用户的组调整,这时可以给用户组指定组管理员,如果有用户需要加入或退出某用户组,可以由该组的组管理员替代 root 进行管理。但是这项功能目前很少使用,我们也很少设置组密码。如果需要赋予某用户调整某个用户组的权限,则可以使用 sudo 命令代替。  | 
| 3 | GID。组的 ID,对应于 /etc/passwd 的第 4 个字段为 GID。 | 
| 4 | 该组的附加成员账号。 初始群组、附加群组、有效群组: 1、初始群组:每个账号 /etc/passwd 的 GID 即为该账号的初始群组,每个账号只有一个初始群组。2、附加群组:每个账号可以加入到多个群组中,除了初始群组外,这个账号加入的其他群组称为附加群组。 3、有效群组: groups 命令输出的第一个组即为当前账号的有效群组,可以使用 newgrp 在已加入的群组中指定该用户的有效群组(该指令做的改变仅在当前会话中有效,如果使用 exit 后该账号的有效群组仍然是初始群组)。新建文件/目录的权限中 GID 为有效群组。/etc/group 的最后一列表示该组的附加成员。注意:如果该用户组是某个用户的初始组,则该用户不会写入到 /etc/group 的第 4 个字段中(该字段显示的用户都是这个用户组的附加用户)。 | 
可以使用 groups 命令查看当前账号加入的组有哪些。有个问题,一个账号可以加入到多个组中,当这个账号创建文件/目录时,该文件/目录对应的 GID 是多少呢?实际上该 GID 为有效群组的 ID(effective group)。
1  | // groups 命令显示的第一个组为有效组  | 
可以使用 newgrp 在已加入的群组中指定该用户的有效群组,注意:有效群组并不一定等于初始群组。
1  | // 此时的有效群组为初始群组  | 
可以使用 newgrp 在已加入的群组中指定该用户的有效群组(该指令做的改变仅在当前会话中有效,如果使用 exit 后该账号的有效群组仍然是初始群组)。如下图:

让用户加入新的组有两个方法:
- 一个是透过系统管理员(root)利用 
usermod帮你加入 - 如果系统有设定群组管理员,那么可以通过群组管理员以 
gpasswd帮你加入他所管理的群组中。 
参考资料:
- 《鸟哥的 Linux 私房菜 第四版 13.1.3》
 - Linux /etc/group文件解析(超详细)
 
3.6 /etc/gshadow
/etc/gshadow 文件中同样每行代表一个用户组,每一行有 4 个字段。用户的各个字段用:冒号分隔。各个字段的含义如下:
1  | [root@centos7 ~]  | 
可以看到,该文件中的每一行和 /etc/group 非常像,有区别的是第 3 字段:
/etc/group:第 3 字段为GID。/etc/gshadow:第 3 字段为组管理员账号。
说明:如果第 2 字段为空或者 !,表示该群组不具有组管理员。
4 用户管理
账号管理
新增账号:
useradd命令/etc/shadow字段修改:passwd、chage命令。/etc/passwd字段修改:usermod命令。账号删除:
userdel命令。
组管理
- 创建组:
groupadd命令。 - 修改 GID、组名称:
groupmod命令。 - 删除组 :
groupdel命令。 - 创建组管理员:
gpasswd命令。 
- 创建组:
 
注意:useradd/usermod/userdel 都是系统管理员所能够使用的指令,作为一般普通账号可以使用 id [username] 查看其他账号的信息,或者直接读取 /etc/passwd 的信息。
4.1 创建账号
新增账号使用 useradd 命令。
1  | [root@centos7 ~]  | 
如果不指定 useradd 命令的参数,系统会按照预设默认值进行普通账号创建,主要有以下几项:
- 在 
/etc/passwd中创建一行数据,并填充每一列。 - 在 
/etc/sahdow中创建一行数据,默认密码为空。 - 在 
/etc/group中创建一行数据,会创建一个和账号名称一样的组名称,默认不会创建组管理员。 - 在 
/etc/gshadow中创建一行数据,默认没有管理员账号和密码。 - 在 
/home下创建一个和账号名一样的目录作为家目录。 
由于系统账号主要是用来运行系统服务,所以系统账号默认都不会创建家目录。
3.2 账号默认值
如果使用 useradd 命令不指定任何参数来创建账号时,可创建一个普通账号,该账号的默认属性由两个文件指定:
/etc/default/useradd。指定家目录基址、账号过期时间、shell 类型等。/etc/login.defs。指定账号家目录的umask=077,注意不是账号的umask。指定账号UID、GID的大小、范围,密码的限制等。
创建账号默认的值由 useradd 这个程序指定,可以使用 useradd -D 查看,这个指令会输出 /etc/default/useradd 文件的值。
1  | [root@centos7 ~]  | 
一、/etc/default/useradd 文件
| 字段 | 说明 | 
|---|---|
GROUP=100 | 
Linux 设定是让新建账号的初始群组属于 users(GID=100),但是 CentOS 上预设的初始群组和账号同名。Linux 上有两种不同的机制:1、私有群组机制:创建账号时,会自动创建一个与账号同名的群组作为该账号的初始群组。使得每个账号都有自己的家目录,并且权限为 700,具有较好的保密性。该机制并不会参考使用 GROUP=100 这个设定值,这样的系统有 REHL、CentOS、Fedora。2、公共群组机制:创建账号时,使用 GROUP=100 这个设定值作为账号的初始群组,默认的家目录权限是 755,这样的账号都可以共享家目录的文件,这样的操作系统由 SuSE。 | 
HOME=/home | 
指定用户家目录的基准目录(basedir)。用户的家目录通常与账号同名,在 /home 目录下。如 /home/alvin。 | 
INACTIVE=-1 | 
密码到期后,多少天时效。即为 /etc/shadow 的第 7 个字段。0:密码到期后立即失效,-1:密码永不失效。 | 
EXPIRE= | 
账号的失效日期,是个时间戳,单位是 day。对应 /etc/shadow 的第 8 个字段。 | 
SHELL=/bin/bash | 
系统默认使用的 shell 类型。如果是运行系统服务的系统账号,shell 类型可以设置为 /sbin/nologin,这样的账号就不使用 shell 登录系统。 | 
SKEL=/etc/skel | 
用户家目录的参考基准目录。每个新创建的用户家目录下的文件都是从这个目录复制过去的。 | 
CREATE_MAIL_SPOOL=yes | 
创建用户的邮箱 mailbox。在 /var/spool/mail/ 目录下创建一个和用户同名的邮箱文件。 | 
二、/etc/login.defs 文件
1  | [root@centos7 ~]# cat /etc/login.defs  | 
在 /etc/login.defs 文件中特别需要注意两点:
- 1)
umask表示家目录的掩码值,并非/etc/profile中指定的账号umask。 - 2)
USERGROUPS_ENAB yes指定使用userdel删除账号时,是否会删除初始群组。如果使用userdel去删除一个账号时,且该账号所属的初始群组己经没有人隶属于该群组了,那么就删除掉该群组。 
总结来说:创建账号时,要参考 /etc/default/useradd、/etc/login.defs 文件指定的属性。并在 /etc/passwd、/etc/shadow、/etc/group、/etc/gshadow 中写入相关数据。
新的一些发行的操作系统使用 PAM 模块来管理用户密码,这个管理机制在 /etc/pam.d/passwd 控制,该文件中,与密码有关的测试模块为 pam_cracklib.so,该模块会检验密码相关的信息,并且该模块的设定会取代 /etc/login.defs 中 PASS_MIN_LEN 的设定。
3.3 修改/删除账号
修改账号 /etc/passwd、/etc/shadow 的字段可以使用 usermod/passwd/chage。
如果账号不使用了,可以修改 /etc/shadow 第 8 个字段(账号失效日期)为 0,以达到禁用账号的目的,但是账号的相关数据还会保存在系统上。如果要彻底删除账号和相关数据,可以使用 userdel -r 用户名,以完整删除账号,之后使用 find / -user 用户名 来查看是否还存留该账号的数据。
usermod -L/U 用户名类似于passwd -l/u 用户名将某个账号冻结(Lock)起来,锁起来时该账号/etc/shadow第 2 列会显示!。
3.4 创建/修改/删除组(用户)
| 组操作 | 命令 | (参数)解释 | 
|---|---|---|
| 创建组 | groupadd | 
命令格式:groupadd [-g gid][-r〕组名参数: -g :指定 GID。-r:创建系统组(200<GID<1000)。 | 
| 修改 GID、组名称 | groupmod | 
命令格式:groupmod [-g gid] [-n group_name] 群组名参数: -g:要修改成该 GID。-n:要修改成该组名称 | 
| 删除组 | groupdel | 
命令格式:groupdel [groupname]说明: 如果要删除的组是某个账号的初始群组,则无法通过 groupdel 删除群组(初始群组不支持删除)。 | 
| 创建组管理员 | gpasswd | 
命令格式:gpasswd [-A user1,...] [-M user2,...] 组名主要功能:该命令可以指定组管理员、修改组管理员密码、将账号加入/移出群组。 选项与参数表: []:无参数,修改组管理员密码-A   :指定一个账号为该组的管理员,该账号无需加入该组也可以被设定-a   :将指定的用户加入到指定的群组-d   :将指定的用户从指定的群组中删除-M  :同 -a 参数,将指定的用户加入到指定的群组-r    :将组管理员密码移除-R   :使组管理员和密码失效,即在 /etc/gshadow 的第二列(管理员密码)设置 ! | 
注意:
usermod -G 组名 用户名是用户附加的组,从原来的附加组移到新的附加组。gpasswd -a 用户 用户组是将用户再加入到另外一个组,累加的关系。
参考资料:
- 《鸟哥的 Linux 私房菜第四版 13.2》
 - Linux groupadd命令:添加用户组
 
5 文件 ACL
5.1 ACL 介绍
有一个需要解决的事,在文件权限中,我们已经学习了 owner, group, others 三种身份下文件的  r, w, x  三种常规权限。还有文件/目录的 SUID, SGIT, SBIT 等特殊权限,如某个可执行文件的权限为4755,表示 -rwsr-xr-x。最后学了 chattr 设置的隐藏权限,只有 lsattr 才可以看到。
但是这些权限都是针对  owner, group, others 三种身份来设置的,无法做到对某个单独的用户、群组设置对某文件的权限控制,“如何指定某个文件仅允许某个用户/组来访问”,所以引入了文件的控制列表(Access Control List,ACL)来解决这些问题。
ACL 可以针对单一用户,单一文件或目录来进行 r/w/x 的权限控制。大部分文件系统(File System)都支持 ACL。ACL 可以做到:
- 针对单个用户:可以针对某个用户设置对某个文件/目录的访问权限。
 - 针对某个组:可以针对某个组设置对某个文件/目录的访问权限。
 - 预设权限(
mask):可以对某个目录设置好预设权限,之后在该目录下创建子目录或文件时,将会自动继承预设好的文件 ACL 权限。 
在有的文献中,有两种类型的 ACL 规则(rules):
- access ACLs:针对单个文件/目录的访问信息。
 - default ACLs:仅对目录有关,也就是上述的预设的目录权限。
 
ext2/ext3/ext4/xfs 文件系统基本都对 ACL 提供支持,可以通过如下命令查看:
1  | [alvin@centos7 ~]$ dmesg | grep -i acl  | 
可以看到系统中 XFS 文件系统支持 ACL。
5.2 setfacl 设置权限
setfacl 用来设置文件/目录的 ACL 访问权限。指令格式如下:
1  | [root@centos7 ~]  | 
举例说明:
使用 root 新建一个仅 root 有
rwx权限的文件。1
2
3
4
5
6
7
8
9
10
11
12
13// 新建文件,umask(root) = 022, file_full_mask = 666
[root@centos-7 ~]
[root@centos-7 ~]
-rw-r--r--. 1 root root 0 Jul 26 20:40 /tmp/test_acl
// 修改文件权限
[root@centos-7 ~]
[root@centos-7 ~]
-rwx------. 1 root root 0 Jul 26 20:40 /tmp/test_acl
// 此时一般的用户无法访问该文件
[alvin@centos-7 ~]$ cat /tmp/test_acl
cat: /tmp/test_acl: Permission denied给
alvin用户设置对该文件的可读权限。1
2
3
4
5[root@centos-7 ~]
// 注意观察此时的文件权限
[root@centos-7 ~]
-rwxr-----+ 1 root root 11 Jul 26 20:48 /tmp/test_acl可以看到权限最后一列有个
+,说明一个情况:文件/目录权限最后一列有+时,说明该文件/目录有相应的 ACL 权限设置。还要注意到:此时在该文件
group对应的权限上显示了r,而此时group对应的这三列是mask的值。这个地方很微妙,ACL 设置时,原先group上的三列的权限值就是默认的mask值。上述仅限于 root 创建的文件,如果是一般用户创建的文件则有不同,具体可以修改。
使用
alvin访问该文件。1
2
3
4
5
6
7
8
9
10
11
12
13
14[alvin@centos-7 ~]$ cat /tmp/test_acl
Hello ACL.
// 查看 ACL 权限,mask::r--
[alvin@centos-7 ~]$ getfacl /tmp/test_acl
getfacl: Removing leading '/' from absolute path names
user::rwx
user:alvin:r--
group::---
mask::r--
other::---可以看到
alvin已经可以访问该文件了。移除
alvin的访问权限。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16[alvin@centos-7 ~]$ cat /tmp/test_acl
cat: /tmp/test_acl: Permission denied
[alvin@centos-7 ~]$ ll /tmp/test_acl
-rwx------+ 1 root root 11 Jul 26 20:48 /tmp/test_acl
// 查看 ACL 权限,mask::---
[alvin@centos-7 ~]$ getfacl /tmp/test_acl
getfacl: Removing leading '/' from absolute path names
user::rwx
group::---
mask::---
other::---此时该文件权限中还有
+,但是alvin已经不能访问该文件了。要想完全清除该文件的+,必须要使用-b参数。1
2[alvin@centos-7 ~]$ ll /tmp/test_acl
-rwx------. 1 root root 11 Jul 26 20:48 /tmp/test_acl
说明:关于 getdacl 命令中展示的 user:alvin:r-- 等格式的语句,具体说明参见《Linux/UNIX 系统编程手册(上册)第17章 访问控制列表》。
5.3 getfacl 读取权限
查看文件权限时,如果有 +,则表示该文件有 ACL 指定的权限,这个时候可以使用 getfacl 进行查看。
命令格式:
1  | getfacl [-aceEsRLPtpndvh] file ...  | 
参数不进行单独说明,但是需要对命令返回信息进行说明:
#:文件的常规默认属性。user:文件的owner。user:alvin:r-x:表示该文件指定给 alvin 用户r-x权限。mask:指示文件/目录最大权限(也叫做有效权限,effective permission),指定给其他用户/组的权限必须在该权限范围内。
5.4 mask 最大权限
关于最大权限(有效权限)需要进行说明,这个权限会体现在 mask 这个关键字上,可以使用 m:[rwx] 来对 mask 进行修改。
1  | [root@centos-7 ~]  | 
将文件最大权限 mask 修改为只读 r--:
1  | // 修改 mask  | 
说明:关于
getdacl命令中展示的user:alvin:r--等格式的语句,具体说明参见《Linux/UNIX 系统编程手册(上册)第17章 访问控制列表》。
5.5 目录预设权限
当使用 setfacl -m [u|g]:[user|group]:权限 目录名称 给某个用户/组指定 ACL 权限后,当该用户/组成员在该目录下创建新的文件时,新的文件并不具备父目录的 ACL 权限。可以使用 setfacl -d 参数来给目录预设权限,使得该目录下新建文件/子目录都能够继承相关的 ACL 权限。-d 参数只能用于目录。
观察无预设 ACL 权限的目录。
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
30
31
32
33
34
35
36// 使用 root 账号在 /tmp 目录下新建一个目录 test_dir
[root@centos-7 ~]
// 修改目录权限为 750
[root@centos-7 ~]
[root@centos-7 ~]
drwxr-x---. 2 root root 6 Jul 26 23:52 test_dir
// 给 alvin 用户开放 r、x 权限
[root@centos-7 ~]
[root@centos-7 ~]
getfacl: Removing leading '/' from absolute path names
user::rwx
user:alvin:r-x
group::r-x
mask::r-x
other::---
// 再用 root 在 test_dir 目录创建新的文件,并查看 ACL 权限
// 可以看到新的文件并没有继承父目录 test_dir 具有的 ACL 权限
[root@centos-7 ~]
[root@centos-7 ~]
-rw-r--r--. 1 root root 0 Jul 27 00:00 /tmp/test_dir/0727.txt
[root@centos-7 ~]
getfacl: Removing leading '/' from absolute path names
user::rw-
group::r--
other::r--给目录预设权限。注意:当目录有预设权限时,使用
getfacl命令查看文件 ACL 权限时就会显示default关键字。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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49// 删除目录重新创建
[root@centos-7 ~]
[root@centos-7 ~]
[root@centos-7 ~]
[root@centos-7 ~]
drwxr-x---. 2 root root 6 Jul 27 00:06 test_dir
// 给 alvin 用户预设 ACL 权限,指定该目录的 r、w、x 权限
// 没有 x 权限,进不去目录
[root@centos-7 ~]
[root@centos-7 ~]
drwxr-x---+ 2 root root 6 Jul 27 00:21 test_dir
[root@centos-7 ~]
getfacl: Removing leading '/' from absolute path names
user::rwx
group::r-x
other::---
default:user::rwx
default:user:alvin:rwx // 这里显示的就是给 alvin 预设读写权限
default:group::r-x
default:mask::rwx
default:other::---
// 再用 root 在 test_dir 目录创建新的文件,并查看 ACL 权限
// 可以看到新创建的文件已经给 alvin 父目录的 ACL 权限了
[root@centos-7 ~]
[root@centos-7 ~]
-rw-rw----+ 1 root root 0 Jul 27 00:24 /tmp/test_dir/0727.txt
[root@centos-7 ~]
getfacl: Removing leading '/' from absolute path names
user::rw-
user:alvin:rwx // alvin 用户继承父目录 test_dir 的 ACL 权限
group::r-x
mask::rw-
other::---
// 使用 alvin 用户在 0727.txt 文件写入数据测试
// 可以看到是失败的,这是因为我们只给目录预设了权限,但是还没有讲相应的 ACL 权限给 alvin
[alvin@centos-7 ~]$ echo "Hello, my permissions inherited from parent directory." >> /tmp/test_dir/0727.txt
-bash: /tmp/test_dir/0727.txt: Permission denied最后我们看到
alvin用户并没有成功写入0727.txt文件。这是因为我们只是给目录test_dir预设了 ACL 权限,还没有给alvin用户添加访问test_dir目录的 ACL 权限。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 给 alvin 添加访问 test_dir 目录的 ACL 权限
[root@centos-7 ~]
// 查看该目录的 ACL 权限
[root@centos-7 ~]
getfacl: Removing leading '/' from absolute path names
user::rwx
user:alvin:rwx // 可以看到比上面多出来这行,也就是给 alvin 添加访问 test_dir 目录的 ACL 权限
group::r-x
mask::rwx
other::---
default:user::rwx
default:user:alvin:rwx
default:group::r-x
default:mask::rwx
default:other::---下面使用
alvin用户在0727.txt文件写入数据测试。1
2
3
4[alvin@centos-7 ~]$ echo "Hello, my permissions inherited from parent directory." >> /tmp/test_dir/0727.txt
[alvin@centos-7 ~]$ cat /tmp/test_dir/0727.txt
Hello, my permissions inherited from parent directory.可以看到写入成功。
参考内容:
- 《鸟哥的 Linux 私房菜第四版 13.3.2》
 - An introduction to Linux Access Control Lists (ACLs)
 - Access Control Lists on Linux Explained
 - How to Configure ACL(Access Control Lists) in Linux FileSystem
 
6 用户切换
Linux 是多用户多任务的操作系统,为了保证系统的安全性,有的服务不允许某些账号登录。不同用户之间也必须有相应的隔离。
如 telnet、ssh 服务都可以拒绝 root 用户登录。在服务器中,一般都是以普通账号身份进行登录。要在不同的账号账号进行切换,可以使用  su、sudo 两个命令。
su 和 sudo 的区别:
su:可以切换到目标用户的 shell 环境,但是必须要知道目标用户的密码才能进行切换。sudo:以目标用户身份运行命令,需验证用户自己的密码。但是需要设置/etc/sudoers文件,给用户进行授权,指定哪些用户/组可以使用sudo命令。
6.1 su
su 命令切换用户身份时,有 login-shell 和 non-login shell 两种方式,即是否切换用户环境变量的两种方式。通过 man su 可以获取这些信息:
- non-login shell 方式:用户使用 
su命令时不加任何参数,如su alvin。- 不会改变当前目录
 - 切换到目标用户后,关于环境变量,只会改变 
HOME/SHELL环境变量(如果是从 root 切换到普通用户,则还会改变USER/LOGNAME变量),其他环境变量还是切换前用户的值。特别PATH/PWD等环境变量并不会更改。 
 - login-shell 方式:使用 
-或-l参数,会完整地切换到新的 shell 中。- 切换至目标用户的家目录中。
 - 环境变量内容都全部为目标用户的环境。
 
 
在
man su输出信息中可以看到,系统使用PAM模块来管理su的认证、账号和会话管理。
命令格式:
1  | su [-lm] [-c 指令] 用户名  | 
举例说明:
以 non-login shell 方式切换。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 不加任何参数时,以 non-login shell 方式
[alvin@centos-7 ~]$ su root
Password:
// 查看当前用户身份,发现已经成功切换至 root
[root@centos-7 alvin]
uid=0(root) gid=0(root) groups=0(root)
context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
// 查看当前用户的环境(仅列出部分环境变量)
// 可以看到,USER、PATH、MAIL、PWD、LOGNAME 都是原 alvin 的环境
[root@centos-7 alvin]
USER=alvin
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:
/home/alvin/.local/bin:/home/alvin/bin
MAIL=/var/spool/mail/alvin
PWD=/home/alvin
HOME=/root
LOGNAME=alvin以 login shell 方式切换。切换用户后会有提示上次 login shell 的时间信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 使用 - 或 -l 参数切换,不指定用户的话默认切换至 root(su -)
[alvin@centos-7 ~]$ su -l root
Password:
Last login: Thu Jul 27 22:49:15 CST 2023 on pts/0
[root@centos-7 ~]
uid=0(root) gid=0(root) groups=0(root)
context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
// 可以看到所有的环境变量已经全部被切换为目标用户的了(仅列出部分环境变量)
[root@centos-7 ~]
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=root
6.2 sudo
当使用 su 命令切换至 root 时,必须要输入 root 密码,并且还会切换至 root 环境。这样很不妥当,如果每次使用 su - -c 执行一条命令,每次都要输入 root 密码,可能会带来密码泄露的问题。另外系统中还有很多指定 /sbin/nologin 运行系统服务的账号,不能使用 su - 切换登录到该用户。为了解决这些问题,可以使用 sudo 命令来以目标用户的身份来执行命令。
sudo 的功能:以指定用户身份运行命令。
除了 root 以外,其他用户要想使用 sudo 命令,必须使用 root 在 /etc/sudoers 文件中对用户进行授权,否则没有权限使用 sudo 命令。修改该文件必须直接使用 visudo,该命令的语法类似于 vi/vim,但是不能使用 vi/vim 对该文件进行编辑。
/etc/sudoers 文件遵循相关的规范,文件保存时会自动检查相关语法是否符合规范,如果不符合则会提示,并且无法保存。
命令格式:
1  | sudo [-bACEh] [-u 目标用户]  | 
一般的普通用户,没有在 /etc/sudoers 中对齐权限设置,是没有权限执行 sudo 命令的,如下。
1  | [alvin@centos-7 ~]$ sudo -u root cat /etc/shadow  | 
当 alvin 用户使用 sudo 命令后,在 root 账户的操作中会有提示,如下。
1  | [root@centos-7 ~]  | 
6.3 /etc/sudoers
Linux 上不同用户之间有严格控制,而要以目标用户身份运行命令,一般是用 sudo -u 目标用户 要执行的命令行 来进行操作。而除了 root 之外,其他所有用户要实行 sudo 命令,必须要在 /etc/sudoers 中设置了相关的权限才行。
修改 /etc/sudoers 文件直接使用 visudo 即可(不参数),关于用户权限这儿,主要是:
1  | 当前登录账号 登入者的来源主机名=(可切换的身份) 可下达的指令  | 
- 当前登录账号:以哪个账号执行 
sudo命令。 - 登入者的来源主机名:“当前登录账号”由哪部主机联机到本 Linux 主机,这个设定值可以指定客户端计算机(信任的来源的意思)。
ALL表示任何主机(包括网络主机)。 - (可切换的身份):要切换至的目标账号。
 - 可下达的指令:切换到目标账号之后,指定可以执行的命令有哪些。这个命令的路径必须以绝对路径进行指定。如 
/usr/bin/cat 
简单介绍 /etc/sudoers 给用户指定简单权限的操作:
给某个用户指定权限。
1
2
3
4
5
6
7
8
9[root@centos-7 ~]
...
root ALL=(ALL) ALL // root 账号可以切换至任何用户,执行任何命令。
alvin ALL=(testuser) NOPASSWD: ALL // alvin 账号可以切换至 testuser 账号,
// 切换时不需要再输入 alvin 的密码。切换之后可以执行 testuser 账号的所有命令。
alvin ALL=(michael) NOPASSWD: /usr/bin/telnet// alvin 账号可以切换至 michael 账号,
// 切换后仅能执行 telnet 命令。
alvin ALL=(maria) !/usr/bin/telnet // alvin 账号可以切换至 maria 账号,
// 但是不可以执行 telnet 命令给某个组指定权限。组名之前加上
%,以区别用户名。1
2
3
4
5[root@centos-7 ~]
...
%wheel ALL=(ALL) ALL // wheel 组的任何用户可以切换至任何用户,执行任何命令。
%alvin ALL=(ALL) NOPASSWD:ALL // alvin 组的任何用户可以切换至任何用户,执行任何命令。
// 切换时无需再输入自己的密码CentOS 7.x 之后,
wheel组就默认开放了如上的权限。使用别名。
如果是批量给多个用户指定相关的权限,可以通过别名的方式进行操作,实际上也就是通过定义变量来进行操作,而定义变量类型的关键字是
/etc/sudoers文件预设好的,直接用即可。主要有以下四个变量类型关键字(定义的变量名必须大写):Host_Alias:定义主机别名。User_Alias: 用户别名,别名成员可以是用户,用户组(前面要加%号)Runas_Alias:这个别名指定的是“目标用户”, 即 sudo 允许切换至的用户Cmnd_Alias:命令别名
1
2
3
4[root@centos-7 ~]
User_Alias PASSWDUSER = alvin,cater,god
Cmnd_Alias PASSWDCOM = !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
PASSWDUSER ALL=(root) PASSWDCOM上述指令说明:指定
PASSWDUSER表示的三个用户,可以以 root 身份修改其他用户的密码。但是要注意,禁用了passwd和passwd root以防止这三个账号修改 root 的命令。备注:变量名必须使用大写英文字母,不能包含小写英文、数字、特殊符号(包括
_)等。举例:
设置
alvin的sudo权限。1
2
3
4[root@centos-7 ~]
...
alvin ALL=(root) NOPASSWD: !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
...使用
alvin账号修改nana(uid=1002)账号的密码。但是不能修改 root 的密码1
2
3
4
5
6
7
8
9[alvin@centos-7 ~]$ sudo -u root passwd nana
Changing password for user nana.
New password:
BAD PASSWORD: The password is shorter than 8 characters
Retype new password:
passwd: all authentication tokens updated successfully.
[alvin@centos-7 ~]$ sudo -u root passwd root
Sorry, user alvin is not allowed to execute '/bin/passwd root' as root on centos-7.9.shared.时间间隔。
在不使用
NOPASSWD指定时,用户(非 root)执行sudo命令必须输入自己的密码,但是在 5 分钟内该用户再次使用sudo命令时无需再次输入自己的密码。类似于锁屏的超时时间。sudo搭配su。实际上就是给指定用户权限,让这些用户输入自己的密码即可提权到 root,这些用户就无需每次都是用
sudo来执行命令了。1
2User_Alias ADMINS = prol, pro2, pro3, myuser1
ADMINS ALL=(root) /bin/su -验证:
给
nana用户授权。1
2
3
4[root@centos-7 ~]
...
nana ALL=(root) /usr/bin/su -
...nana用户提权并切换至 root 账号。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17[nana@centos-7 ~]$ sudo su -
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for nana:
Last login: Thu Jul 27 23:19:19 CST 2023 on pts/0
Last failed login: Fri Jul 28 21:00:19 CST 2023 on pts/0
There was 1 failed login attempt since the last successful login.
[root@centos-7 ~]
uid=0(root) gid=0(root) groups=0(root)
context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

