第六章. 管理本地用户和组
学习目标:
- 描述Linux系统上用户和组的用途
- 配置sudo授权
- 创建、修改和删除本地用户
- 创建、修改和删除本地组
- 设置用户密码管理策略,手动锁定和解锁账户。
6.1 描述用户和组的概念
什么是用户
用户账户是为在不同的人员和不同的程序间提供隔离,对外,用户使用用户名供人们使用。对内,系统分配唯一标识号(UID)来区分不同的账户。操作系统内部,每一个程序都作为特定用户执行。每一个文件,都属于特定的用户。
用户账户有三种主要类型:超级用户、系统用户和普通用户
- 超级用户账号用于管理系统,超级用户的名称为root,其账户UID为0.超级用户对系统具有完全访问权限。
- 系统用户账号供系统服务进程使用,用户无法使用系统用户账户以交互方式登陆。
- 普通用户账号用于处理日常工作的普通用户账号。
1.使用id命令显示当前已登陆用户的信息
[yanjianjun@ansible ~]$ id
uid=1000(yanjianjun) gid=1000(yanjianjun) groups=1000(yanjianjun)
2.使用id useranme显示其他用户信息
[yanjianjun@ansible ~]$ id student
uid=1001(student) gid=1001(student) groups=1001(student)
3.使用ls -l查看文件的属性
[yanjianjun@ansible ~]$ ls -l file1
-rw-rw-r-- 1 yanjianjun yanjianjun 0 Jan 11 11:28 file1
4.使用ls -ld查看目录的属性
[yanjianjun@ansible ~]$ ls -ld dir1
drwxrwxr-x 2 yanjianjun yanjianjun 6 Jan 11 11:29 dir1
5.使用ps命令,查看当前shell中的进程
[yanjianjun@ansible ~]$ ps
PID TTY TIME CMD
122308 pts/0 00:00:00 bash
122987 pts/0 00:00:00 ps
6.使用ps -a查看与某一终端相关联的所有进程
[yanjianjun@ansible ~]$ ps -a
PID TTY TIME CMD
122306 pts/0 00:00:00 su
122308 pts/0 00:00:00 bash
122998 pts/0 00:00:00 ps
7.使用ps -au查看与进程相关联的用户
[yanjianjun@ansible ~]$ ps -au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2065 0.0 0.0 110108 856 tty1 Ss+ Jan05 0:00 /sbin/agetty --noclear tty1 linux
root 102657 0.0 0.0 116896 3600 pts/0 Ss Jan09 0:00 -bash
root 122306 0.0 0.0 231876 3428 pts/0 S 11:28 0:00 su - yanjianjun
yanjian+ 122308 0.0 0.0 116660 3288 pts/0 S 11:28 0:00 -bash
yanjian+ 123035 0.0 0.0 155372 1872 pts/0 R+ 11:34 0:00 ps -au
账户信息数据库文件/etc/passwd文件解析:
/etc/passwd文件中的每一行都包含了有关某个用户的信息,它分为七个以冒号分隔的字段。示例如下
yanjianjun: x:1000:1000::/home/yanjianjun:/bin/bash
1. 字段1:用户名
2. 字段2:旧版本用来存放用户密码,现在已移至/etc/shadow文件,该字段始终应为x。
3. 字段3:用户ID(UID)
4. 字段4:用户的组ID(GID)
5. 字段5:用户的真实姓名
6. 字段6:用户的家目录(也称主目录),shell启动时的初始目录,包含用户数据和配置设置。
7.字段7:用户的默认shell程序,用户登陆时运行/bin/bash程序。如果不允许用户进行交互式登陆,则设置为/sbin/nologin。
- 什么是组
组是需要共享文件和其他系统资源访问权限的用户集合,组可以向一组用户授予文件访问权限。与用户相似,组也有组名称。在内部,系统通过分配唯一标识号(GID)来区分不同的组。组名称和GID的对应关系存放在组账号信息数据库中/etc/group。
/etc/group文件的每一行都包含了组相关的信息,字段以冒号分隔,如下示例:
yanjianjun: x:1000:
1.字段1:组名称
2. 字段2:旧版本中的组密码字段,该字段始终为x。
3. 字段3:组id(GID)
4. 字段4:作为附属组的用户列表
主要组和附属组
主组:每个用户都有一个主组,在/etc/passwd文件中GID号对应的组。默认情况下,在创建新用户时,会创建一个与用户同名的新组,该组将用作新用户的主要组。
附属组:用户也可以有附属组,附属组的成员资格由/etc/group文件确定。根据所在的组是否有访问权限,将授予用户对文件的访问权限。
6.2 获取超级用户访问权限
6.2.1 超级用户
任何操作系统都具有超级用户,即具有操作系统全部权限的用户。在红帽Linux中,此用户为root用户。要执行诸如安装或删除软件以及管理系统文件和目录等任务,必须将特权提升到root用户。
尽管如此,这种无限制的特权也带来了职责问题。root用户拥有足以破坏系统的无限制权限,如删除系统文件和目录,删除用户账户,以及添加后门等。如果root账户泄露,则其他人就有可能拥有系统的绝对控制权。在本课程中,建议管理员以普通用户身份登录,仅在需要时升级到root用户。
警告:红帽建议管理员不直接以root身份登录,取而代之,系统管理员应当以普通用户登录,然后使用其他机制(例如su、sudo或PolicyKit)临时活得超级用户特权。
6.2.2 切换用户
su命令让用户切换至另一个用户账号,如果从普通用户执行su,系统会提示您输入要切换的账户密码。当以root用户身份执行su时,则无需输入密码。
[root@ansible ~]# su - yanjianjun
Last login: Mon Jan 11 11:28:11 CST 2021 on pts/0
[yanjianjun@ansible ~]$
[yanjianjun@ansible ~]$ su - student
Password:
如果省略用户名,默认情况下su或su -命令尝试切换到root。
[yanjianjun@ansible ~]$ su -
Password:
[root@ansible ~]#
命令su与命令su -的区别
- 命令su启动非登录shell,而su仅以该用户身份启动shell,但使用的是原始用户的环境变量。
- 命令su -启动登录shell,会将shell环境设置为如同以该用户身份重新登录一样。
大多数情况下,管理员应该运行su -进行账户切换,以获的目标用户的环境变量。
6.2.3 通过sudo运行命令
与su不同,sudo通常要求用户输入自己的密码进行身份验证,而非输入正在尝试访问的用户账户密码。此外,sudo可以配置为允许特定用户像某个其他用户一样运行任何命令,或仅允许以该用户身份运行部分命令。
1.如果sudo已配置为允许yanjianjun用户以root身份执行命令usermod,那么yanjianjun就可以来锁定或解锁用户账户
[yanjianjun@ansible ~]$ sudo usermod -L student
[sudo] password for yanjianjun:
[yanjianjun@ansible ~]$ su - student
Password:
su: Authentication failure
[yanjianjun@ansible ~]$
2.如果某用户尝试以另一用户身份运行命令,但sudo配置不允许,则该命令将被阻止。这次尝试也会被记录下来。
[yanjianjun@ansible ~]$ sudo tail /var/log/secure
yanjianjun is not in the sudoers file. This incident will be reported.
[yanjianjun@ansible ~]$
执行sudo的另一个优点在于,执行的所有命令都默认将日志记录到/var/log/secure中
Jan 11 22:04:21 ansible su: pam_unix(su-l:session): session opened for user yanjianjun by root(uid=0)
Jan 11 22:04:23 ansible sudo: yanjianjun : user NOT in sudoers ; TTY=pts/0 ; PWD=/home/yanjianjun ; USER=root ; COMMAND=/bin/tail /var/log/secure
Jan 11 22:06:07 ansible su: pam_unix(su-l:session): session closed for user yanjianjun
在红帽企业Linux7和红帽企业Linux8中,wheel组的所有成员都可以使用sudo以任何用户身份运行命令,包括root在内。这是红帽企业Linux6及更早版本相比的变化,在Linux7以前的版本,wheel组的成员默认情况下不会获得这种管理权限。
6.2.4 通过sudo获取交互式Root Shell
方法一:如果系统的非管理员用户能够使用sudo来运行su命令,则个可以从该账户运行sudo su -来获取root用户的交互式shell。这式因为sudo将以root用户身份运行su -,而root用户无需输入密码即可使用su。
方法二:使用sudo -i命令,这将切换到root账户并运行该用户的默认shell及关联的shell登录脚本。
[yanjianjun@ansible ~]$ sudo -i
[sudo] password for yanjianjun:
[root@ansible ~]#
sudo su -命令与sudo -i的行为不完全相同
6.2.5 配置sudo
sudo的主配置文件为/etc/sudoers,sudoers文件有固定的语法要求,为避免出现问题,应使用特殊的visudo命令进行编辑。
例如:以下来自/etc/sudoers文件的一行可为组wheel的成员启用sudo访问权限。
%wheel ALL=(ALL) ALL
- %wheel是用户或组,%开头的是一个组,即wheel组
- 第一个ALL 允许从任何机器终端访问sudo
- 第二个ALL sudo 命令被允许以任何用户身份执行(指目标用户,也就是以谁的身份去执行命令)
- 第三个ALL wheel组中的用户可以像系统上的任何用户一样运行命令
默认情况下,/etc/sudoers还包含/etc/sudoers.d目录中所有文件的内容,作为配置文件的一部分。这样管理员只需将像一个的文件放入该目录中,即可为用户添加sudo访问权限。
注意
使用/etc/sudoers.d目录下的补充文件比较简单方便,只需将文件复制到目录中或从目录中删除文件,即可启用或禁用sudo访问权限。在本课程中,您将在/etc/sudoers.d目录中创建和删除文件,从而为用户和组配置sudo访问权限。
1.若要为用户yanjianjun启用完整的sudo访问权限,可创建含有以下内容的/etc/sudoers.d/yanjianjun
yanjianjun ALL=(ALL) ALL
2.若要为组group01启用完整的sudo访问权限,可创建含有以下内容的/etc/sudoers.d/group01
%group01 ALL=(ALL) ALL
3.此外,也可以设置sudo,以允许用户在不输入密码的前提下以其他用户身份运行命令
ansible ALL=(ALL) NOPASSWD:ALL
授予用户或组此级别访问权限存在明显的安全风险,非特定场景,不建议使用。
6.3 管理本地用户账户
6.3.1 从命令行创建用户
- useradd username命令将创建一个名为username的新用户。同时会设置用户的主目录和账户信息,并为username用户创建一个同名的组。默认情况下,主目录是/home/username目录。在账户未设置密码前,用户无法登录。
- useradd --help命令显示基本的参数,在大多数场景下,这些参数同样适用于usermod命令。usermod命令用来修改用户的属性。
- 一些默认值从/etc/login.defs文件中获取,如有效的UID编号和默认密码过期规则。此文件中的值仅在创建新用户时使用。更改此文件对现有用户毫无影响。
6.3.2 从命令行修改现有用户属性
usermod --help的选项
选项 | 用法 |
---|---|
-g,–gid GROUP | 为用户指定主要组,指定的组名必须是系统中存在的组 |
-G,–groups GROUPS | 为用户指定补充组,以逗号分隔 |
-a,–append | 利用-G选项将补充组添加到用户当前的组成员集合,而不是将当前补充组集合替换为新的集合 |
-d,–home HOME_DIR | 为用户账户指定特定的主目录 |
-m,–move-home | 将用户主目录移到新的位置,必须与-d选项配合使用。 |
-s,–shell SHELL | 为用户指定特定的登录shell |
-L,–lock | 锁定用户账户 |
-U,–unlock | 解锁用户账户 |
6.3.3 从命令行删除账户
- userdel username命令从/etc/passwd中删除username的详细信息,但保留用户的主目录不变。
- userdel -r username命令从/etc/passwd中删除username的详细信息,同时删除用户主目录。
警告:在红帽企业Linux7以上版本,useradd命令为新用户分配一个大于或等于1000的可用UID,除非通过-u选项明确指定。如果在未指定-r选项的情况下使用userdel删除某一用户,系统将残留未分配的UID所拥有的文件。或者当已删除用户拥有的文件在该用户的主目录之外,也会发生这种情况。这种情况将导致信息的泄露和其他的安全问题。
根据这一情况,解决方案是,在删除创建了文件的用户时,同时从系统中删除所有这些无人拥有的文件。root用户可以使用find / -nouser -o -nogroup命令来查找所有无人拥有的文件和目录。
6.3.4 从命令行设置密码
- passwd username命令可以为username设置初始密码,或者修改其吸纳有的密码
- root用户可以将任何用户的密码设为任何值,即使不符合密码标准,也能设置成功。
- 默认配置下,普通用户必须选择长度至少为8个字符,并且不以字典词语、用户名或上一密码为基础的密码。
6.3.5 UID范围
- UID 0 超级用户root
- UID 1-200 系统用户,由红帽分配给系统进程
- UID 201-999 系统用户,供文件系统中没有自己的文件的系统进程使用。通常在安装需要他们的软件时,从可用池中动态分配它们。
- UID 1000+ 是可供分配给普通用户的范围。
6.3 管理本地组账户
组必须存在后,用户才能添加到其中。
6.3.1 从命令行创建组
- groupadd命令用于创建组。默认情况,groupadd命令会在创建组时使用**/etc/login.defs**文件中指定范围内的下一个可用GID。
- -g选项指定特定的GID
- -r使用/etc/login.defs文件中所列的有效系统GID范围内的GID创建系统组,/etc/login.defs中的SYS_GID_MIN和SYS_GID_MAX配置项定义系统GID的范围。
6.3.2 从命令行修改现有的组
- groupmod命令修改现有组的属性
- -n选项重命名组
- -g选项更改组的GID
6.3.3 删除组
- groupdel命令删除组
**注意:**如果组是任何现有用户的主要组,则您无法删除它。与userdel一样,请检查所有文件系统,确保系统上不遗留该组拥有的任何文件。
6.3.4 从命令行更改组成员资格
- 组成员资格通过用户管理控制,使用usermod -g名更改用户的主要组。
[root@ansible project]# id user02
uid=1002(user02) gid=1002(user02) groups=1002(user02)
[root@ansible project]# usermod -g group01 user02
[root@ansible project]# id user02
uid=1002(user02) gid=1003(group01) groups=1003(group01)
[root@ansible project]#
- usermod -aG命令,将用户添加到某一补充组
[root@ansible project]# id user03
uid=1003(user03) gid=1004(user03) groups=1004(user03)
[root@ansible project]# usermod -aG group01 user03
[root@ansible project]# id user03
uid=1003(user03) gid=1004(user03) groups=1004(user03),1003(group01)
[root@ansible project]# groupadd group02
[root@ansible project]# usermod -G group02 user03
[root@ansible project]# id user03
uid=1003(user03) gid=1004(user03) groups=1004(user03),1005(group02)
[root@ansible project]#
使用-a选项使usermod函数处于append模式,如果未增加-a,就会从用户当前的其他补充组中删除该用户,之后再增加到新的补充组。
6.4 管理用户密码
密码文件/etc/shadow,与/etc/passwd文件格式类似。以九个冒号分隔字段。
yanjianjun:6 66Qi7ozxMh.$sWahbub17MBq7YBQSXQnM.y757qBiQ.UhJLpjZC0tTzbzLSyw9o6/HjqbQPEKJJCrkZR60.m4CVY8.WATo54E.:18456:0:99999:7:::
- 用户名
- 用户的加密密码
- 上次更改密码的日期,其设置值为自1970年1月1日起的天数,按UTC时区计算。
- 自用户上次更改密码以来到可以再次更改之前必须经过的最短天数
- 密码过期时间,默认9999为永不过期
- 警告期,密码过期前提前几天开始警告。
- 非活动期,一旦密码过期,在这些天内仍可以接受扽古,过了这一时期,账户将被锁定。
- 密码过期日,其设置值为自1970年1月1日起的天数,按UTC时区计算。孔子段表示它不会在特定的日期失效。
- 最后一个字段为预留字段,预留给未来使用。
1970年1月1日起,计算天数的方法
[root@ansible project]# date -u -d "1970-01-01 UTC $((18644 * 86400 )) seconds"
Sun Jan 17 00:00:00 UTC 2021
[root@ansible project]# date -u -d "1970-01-01 18644 days"
Sun Jan 17 00:00:00 UTC 2021
6.4.1 加密密码的格式
**6 66Qi7ozxMh.s W a h b u b 17 M B q 7 Y B Q S X Q n M . y 757 q B i Q . U h J L p j Z C 0 t T z b z L S y w 9 o 6 / H j q b Q P E K J J C r k Z R 60. m 4 C V Y 8. W A T o 54 E . ∗ ∗ 加 密 密 码 字 段 中 存 储 了 三 段 信 息 : 哈 希 算 法 、 s a l t 及 加 密 哈 希 值 , 每 段 信 息 由 sWahbub17MBq7YBQSXQnM.y757qBiQ.UhJLpjZC0tTzbzLSyw9o6/HjqbQPEKJJCrkZR60.m4CVY8.WATo54E.** 加密密码字段中存储了三段信息:哈希算法、salt及加密哈希值,每段信息由sWahbub17MBq7YBQSXQnM.y757qBiQ.UhJLpjZC0tTzbzLSyw9o6/HjqbQPEKJJCrkZR60.m4CVY8.WATo54E.∗∗加密密码字段中存储了三段信息:哈希算法、salt及加密哈希值,每段信息由符号分隔。
- 此密码采用哈希算法,数字6表示SHA-512哈希算法,1表示MD5哈希算法,5表示SHA-256哈希算法。
- 用于加密密码的salt
- 用户密码的加密哈希值,salt和未加密密码组合并加密,生成加密的密码哈希。
**使用salt可以防止两个密码相同的用户在/etc/shadow文件中拥有相同的条目。即使两个用户的密码相同,salt不同的情况下,/etc/shadow中的加密密码也是不同的。
6.4.2 密码验证
用户尝试登录时,系统在/etc/shadow中查询用户条目,将用户的salt和键入的未加密密码组合,再使用指定的哈希算法加密。如果结果与已加密哈希匹配,则用户键入了正确的密码。如果结果与已加密密码不符,则用户键入了错误的密码,登录尝试也会失败。
6.4.3 配置密码期限
密码期限可用通过change命令进行调整来试试密码期限策略。
前面的chage命令使用了-m,-M,-W和-I选项,它们分别用于设置用户密码的最短期限、最长期限、警告周期和失效期限。
- chage -d 0 user03 命令强制user03用户在下一次登录时更新其密码(用法同passwd -e user03)
- chage -l user03命令显示user03的密码期限详情
- chage -E 2019-08-05 user03命令使user03用户的账户于2019-08-05到期(YYYY-MM-DD格式)
注意:date命令可用于计算未来的日期,-u选项报告UTC时间。
[user01@host ~]$ date -d “+45 days” -u
Thu May 23 17:01:20 UTC 2019
编辑/etc/login.defs文件中的密码期限配置项,以设置默认的密码期限策略。PASS_MAX_DAYS设置密码的默认最长期限,PASS_MIN_DAYS设置密码的默认最短期限。PASS_WARN_AGE设置密码的默认警告周期。默认密码期限策略的任何更改都仅对新用户有效。现有用户将继续使用旧密码期限设置,而非新密码设置。
6.4.4 限制访问
chage命令可以用来设置账户到期日期,到了设定的日期,用户将无法以交互方式登录系统。usermod命令可以通过-L选项锁定账户。
[root@ansible project]# usermod -L yanjianjun
[root@ansible project]# su - student
Last login: Mon Jan 11 22:03:20 CST 2021 on pts/0
[student@ansible ~]$ su - yanjianjun
Password:
su: Authentication failure
使用场景1:用户离开公司,管理员可以通过usermod命令锁定账户并使其到期。该日期必须使用距离1970-01-01的天数来指定,或者以YYYY-MM-DD格式来指定。
[root@ansible project]# usermod -L -e 2019-10-05 user03
-e用来设置账户的到期日期,-L锁定用户的密码。如果以后员工返回,其账户通过usermod -U解锁。如果账户已到期,务必也要修改到期日期。
6.4.5 nologin Shell
nologinshell用作不打算以交互方式登录系统的用户账户的替代shell。从安全角度来看,如果用户账户担当的职责不需要用户以交互方式登录系统,则禁止用户账户登录系统是明智的。这种情况的解决方案是将用户的登录shell设为/sbin/nologin。如果用户试图直接登录系统,nologinshell将关闭该连接
[root@ansible project]# usermod -s /sbin/nologin yanjianjun
[root@ansible project]# su - yanjianjun
Last login: Sun Jan 17 18:16:57 CST 2021 on pts/0
Last failed login: Sun Jan 17 18:17:32 CST 2021 on pts/0
There were 2 failed login attempts since the last successful login.
This account is currently not available.
[root@ansible project]#
重要:nologin可以防止以交互方式使用系统,但不会阻止所有访问。例如ftp等应用的访问。
总结
在本章中,你学到了:
- 用户账户有三种主要类型:超级用户、系统用户和普通用户
- 用户必须有主要组,并且同时可以属于多个补充组成员
- 包含用户和组信息的三个关键文件/etc/passwd,/etc/group和/etc/shadow
- su和sudo命令可用于以超级用户身份运行命令
- useradd、usermod和userdel命令来管理用户
- groupadd、groupmod、groupdel命令来管理组
- chage命令可用于配置和查看用户的密码期限