管理本地用户和组

什么是用户?

​ 用户账户在可以运行命令的不同人员和程序之间提供安全界限。

​ 用户使用用户名想人类用户标识自己并加强操作的便利性。在内部,系统通过分配的唯一标识号(用户ID或UID)来区分不同的用户账户。在大多数情况下,如果有人使用用户账号,则系统会位改用户分配一个机密密码,以证明他们是登录的授权用户。

​ 用户账户构成了系统安全的基础。系统中的每个进程(运行的程序)都作为一个特定用户运行。每个文件都有一个特定用户作为其所有者。借助文件所有权,系统可以对文件的用户实施访问控制。与运行进程相关联的用户可确定该进程可访问的文件和目录。

​ 用户账户有以下三种主要类型:超级用户、系统用户和普通用户。

  • 超级用户账户负责管理系统。超级用户的名称为root,其账户的UID为0.超级用户具有完全的系统访问权限。
  • 系统用户账户提供支持服务进程使用。这些进程(或守护进程)通常不需要以超级用户身份运行。系统会为它们分配非特权账户,确保其文件和其他资源不受彼此以及系统上普通用户的影响。用户无法使用系统用户账户以交互式登录。
  • 大多数用户都有用于日常工作的普通用户账户。与系统用户一样,普通用户对系统具有有限的访问权限。

​ 使用id命令可显示有关当前已登录用户的信息。

1
2
3
4
[kiosk@foundation0 ~]$ id
uid=1000(kiosk) gid=1000(kiosk) groups=1000(kiosk),982(libvirt) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[kiosk@foundation0 ~]$

​ 要查看有关其他用户的基本信息,请将用户作为参数传递给id命令:

1
2
3
[kiosk@foundation0 home]$ id redhat01 
uid=1001(redhat01) gid=1001(redhat01) groups=1001(redhat01)
[kiosk@foundation0 home]$

​ 使用ls -l命令可查看文件的所有者。使用ls -ld命令可查看目录的所有者,而不是该目录的内容。在以下出书中,第三列显示所有者的用户名。

1
2
3
4
5
[kiosk@foundation0 ~]$ ls -l test1.txt 
-rw-r--r--. 1 kiosk kiosk 1 Mar 6 16:46 test1.txt
[kiosk@foundation0 ~]$ ls -ld Music/
drwxr-xr-x. 2 kiosk kiosk 6 Feb 1 2023 Music/
[kiosk@foundation0 ~]$

​ 使用ps命令可查看进程信息。默认为仅显示当前shell中的进程。使用ps命令-a选项可查看与某一终端相关的所有进程。使用ps命令-u选项可查看与进程关联的用户。在以下输出中,第一列显示用户名。

1
2
3
4
5
6
7
8
[kiosk@foundation0 ~]$ ps -au
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
kiosk 2342 0.0 0.0 374120 5872 tty2 Ssl+ 14:28 0:00 /usr/libexec/gdm-wayland-session --register-s
kiosk 2352 0.0 0.1 521392 19632 tty2 Sl+ 14:28 0:00 /usr/libexec/gnome-session-binary
kiosk 3200 0.0 0.0 224212 5800 pts/0 Ss+ 14:29 0:00 bash
kiosk 4447 0.0 0.0 224228 5768 pts/6 Ss 14:35 0:00 -bash
kiosk 4918 1.5 0.0 224096 5556 pts/7 Ss+ 15:13 0:00 -bash
kiosk 4952 0.0 0.0 225500 3648 pts/6 R+ 15:13 0:00 ps -au

​ 以上命令输出按名称显示用户名,但操作系统内部利用UID来跟踪用户。用户名到UID的映射在账户信息数据库中定义。默认情况下,系统使用/etc/passwd文件存储有关本地用户的信息。

​ /etc/passwd文件的每一行都包含了有关某个用户的信息。该文件划分为7个以上的冒号分割的字段。以下是来自/etc/passwd行的示例。

1
2
[kiosk@foundation0 ~]$ cat /etc/passwd
redhat01:x:1001:1001:User One:/home/redhat01:/bin/bash

​ 代码块的每个部分,用冒号分割

  • redhat01:此为用户的用户名
  • x:用户的加密密码历来存储在这里;但在此是一个占位符。
  • 1001:此用户账户的UID编号
  • 1001:此用户账户的主要组的GID编号。本章节稍后将对组进行讨论
  • User One:此用户的简短注释、描述或真实姓名等。
  • /home/redhat01:用户的主目录,以及登录shell启动时的初始工作目录。
  • /bin/bash:此用户的默认shell程序,在登陆时运行,一些账户使用/sbin/nologin shell来禁止该用户使用交互式登录。

什么是组

​ 组是需要共享文件和其他系统资源访问权限的用户集合。组可用于向一组用户授予文件访问权限,而非向一个用户授予访问权限。

​ 与用户一样,组也具有组名以便识别。在内部,系统通过分配的唯一标识号(组ID或GID)来区分不同的组。组名到GID映射在组账户信息身份管理数据库中定义。默认情况下,系统使用/etc/group文件存储有关本地组的信息。

​ /etc/group文件的每行都包含了有关某个组的信息。每个组条目被分为四个以冒号分割的字段。以下来自/etc/group行的示例:

1
2
...忽略...
redhat01:x:1001:user01,user02

​ 考虑代码块的每个部分用冒号分割:

  • redhat01:此组的名称
  • x:以前的组密码字段;现在是一个占位符。
  • 1001:此组的GID编号。
  • user01,user02:属于此组成员的用户列表,作为一个补充组。

主要组和补充组

​ 每一个用户有且只有一个主要组。对于本地用户而言,这个组按照GID列在/etc/passwd文件中。主要组拥有用户创建的文件。

​ 在创建普通用户时,会创建一个与用户名同名的组,作为该用户的主要组。该用户是这个私有组的唯一成员。这种组成员资格设计简化了文件权限的管理,默认为区隔不同的用户组。

​ 用户还可以拥有多个补充组。补充组中的成员资格存储在/etc/group文件中。根据所在组身份具有访问权限,将授予用户对文件的访问权限,不论这些组是主要组还是补充组。例如,如果user01用户有一个主要组user01以下两个补充组wheel和webadmin,那么该用户就可以读取这三个组中任何一个组,有权读取的文件。

​ id命令可以显示用户的组成员资格。在以下示例中,kiosk用户具有组kiosk作为自己的主要组(gid)。groups项列出此用户的所以组成员资格,而且用户还具有libvirt组作为补充组。

1
2
[kiosk@foundation0 ~]$ id
uid=1000(kiosk) gid=1000(kiosk) groups=1000(kiosk),982(libvirt) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

获取超级用户访问权限

超级用户

​ 大多数操作系统具有一个超级用户,该用户拥有系统的全部权限。在红帽Linux中,此为root用户。此用户的特权高于文件系统上的一般特权,您可以使用它来管理系统。若要执行诸如安装或删除软件以及管理系统文件和目录任务,必须将特权升级到root用户。

​ 通常,普通用户中只有root用户才能控制大部分设备,但也有一些例外。例如,普通用户可以控制可移动设备,如USB设备。因此,虽然普通用户可以添加和删除文件并可管理可移动的设备,但默认情况下,只有root用户才能管理硬盘。

​ 尽管如此,这种无限制的特权也带来了职责问题。root用户拥有足以破坏系统的无限制特权:删除文件和目录、删除用户账户,以及添加后门等。一旦root用户账户被盗,系统将处于危险之中,您也可能会失去管理控制。红帽建议系统管理员始终以普通用户身份登录,仅在需要时升级到root用户特权。

​ Linux上root账户大致相当于Windows上的本地Admininstrator账户。在Linux中,大多数系统管理员都作为无特权的用户登录,然后使用特种工具临时获得root特权。

警告:Windows用户可能熟悉以本地Administrator用户身份登录以执行系统管理员职责的做法。如今不建议这样做,用户通过Administrator组中的成员资格来获取执行管理的特权。RHEL中同样如此,红帽建议系统管理员不要直接以root身份登录。取而代之,系统管理员以普通用户身份登录,然后使用其他机制(例如:su、sudo或policykit)临时获得超级用户特权。

切换用户账户

​ 通过使用su命令,用户可以切换至另一个用户账户。如果从普通用户账户运行su命令并将另一用户账户作为参数,则必须提供要切换到的用户账户密码。以root用户身份运行su时,则无需输入用户密码。

​ 本示例从kiosk账户运行su命令来切换到redhat01账户:

1
2
3
4
5
[kiosk@foundation0 ~]$ su redhat01
Password: # redhat01的密码
[redhat01@foundation0 kiosk]$ id
uid=1001(redhat01) gid=1001(redhat01) groups=1001(redhat01) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[redhat01@foundation0 kiosk]$

​ 如果省略用户名作为su命令的参数,则默认情况下su 或 su - 命令会尝试切换到root。

1
2
3
4
5
6
[redhat01@foundation0 kiosk]$ su -
Password:
Last login: Thu Apr 3 18:01:23 CST 2025 on pts/6
[root@foundation0 ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[root@foundation0 ~]#

​ 命令su将启动非登录shell,而命令su - (带有短划线选项)会启动登录shell。两个命令的主要区别在于,su - 会将shell环境变量设置为如同该用户身份重新登录一样,而su以该用户身份启动shell,但使用的是原始用户环境变量设置。

注意:su命令最常用于获得另一个用户身份(通常root)运行的命令行界面(shell提示符)。但是,您还可以通过su命令结合-c选项,以另一个用户身份运行任意程序。具体su命令更多选项可通过man su(1)查看

通过sudo运行命令

​ 出于安全原因,在某些情况下,系统管理员会将root用户配置为没有有限的密码。因此,用户无法使用密码直接以root身份登录系统。此外,您也无法使用su来获取交互式shell。在这种情况下,您可以使用sudo命令来获取root访问权限。

​ 与su命令不同,sudo通常要求用户输入自己的密码以进行身份验证,而不是输入他们正尝试访问的用户账户的密码。也就是说,用户使用sudo命令以root身份运行命令时,是不需要知道root密码。相反,他们将使用自己的密码来验证访问权限。

​ 下表总结了su、su - 和sudo命令之间的区别:

su su - sudo
成为新用户 权限升级的命令
环境 新用户的 新用户的 当前用户的
需要密码 新用户的 新用户的 当前用户的
特权 与新用户相同 与新用户相同 有配置定义
记录的活动 仅su命令 仅su命令 权限升级的命令

​ 此外,您可以将sudo配置为允许特定用户像某个其他用户一样运行任何命令,或仅允许以该用户是否允许部分命令。例如,如果您将sudo命令配置为允许redhat01用户以root身份允许usermod命令,那么您可以允许一下命令来锁定或解锁用户账户:

1
2
3
4
5
6
[kiosk@foundation0 home]$ sudo usermod -L redhat01 
[sudo] password for kiosk:
[kiosk@foundation0 home]$ su - redhat01
Password:
su: Authentication failure
[kiosk@foundation0 home]$

​ 如果某用户尝试以另一用户身份允许命令,但sudo配置不允许,则bash会阻止该命令,记录这次尝试,并向root发送一封邮件。

1
2
[root@foundation0 ~]# tail -f /var/log/secure
Apr 17 15:53:04 foundation0 su[2569]: pam_unix(su-l:auth): authentication failure; logname=kiosk uid=1000 euid=0 tty=/dev/pts/0 ruser=kiosk rhost= user=redhat01

​ sudo的另一个好处是默认将所有执行的命令记录到/var/log/secure中。

1
2
[root@foundation0 ~]# tail -f /var/log/secure
Apr 17 15:50:06 foundation0 sudo[2373]: kiosk : command not allowed ; TTY=pts/0 ; PWD=/home ; USER=root ; COMMAND=/sbin/usermod -L redhat01

​ 在红帽Linux中,wheel组所有成员都可以使用自己的密码通过sudo以任何用户身份允许命令,包括root在内

通过Sudo获取交互式Root Shell

​ 要通过sudo访问root账户,请使用sudo -i命令。此命令将切换root账户并运行该用户的默认shell及关联的交互式登录脚本。要在没有交互式脚本的情况下运行shell,请使用sudo -s命令。

​ 例如,管理员可以获取kiosk实例上root用户的交互式shell,方法是使用SSH公钥身份验证作为普通用户kiosk登录,在运行sudo -i命令获取root用户的shell。

1
2
3
[kiosk@foundation0 home]$ sudo -i
[sudo] password for kiosk:
[root@foundation0 ~]#

配置Sudo

​ /etc/sudoers文件是sudo命令的主要配置文件。如果多个管理员试图编辑该文件,为了避免出现问题,您只能特殊的visudo命令进行编辑。visudo编辑器也会验证该文件,确保没有语法错误。

​ 例如,以下来自/etc/sudoers文件的这一行可为wheel组成员启用sudo访问权限:

1
%wheel  ALL=(ALL)       ALL
  • %wheel字符串是规则所应用到的用户或组。词语wheel前的%符号指定该是对一个组进行权限的设置。
  • ALL=(ALL:ALL)命令指定在具有此文件的任何主机上(第一个ALL),wheel组中的用户可以在系统上以任何其他用户(第二个ALL)和任何其他组(第三个ALL)运行命令。
  • 最后的ALL命令指定wheel组中的用户可以运行任何命令。

​ 默认情况下,/etc/sudoers文件还包含/etc/sudoers.d目录中所有文件的内容,作为配置文件的一部分。通过使用这种层次结构,您只需将相应的文件放入该目录中,即可为用户添加sudo访问权限。

注意:将配置文件放在/etc/sudoers.d目录下比较方便。将文件复制到目录中或从目录中删除文件,即可启用或禁用sudo访问权限。通常每个文件都会以用户或组来进行命名,当要启用或是禁用时,只需将文件在该目录中复制或删除即可。避免一个文件长篇大论,难以维护

​ 要为redhat01用户启用完整的sudo访问权限,您可以创建含有以下内容的/etc/sudoers.d/redhat01文件:

1
2
[root@foundation0 ~]# cat /etc/sudoers.d/redhat01 
redhat01 ALL=(ALL) ALL

​ 要为group01组启用完整的sudo访问权限,您可以创建含有以下内容的/etc/sudoers.d/group01文件:

1
2
[root@foundation0 ~]# cat /etc/sudoers.d/group01
%group01 ALL=(ALL) ALL

​ 要使games组中的用户能够以operator用户身份运行id命令,您可以创建含有以下内容的/etc/sudoers.d/games文件:

1
2
[root@foundation0 ~]# cat /etc/sudoers.d/games
%games ALL=(operator) /bin/id

​ 此外,也可以设置sudo,以允许用户通过使用NOPASSWD:ALL命令在不输入密码的前提下以其他用户身份允许命令:

1
2
[root@foundation0 ~]# cat /etc/sudoers.d/ansible
%ansible ALL=(ALL) NOPASSWD:ALL

​ 虽然授权用户或组这种级别的访问权限存在明显的安全风险,但系统会将这种做法用于云实例、虚拟机和调配系统,以配置服务器。您必须谨慎地保护具有此访问权限的账户,并且要求使用SSH公钥身份验证,以便远程系统上的用户能访问它。

管理本地用户账户

从命令行创建用户

​ useradd username命令可以创建名为username的用户。它会设置用户的主目录和账户信息,并为名为username的用户创建一个私有组。此时,该账户尚未设置有效密码,用户也要设置了密码后才能登录。

​ useradd –help 命令将显示可用于覆盖默认设置的基本选项。大多数情形中,您可以将相同的选项用于usermod命令,以修改现有用户。

​ 在红帽linux9中,useradd命令为新用户分配的第一个大于或等于1000的可用UID,除非您通过-u选项进行明确指定。

从命令行修改现有的用户

​ usermod –help命令显示用于修改账户的基本选项。一些常见的选项如下:

usermod选项 用法
-a,–append 与-G选项一起使用,将补充组添加到用户当前的组成员集合中,而不是将补充组集合替换为新的集合。
-c,–comment COMMENT 将COMMENT文本添加到注释字段。
-d,–home HOME_DIR 为用户账户指定一个主目录。
-g, –gid GROUP 为用户账户指定主要组。
-G,–groups GROUPS 为用户账户指定补充组,多个补充组用逗号分割列表。
-L, –lock 锁定用户账户。
-m,–move-home 将用户的主目录移送到新的位置。您必须将它于-d选项搭配使用。
-s,–shell SHELL 为用户账户指定特定的登录shell。
-U,–unlock 解锁用户账户。

从命令行删除用户

​ userdel username 命令从/etc/passwd中删除用户的详细信息,但用户的主目录保持不变。userdel -r username 命令从/etc/passwd 中删除用户,同时删除用户的主目录。

警告:如果您在不指定userdel -r 选项的情况下删除用户,则用户的文件归为未分配的UID所有。如果您创建了一个用户,并且该用户被分配了已删除用户的UID,则新账户将用有这些文件,这存在安全风险。通常,组织安全策略不允许删除用户账户,而是锁定它们不被使用,以避免这种情况。

​ 以下示例演示了这如何导致信息泄露:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@foundation0 kiosk]# useradd user01
[root@foundation0 ~]# ls -l /home/
total 1
drwx------. 3 user01 user01 78 May 13 10:57 user01
# 删除用户
[root@foundation0 ~]# userdel user01
# 为加-r选项,此时用户的主目录处于未分配状态,他之前所属用户UID为:1002
[root@foundation0 ~]# ls -l /home/
total 1
drwx------. 3 1002 1002 78 May 13 10:57 user01
# 创建用户,-u 指定该用户的UID为:1002
[root@foundation0 ~]# useradd -u 1002 user02
# 由于于之前的user01的UID一致,user01的主目录则自动归属为user02
[root@foundation0 ~]# ls -l /home/
total 2
drwx------. 3 user02 user02 78 May 13 10:57 user01
drwx------. 3 user02 user02 78 May 13 11:02 user02

请注意,user02现在拥有之前归为user01所属的所有文件。root用户可以使用find / -nouser -o -nogroup 命令来查找无人拥有的文件和目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@foundation0 ~]# userdel user02 
[root@foundation0 ~]# ls -l /home/
total 2
drwx------. 3 1002 1002 78 May 13 10:57 user01
drwx------. 3 1002 1002 78 May 13 11:02 user02
# nouser表示没有归属用户的条件,nogroup表示没有归属用户的组,-o选项表示【或】的意思,用于多个条件的拼接
[root@foundation0 ~]# find / -nouser -o -nogroup
...忽略...
/home/user01/.mozilla
/home/user01/.mozilla/extensions
/home/user01/.mozilla/plugins
/home/user01/.bash_logout
/home/user01/.bash_profile
/home/user01/.bashrc
/home/user02
....忽略....

从命令行设置密码

​ passwd username 命令可为username用户设置初始密码,或更改其现有密码。root用户可以将密码设置为任何值。如果密码不符合最低建议标准,终端会显示消息;不顾哦,之后您可以重新键入该新密码,passwd也会成功更新该密码。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 创建用户
[root@foundation0 ~]# useradd -u 1002 user01
useradd: warning: the home directory /home/user01 already exists.
useradd: Not copying any file from skel directory into it.
Creating mailbox file: File exists
# 为用户设置初始密码,密码:123456,虽会提示密码过于简单,未通过字典检查,但再次确认密码后任然可以成功设置。
[root@foundation0 home]# passwd user01
Changing password for user user01.
New password:
BAD PASSWORD: The password fails the dictionary check - it is too simplistic/systematic
Retype new password:
passwd: all authentication tokens updated successfully.
[root@foundation0 home]#

建议普通用户必须选择至少八个字符长的密码。不要使用字典词语、用户名或旧密码。

UID范围

  • UID 0:超级用户(root)账户UID。
  • UID 1-200:静态分配给系统进程的系统账户UID。
  • UID 201-999:分配给不拥有此系统上文件的系统进程的UID。需要非特权UID的软件将从这个可用池中动态分配UID。
  • UID 1000+:分配给普通非特权用户的UID范围。

注意:RedHat6及更早的版本对系统用户使用的范围1-499的UID,对普通用户使用高于500的UID。您可以在/etc/login.defs文件中更改useradd和groupadd默认范围。

image-20250513112428467

管理本地组账户

从命令行创建组

​ groupadd命令用于创建组。不带选项时,groupadd命令会使用/etc/login.defs文件中通过GID_MIN和GID_MAX 变量指定的范围内的下一个可用GID。默认情况下,该命令分配的GID值大于任何其他现有的GID,即使有较低的值可用。

​ groupadd 命令 -g选项指定该组使用的特定GID。

1
2
3
4
[root@foundation0 ~]# groupadd -g 10000 group1
[root@foundation0 ~]# tail /etc/group
....忽略...
group1:x:10000:

注意:由于创建用户时会自动为该用户生成一个私有组(GID 1000+),一些管理员会留出了一个单独的GID范围,用于创建补充组来满足其目的。但是,这种额外的管理是不必要的,因为用户的UID和主要组GID是不需要是相同的数字。

​ groupadd 命令 -r 选项用于创建系统组。与普通一样,系统组使用/etc/login.defs文件中列出的有效系统GID范围内的GID。/etc/login.defs文件中的SYS_GID_MIN和SYS_GID_MAX配置项定义系统GID的范围。

1
2
3
4
[root@foundation0 ~]# tail /etc/group
...忽略...
group1:x:10000:
group2:x:976:

从命令行修改现有的组

​ groupmod 命令可以更改现有组的属性。groupmod命令-n选项可指定组的新名称。

1
2
3
4
5
6
[root@foundation0 ~]# groupmod -n group002 group2 
[root@foundation0 ~]# tail /etc/group
...忽略...
group1:x:10000:
group002:x:976:
[root@foundation0 ~]#

​ 注意组名称从group2更改为group002,groupmod命令-g选项可更改GID

1
2
3
4
5
[root@foundation0 ~]# groupmod -g 975 group002 
[root@foundation0 ~]# tail /etc/group
...忽略...
group1:x:10000:
group002:x:975:

​ 注意GID从原来的976变更为975.

从命令行删除组

​ groupdel 命令可删除组。

1
2
3
4
[root@foundation0 ~]# groupdel group002 
[root@foundation0 ~]# tail /etc/group
...忽略...
group1:x:10000:

注意:如果删除的组是现有用户的主要组,则您无法删除它。于使用userdel命令类似,首先检查以确保找到该组拥有的文件,避免信息泄露

从命令行更改组成员资格

​ 组成员资格通过用户管理进行控制。使用usermod -g命令来更改用户的主要组。

1
2
3
4
5
6
[root@foundation0 home]# id user01 
uid=1002(user01) gid=1002(user01) groups=1002(user01)
[root@foundation0 home]# usermod -g group01 user01
[root@foundation0 home]# id user01
uid=1002(user01) gid=10000(group1) groups=10000(group1)
[root@foundation0 home]#

​ 使用usermod -aG命令,将用户太你家到某一补充组。

1
2
3
4
5
[root@foundation0 home]# id user01 
uid=1002(user01) gid=10000(group1) groups=10000(group1)
[root@foundation0 home]# usermod -aG user01 user01
[root@foundation0 home]# id user01
uid=1002(user01) gid=10000(group1) groups=10000(group1),1002(user01)

重要:usermod命令的-a选项可启用附加模式。不带-a选项时,命令会从当前未包含在 -G 选项列表中的任何补充组从该用户中删除。

比较主要组和补充组成员资格

​ 用户的主要组是在/etc/passwd文件中查看的用户账户和组。一个用户一次只能属于一个主要组。

​ 用户的补充组是为用户配置的额外组,可在/etc/group文件中的用户条目中查看。一个用户可以属于任意数量的补充组,以有效实施文件访问和权限。

​ 对于配置基于组的文件权限而言,用户的主要组和补充组之间没有区别。如果用户所属的组被分配了特定文件的访问权限,则该用户有权访问这些文件。

​ 用户的主要组和补充组成员资格之间唯一的区别体现在用户创建文件时。新文件必须具有用户所有者和组所有者,这是在文件创建时分配的。用户的主要组用于新文件的组所有权,除非被选项命令覆盖。

临时更改您的主要组

​ 只有用户的主要组才会用于新文件创建属性。但是,您可以暂时将主要组切换到另一个组,但只能从您所属的补充组中去选择。如果您要手动或以脚本方式创建多个新文件,并希望创建时将不通的组分配为所有者,则可以切换组。

​ 在此shell会话中,使用newgrp命令来切换主要组。您可以在所属的任何主要组或补充组之间却换,但一次只能由一个组是主要组。如果您注销并重新登录,主要组将回复为默认值。此示例将user01用户中的补充组user01临时切换为主要组。

1
2
3
4
5
6
7
[user01@foundation0 ~]$ id
uid=1002(user01) gid=10000(group1) groups=10000(group1),1002(user01) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[user01@foundation0 ~]$ newgrp
group1 user01
[user01@foundation0 ~]$ newgrp user01
[user01@foundation0 ~]$ id
uid=1002(user01) gid=1002(user01) groups=1002(user01),10000(group1) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

管理用户密码

影子密码和密码策略

​ 加密的密码最初存储在全局可读的/etc/passwd文件中。这曾认为是最妥善的,直到对加密密码的字典式攻击变得常见。加密后的密码已移至/etc/shadow文件,只有root用户可以读取该文件。

​ 与/etc/passwd文件一样,每个用户在/etc/shadow文件中都有一个条目。/etc/shadow文件中的示例条目具有九个以冒号分割的字段:

1
redhat01:$6$N4i94UcIEydvTFzp$pf9W0C4I6w4BFxyK/ver6M7DVPnvupuGoYK/ZP24Y9ojBLN1/VYuJSucRtIDrICSSzhvmc31iUeXuBNnV3oBm0:20195:0:99999:7:::

​ 以此代码块为例,每个字段用冒号分割:

  • redhat01:用户账户名称。
  • $6$N4i94UcIEydv…省略:用户的加密密码,$6开头(SHA-512)加密。
  • 20195:上次更改密码时间距离纪元的天数;纪元是UTC时区的1970-01-01。
  • 0:自上次更改密码以来到用户可再次更改密码之前必须经过的最短天数。
  • 99999:在密码过期之前不进行密码更改的最长天数。空字段表示密码永不过期,自最后一次修改密码截至多少天过期。
  • 7:在密码过期前提前多少天警告用户。
  • 空:自密码过期之日起,在账户自动锁定前能够活动的天数,宽限天数。
  • 空:密码到期之日距离纪元的天数。空字段表示密码永不过期,密码过期天数。
  • 空:保留字段,预留给未来使用。

加密密码的格式

​ 加密密码字段中存储了三段信息:所用的哈希算法、salt及加密哈希值。每段信息由美元符号($)字符分割。

1
$6$N4i94UcIEydvTFzp$pf9W0C4I6w4BFxyK/ver6M7DVPnvupuGoYK/ZP24Y9ojBLN1/VYuJSucRtIDrICSSzhvmc31iUeXuBNnV3oBm0
  • $6:此密码所使用的哈希算法。6表示SHA-512,这是RedHat默认算法;1表示MD5,而5则表示SHA-256。
  • $N4i94UcIEydvTFzp:用于加密密码的salt;最初是随机选择的。
  • $pf9W0C4I6w4BFxyK/ver…忽略:用户密码的加密后的哈希;将salt和未加密密码组合并加密,生成密码哈希。

​ 将salt与密码组合的主要原因是为了防止使用预先计算的密码哈希列表攻击。添加salt会改变生成的哈希值,使预先计算的列表毫无用处。如果攻击者获得了使用salt的/etc/shadow文件的副本,则它们需要通过暴力破解来猜测密码,这将花费更多的时间和精力。

密码验证

​ 用户尝试登录时,系统在/etc/shadow文件中查询用户的条目,将用户的salt和键入的未加密密码组合,在使用制定的哈希算法加密组合。如何加密组合后的结果与已加密的哈希匹配,则用户键入了正确的密码。如果结果与已加密的密码不符合,则用户键入了错误的密码,登录尝试也会失败。这种方式允许系统半段用户是否键入了正确的密码,同时又不以用于登录的密码形式来存储密码。

配置密码期限

​ 下图显示了相关的密码期限参数,可以通过chage命令对起调整实施密码期限策略。

image-20250520145616305

​ 以下示例演示使用chage命令修改redhat01用户的密码策略。该命令定义密码修改间隔最短期限(-m)为0天,密码最长有效期(-M)为90天,警告期(-W)7天,以及过期后宽限(-I)14天后自动过期为不活动状态。

1
2
3
4
5
6
7
8
9
[root@foundation0 ~]# chage -m 0 -M 90 -W 7 -I 14 redhat01
[root@foundation0 ~]# chage -l redhat01
Last password change : Apr 17, 2025
Password expires : Jul 16, 2025
Password inactive : Jul 30, 2025
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 90
Number of days of warning before password expires : 7

​ 假设您在RedHat上管理用户密码策略。user01用户是系统中的新用户,您要设置自定义密码期限策略。您希望将账户的到期之间设置为,即日起30天后到期,因此您可以使用以下命令。

1
2
3
4
5
6
7
[root@foundation0 ~]# date +%F
2025-05-20
[root@foundation0 ~]# date -d "+30 days" +%F
2025-06-19
[root@foundation0 ~]# chage -E $(date -d "+30 days" +%F) user01
[root@foundation0 ~]# chage -l user01 | grep "Account expires"
Account expires : Jun 19, 2025
  • 使用date命令获取当前时间,并通过+%F选项,调整date命令输出的日期格式。
  • 使用date命令的-d选项以及“+30 days”参数获取即日起30天后的日期,并转换日期格式。
  • 使用chage命令的-E选项,将获得的截至日期作为参数赋予该选项。
  • 使用chage命令的-l选项,并且通过grep命令筛选出命令输出结果中的“Account expires”行,最终查看user01用户的过期时间成功设置为30天后。

​ 几天后,您在/var/log/secure日志文件中发现user01用户有一个奇怪的行为。用户尝试使用sudo与其他用户的文件交互。您怀疑用户可能忘记关闭在另一台计算机上工作时打开的ssh会话。您希望user01用户在下次登录时更改密码,因此您可以使用以下命令。

1
2
3
4
5
6
7
8
9
[root@foundation0 ~]# chage -d 0 user01 
[root@foundation0 ~]# chage -l user01
Last password change : password must be changed
Password expires : password must be changed
Password inactive : password must be changed
Account expires : Jun 19, 2025
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7

​ 此时user01的密码策略中提示,用户必须修改密码的结果,下次用户登录时就必须要求修改密码了。

注意:date命令可以计算未来的时间。-u选项报告UTC时间。

1
2
[root@foundation0 ~]# date -d "+5 days" -u +%F
2025-05-25

​ 您可以在/etc/login.defs文件中更改默认密码期限配置。PASS_MAX_DAYS和PASS_MIN_DAYS选项分别设置密码的默认最长和最短期限。PASS_WARN_AGE设置密码的默认警告期限。默认密码期限策略中的任何更改都会影响更改后新创建的用户。现有用户继续使用就密码期限设置,而非新密码设置。

限制访问

​ 您可以使用usermod命令来修改用户的账户到期日期。例如,usermod命令-L选项可锁定用户账户,并且该用户无法登录系统。

1
2
3
4
[root@foundation0 ~]# usermod -L user03
[kiosk@foundation0 ~]$ su - user03
Password:
su: Authentication failure

​ 如果用户在特定日期从公司离职,您可以通过usermod命令锁定并使其到期。该日期必须是从1970-01-01的天开始算起,或者使用YYYY-MM-DD格式。以下示例中,usermod命令于2025-05-21锁定user03用户并使其过期。

1
2
3
4
5
6
7
8
9
[root@foundation0 ~]# usermod -L -e 2025-05-21 user03 
[root@foundation0 ~]# chage -l user03
Last password change : May 20, 2025
Password expires : never
Password inactive : never
Account expires : May 21, 2025
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7

​ 账户锁定后,您可以防止用户使用密码向系统进行验证。简易使用此方法防止前员工访问账户。使用usermod命令-U选项可以重新启用账户的访问权限。

非登录Shell

​ nologin shell用作不打算以交互方式登录系统的用户账户的代替shell。从安全角度来看,在账户不需要登录系统时,禁止账户登录系统是一个明智的选择。例如,邮件服务器可能需要账户来存储邮件,需要密码供用户通过检索邮件所用的邮件客户端进行身份验证。用户不需要直接登录该系统。

​ 这种情况的常用解决方案是将用户的登录shell设置为/sbin/nologin。如果用户试图直接登录系统,nologin shell将关闭该连接。

1
2
3
4
5
6
[root@foundation0 ~]# usermod -s /sbin/nologin user03 
[root@foundation0 ~]# su - user03
Last login: Tue May 20 14:49:37 CST 2025 on pts/0
Last failed login: Tue May 20 14:51:02 CST 2025 on pts/0
There were 4 failed login attempts since the last successful login.
This account is currently not available.

重要:nologin shell可以防止以交互式使用系统,但不会阻止访问。如果用户使用密码进行身份验证,它们有时可以通过身份验证,并使用web应用、文件传输程序或邮件读取程序等应用上传或检索文件。