1. 基础

Linux 是多用户多任务系统 , 用户(User) 和组(Group)是权限管理的基础。核心思路 : 每个进程都有属主 , 每个文件都有属主和属组 , 权限按"用户/组/其他"三元组判定。

用户(User)

每个用户有唯一标识 UID(User ID)

  • root : UID=0 , 超级管理员 , 最高权限

  • 系统用户(程序用户) : UID 1~999(CentOS7+/Ubuntu) , 给服务进程使用 , 一般不允许登录 , 如 nobody、nginx、www

  • 普通用户 : UID ≥1000 , 人为创建 , 日常登录使用

用户名只是名字 , 内核识别靠 UID。

用户组(Group)

每个组有唯一标识 GID(Group ID)

  • 主组(初始组 primary group ) : 用户创建文件时 , 文件默认所属组 , 一个用户只能有 1 个主组

  • 附加组(附属组 supplementary group) : 额外加入的组 , 一个用户可以有多个附加组 , 用来获取别的组的权限

作用 : 批量管理权限 , 不用逐个给用户授权。

  • UID 与 GID

    概念

    说明

    UID (User ID)

    用户数字标识 , 唯一

    GID (Group ID)

    组数字标识 , 唯一

    初始组(主组)

    用户创建时默认所属的组 , 记录在 /etc/passwd 第 4 字段

    附加组(附属组)

    用户可加入的额外组 , 记录在 /etc/group 第 4 字段

  • UID 范围约定

    范围

    类型

    0

    root , 超级用户

    1–999

    系统用户(CentOS/RHEL 传统) ; 100–999 是系统预留段(Debian/Ubuntu 中0-999)

    1000+

    普通用户(现代发行版约定从 1000 开始)

2. 配置文件

  • linux 用户和组的主要配置文件 :

    • /etc/passwd : 用户及其属性信息(名称 , UID , 主组ID等)

    • /etc/group :组及其属性信息

    • /etc/shadow :用户密码及其相关属性

    • /etc/gshadow : 组密码及其相关属性

注: 可以使用pwunconv这个命令使得/etc/shadow不再保存密码信息 , 密码直接保存至/etc/passwd中 。另外通过pwconv直接转换回来 , 将密码保存至/etc/shadow中

grpconv/prgunconv这两个命令主要用于组配置文件 , 将组密码在/etc/group以及/etc/gshadow文件保存位置转换

2.1 /etc/passwd

/etc/passwd 是 Linux 最古老、最核心的账号数据库 , 记录系统中所有用户的账号基本信息。它必须对所有用户可读——因为太多系统操作需要"用户名 ↔ UID"的转换(ls -l 显示属主、ps 显示进程属主、登录时验证用户名等) , 所以密码被挪到了 /etc/shadow, 这里只留一个 x 占位。

ls -l /etc/passwd
# -rw-r--r-- 1 root root 2456 ... /etc/passwd
  • 全系统可读(644) : 任何用户都能列出所有账号名——这本身就是信息泄露点(攻击者先知道有哪些账号可爆破) , 但对功能是必要的妥协

  • 只有 root 可写(修改必须root 或 SUID 工具)

一行代表一个用户 , 用:分隔 7 段

root:x:0:0:root:/root:/bin/bash

字段说明:

用户名:密码占位符x:UID:GID:注释信息:家目录:登录shell
  • x : 密码不存这里 , 只是占位符 , 密码存在 /etc/shadow

  • shell : /bin/bash可登录 ; /sbin/nologin禁止登录

chfn 修改用户的描述信息 同时可以用finger查看用户的描述信息 可以通过chsh修改用户shell类型 chsh -s /bin/sh wang 或者chmod -s /bin/bash wang

2.2 /etc/shadow

/etc/shadow 存储用户的加密密码和密码时效策略。它从 /etc/passwd 中分离出来的原因很简单 : passwd 必须对所有用户可读(用于用户名→UID 解析) , 如果密码哈希也放里面 , 任何人都能拷贝哈希去做离线字典爆破。shadow 只给 root(及shadow 组)读 , 把哈希保护起来。

ls -l /etc/shadow
# ---------- 1 root root 1284 ... /etc/shadow        # RHEL/CentOS 系 : 仅 root
# -rw-r----- 1 root shadow 1284 ... /etc/shadow      # Debian/Ubuntu 系 : shadow 组可读
  • 普通用户读不到哈希 , 但可以验证自己的密码(靠 /usr/bin/passwd 的 SUID root 机制)

  • root:shadow 权限是为了让需要读哈希的服务(如 sshd、cron) 以 shadow 组成员身份运行而不用给 root

该文件里面的内容显示如下,以冒号 : 分隔 , 一共 9 个字段

root:$6$0hxZM8hjuVAGtlJL$D95CSZawl8hRfw1niUFo5r4sIolskNYwjk6EcnszLULa0dkFS5kdKLrRcbrMrOs.GzckC6uZ/eHIijAzvWGfD/::0:99999:7:::
nfsnobody:!!:17785::::::
​
用户名:$6$salt$hash:最后一次改密时间:最小间隔:最大有效期:警告天数:不活动天数:过期日期:保留
8

序号

字段

说明

1

用户名

和 /etc/passwd 里的用户名一一对应

2

密码哈希

核心字段, 密码加密串

3

最后一次修改时间

从 1970-01-01 到上次改密码的天数

4

最小修改间隔

修改密码后, 至少要等多少天才能再次改密码。0 = 随时可改

5

最大修改间隔

密码有效期, 多少天后必须改密码, 默认 99999≈273 年

6

警告时间

密码到期前多少天, 登录提示你改密码

7

不活动时间

密码过期后, 还能保留多少天账号可用 ; 超时账号锁定

8

过期时间

账号整体过期时间 ( 从 1970 起天数 ) , 到期账号直接失效

9

保留

预留字段, 暂时没用, 一般为空

authconfig --passalgo=sha512 --update : 用这种方式更改密码的加密算法 , 在文件/etc/login.defs文件中同样定义了对应的加密模式

这里详细说明第 2 字段密码哈希

  • 格式:加密算法盐值$哈希结果

  • 加密算法标识

    • 1 : MD5 ( 老旧 , 不安全 )

    • 2a /2b : Blowfish (bcrypt)

    • 5 : SHA-256

    • 6 : SHA-512 Linux 默认 , 推荐

  • 特殊符号含义(密码字段)

    • !! 或者 * : 账号无密码 , 禁止登录 ( 系统账号如 daemon、nobody )

    • 空 : 没有密码 , 可以无密码直接登录 ( 高危 )

    • !$6$xxx : 账号被锁定 , passwd -l 用户 会在哈希前面加 !

盐 ( salt ) : 随机字符串 , 防止彩虹表破解 , 相同密码 , 不同盐 , 哈希不一样。

2.3 /etc/group

/etc/group 是 Linux/Unix 系统中存放用户组信息的核心配置文件 , 与 /etc/passwd、/etc/shadow 共同构成用户账户管理体系。所有用户(包括root)都可读取 , 但只有 root 可修改。

ls -l /etc/group
# 一般 : -rw-r--r-- 1 root root

全局可读 , 因为组信息不属于敏感密码信息。

文件中每行代表一个用户组 , 用冒号 : 分隔为 4 个字段 :

group_name:password:GID:user_list

序号

字段

说明

1

组名

用户组名称

2

密码占位符

x 表示组密码存放在 /etc/gshadow ; 为空代表无组密码

3

GID

组 ID , 0 是 root 组 ; 1~999 一般为系统内置组 , 普通用户组默认从 1000 开始

4

附属成员

多个用户用逗号分隔 ; 这里写的是附加组 , 不是用户的主组(主组关系记录在 /etc/passwd 的第 4 字段)

2.4 /etc/gshadow

/etc/gshadow 是 Linux 系统中存放用户组加密密码和组管理员信息的文件 , 可以理解为组版的 /etc/shadow。它是 /etc/group 的"影子文件" , 因为密码不能明文存放在任何人可读的 /etc/group 中 , 所以单独存放并限制权限。

ls -l /etc/gshadow
# 权限 : -rw------- 1 root root  # 600 , 仅root读写

文件中每行代表一个用户组 , 用冒号 : 分隔为 4 个字段

组名:组密码哈希:组管理员列表:组内附属成员列表

与 /etc/group 逐行对应(同一个组在这两个文件中各有一行)

字段

名称

说明

1

组名

与 /etc/group 中的组名一致

2

加密密码

加密后的组密码(sha512crypt6 等格式) , 或占位符

3

组管理员列表

有权管理该组的用户名列表(用逗号分隔) , 由 gpasswd -A 设置

4

组成员列表

与 /etc/group 第 4 字段完全相同的附加成员列表

第 2 字段(密码)的三种取值

值

含义

! 或空

该组没有设置密码 , 只有组成员可以通过 newgrp 切换

*

该组被锁定 , 禁止非成员切换进该组

6rounds=... 等

已设置加密密码 , 知道密码的任何用户可通过 newgrp 临时切换为该组

组密码的用途与机制

newgrp 命令 : 临时切换当前会话的有效主组。

# 场景 : developers 组密码已设置为 secret123
newgrp developers
# 提示输入组密码 , 输入正确后当前 shell 的有效 GID 变为 developers
  • 如果用户已经是该组成员 : 不需要密码 , 直接切换

  • 如果用户不是该组成员 : 必须输入组密码才能切换

vipw命令 : 直接编辑passwd文件 , 如果修改的文件格式不对 , 会有提醒。

vigr :(vim group)

直接使用vi修改了/etc/passwd 以及/etc/group

可以用pwck以及grpck检查文件中的语法格式是否正确

2.5 /etc/skel/

skel是skeleton的缩写 , 意为骨骼、框架。故此目录的作用是在建立新用户时 , 用于初始化用户根目录。创建新用户时 , 系统会把该目录下的所有文件和子目录自动复制到新用户的家目录中(如 /home/alice) ,作为初始环境配置。

  • 如果在新建用户时 , 没有自动建立用户根目录 , 则无法调用到此框架目录。

  • 如果不想以默认的/etc/skel目录作为框架目录 , 可以在运行useradd命令时指定新的框架目录。例如: sudo useradd -d /home/chen -m -k /etc/my_skel chen

  • 如果不想在每次新建用户时 , 都重新指定新的框架目录 , 可以通过修改/etc/default/useradd配置文件来改变默认的框架目录 , 方法如下 : 查找SKEL变量的定义 , 如果此变量的定义已被注释掉 , 可以取消注释 , 然后修改其值 : SKEL=/etc/my_skel。

2.6 /etc/login.defs

login.defs是设置用户帐号限制的文件 , 在这里我们可配置密码的最大过期天数 , 密码的最大长度约束等内容。该文件里的配置对root用户无效。如果/etc/shadow文件里有相同的选项 , 则以/etc/shadow里的设置为准 , 也就是说/etc/shadow的配置优先级高于/etc/login.defs。

/etc/login.defs 是 Linux 系统中 login、useradd、usermod、passwd、su 等用户管理命令的"全局默认配置中心"。它定义了创建用户时的默认参数、密码策略、UID/GID 范围等规则 , 属于用户账户管理的基础性配置文件。

[root@localhost ~]# cat /etc/login.defs 
#
# Please note that the parameters in this configuration file control the
# behavior of the tools from the shadow-utils component. None of these
# tools uses the PAM mechanism, and the utilities that use PAM (such as the
# passwd command) should therefore be configured elsewhere. Refer to
# /etc/pam.d/system-auth for more information.
#
​
# *REQUIRED*
#   Directory where mailboxes reside, _or_ name of file, relative to the
#   home directory.  If you _do_ define both, MAIL_DIR takes precedence.
#   QMAIL_DIR is for Qmail
#
#QMAIL_DIR  Maildir
#注 : 创建用户时 , 要在目录/var/spool/mail中创建一个用户mail文件 ; 
MAIL_DIR    /var/spool/mail
#MAIL_FILE  .mail
​
# Password aging controls:
#
#   PASS_MAX_DAYS   Maximum number of days a password may be used.
#   PASS_MIN_DAYS   Minimum number of days allowed between password changes.
#   PASS_MIN_LEN    Minimum acceptable password length.
#   PASS_WARN_AGE   Number of days warning given before a password expires.
#
#密码最大有效期
PASS_MAX_DAYS   99999
#两次修改密码的最小间隔时间
PASS_MIN_DAYS   0
#密码的最小长度,对root无效
PASS_MIN_LEN    5
#密码过期前多少天开始提示
PASS_WARN_AGE   7
​
#
# Min/max values for automatic uid selection in useradd
#
#普通用户的UID最小值
UID_MIN                  1000
#普通用户UID最大值
UID_MAX                 60000
# System accounts
#新创建系统用户UID最小值
SYS_UID_MIN               201
#新创建系统用户UID最大值
SYS_UID_MAX               999
​
#
# Min/max values for automatic gid selection in groupadd
#普通组GID最小值
GID_MIN                  1000
#普通组GID的最大值
GID_MAX                 60000
# System accounts
#系统组GID的最小值
SYS_GID_MIN               201
#系统组GID的最大值
SYS_GID_MAX               999
​
#
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#
#USERDEL_CMD    /usr/sbin/userdel_local
​
#
# If useradd should create home directories for users by default
# On RH systems, we do. This option is overridden with the -m flag on
# useradd command line.
#
#控制useradd添加用户时是否默认创建家目录 , useradd -m选项会覆盖此处设置
CREATE_HOME yes
​
# The permission mask is initialized to this value. If not specified, 
# the permission mask will be initialized to 022.
#设置创建家目录时的umask值 , 若不指定则默认为022
UMASK           077
​
# This enables userdel to remove user groups if no members exist.
# 设置此项表示当组中没有成员时自动删除该组
# 且useradd是否同时创建同用户名的主组。(该文件中并没有此项说明 , 来自于man useradd中-g选项的说明)
USERGROUPS_ENAB yes
​
# Use SHA512 to encrypt password.
#设置用户和组密码的默认加密算法
ENCRYPT_METHOD SHA512 
​

2.7 /etc/default/useradd

/etc/default/useradd 是 useradd 命令的专属默认配置文件。如果说 /etc/login.defs 是全局规则中心 , 那么本文件就是 useradd 的"个人偏好设置"——执行 useradd 时未显式指定的参数 ,都会从这里读取默认值

创建用户时的默认配置。useradd -D修改的就是此文件。

发行版 : RHEL/CentOS/Rocky 才有这个文件 ; Ubuntu 默认没有 , Ubuntu使用 /etc/default/adduser。

[root@localhost ~]# cat /etc/default/useradd  
# useradd defaults file
GROUP=100       # 在useradd使用-N或/etc/login.defs中USERGROUPS_ENAB=no时表示创建用户时不创建同用户名的主组(primary group) , 
                # 此时新建的用户将默认以此组为主组 , 网上关于该设置的很多说明都是错的 , 具体可看man useradd的-g选项或useradd -D的-g选项
HOME=/home      # 把用户的家目录建在/home中
INACTIVE=-1     # 是否启用帐号过期设置(是帐号过期不是密码过期) , -1表示不启用
EXPIRE=         # 帐号过期时间 , 不设置表示不启用
SHELL=/bin/bash # 新建用户默认的shell类型
SKEL=/etc/skel  # 指定骨架目录 , 前文的/etc/skel就在这里
CREATE_MAIL_SPOOL=yes  # 是否创建用户mail缓冲

示例:

修改默认值

# 修改默认 shell 为 zsh
sudo useradd -D -s /bin/zsh
​
# 修改家目录父路径为 /data/home
sudo useradd -D -b /data/home
​
# 设置账户默认 30 天过期
sudo useradd -D -e 30
​
# 设置密码过期后 7 天锁定账户
sudo useradd -D -f 7

3. 用户管理

3.1 useradd & adduser

useradd或 adduser)是 Linux 中用于创建新用户账户的基础命令。它在底层完成修改 /etc/passwd 、/etc/shadow 、/etc/group 、/etc/gshadow , 创建家目录并复制 /etc/skel 模板等一系列操作。

adduser是useradd的软链接命令

  • 语法 : useradd [options] LOGIN

  • OPTIONS

    • -u : UID

    • -o : 配合-u选项 , 不检查UID的唯一性 , 可以添加UID相同的用户

    • -g : GID :指明用户所属基本组 , 可为组名 , 也可以是GID , 基本组对于一个用户只能有一个 , 同一个组可以是多个用户的基本组

    • -c : "COMMENT":用户的注释信息

    • -d : HOME_DIR:以指定的路径(不存在)为家目录

    • -e : 账户过期日期(YYYY-MM-DD格式)

    • -s : SHELL:指明用户的默认shell程序 , 可用列表在/etc/shells文件中

    • -G : GROUP1[,GROUP2,...]:为用户指明附加组 , 组需事先存在

    • -N : 不创建私用组做主组 , 使用users组做主组

    • -r : 创建系统用户 Centos6 :ID<500, Centos 7 :ID <1000

    • -m : 用于系统用户 , 创建家目录 (一般系统用户在被创建时不会创建家目录)

    • -M : 用于普通用户 , 不创建家目录

    • -D : 可以通过这个命令查看/etc/default/useradd这个默认配置文件

      • -s : useradd -D -s SHELL 修改默认的shell

      • -b : BASE_DIR 修改默认的家目录

      • -g GROUP : 修改基本组信息

/etc/default/useradd,以及/etc/login.defs 均为用户创建时会生成的默认信息 newusers : 批量创建用户 。newusers需要的文件内容 , 与/etc/passwd 文件中里面的用户的基本信息和格式一致 。使用时 : 直接使用newusers filename

示例:

创建一个普通用户

sudo useradd -m -s /bin/bash alice
sudo passwd alice          # 必须单独设置密码才能登录

创建并直接加入附加组

sudo useradd -m -G sudo,docker,developers alice
# 等价于之后执行 : sudo usermod -aG sudo,docker,developers alice

创建系统用户(服务账户)

sudo useradd -r -s /usr/sbin/nologin -M prometheus

指定UID和主组

sudo useradd -m -u 1500 -g developers alice

指定账户过期时间

sudo useradd -m -e 2026-12-31 tempuser
# 该账户在 2026-12-31 后自动锁定 ( 适合临时人员 ) 

3.2 userdel

userdel 是 Linux 中用于删除用户账户的命令。它会移除用户在 /etc/passwd、/etc/shadow、/etc/group、/etc/gshadow 中的记录 , 并可选地清理家目录和邮件 spool。

userdel 只能删除用户 , 删除组需要用 groupdel。

  • 语法 : userdel [OPTION]... login

  • OPTIONS

    • -r : 删除用户的同时 , 删除与用户相关的所有文件。

    • -f : 强制删除用户 , 即使用户当前已登录;

3.3 usermod

usermod(user modify)是 Linux 中用于修改已有用户账户属性的命令。它与 useradd 的选项高度相似 , 但作用对象是已存在的用户 , 可修改 UID、主组、附加组、家目录、shell、账户有效期等。

  • 语法: usermod [option] login

  • options

    • -u UID :新UID

    • -g GID :新主组

    • -G GROUP1[,GROUP2,..[,GROUPN]] : 新的附加组 , 原来的附加组将会覆盖 , 若保留原有 , 则要同时使用-a选项。

    • -s SHELL : 新的默认SHELL

    • -c 'COMMENT' : 新的注释信息

    • -d HOME : 新的家目录不会自动创建 ; 若要创建新家目录 , 并移动原家数据 , 同时使用 -m选项

    • -m : 将旧家目录内容移动到新位置(必须配合 -d)

    • -l New_login_name login_name : 新的名字

    • -L : lock指定用户 , 在/etc/shadow对应用户的密码栏中增加! 。锁定只是让密码验证失败 , 但SSH 公钥认证仍然可以登录! 要彻底禁止 ,还需改 shell 为 nologin , 或在 SSH 配置中禁用

    • -U : unlock指定用户,在/etc/shadow密码栏的!拿掉

    • -e YYYY-MM-DD : 指明用户账号过期日期

    • -f INACTIVE : 设置非活动期限

示例

追加用户到附加组

# 将 alice 加入 docker 组 ( 保留原有附加组 ) 
sudo usermod -aG docker alice
​
# 同时加入多个组
sudo usermod -aG docker,sudo,developers alice
​
#忘记 -a 会清空原有附加组!

修改主组

sudo usermod -g developers alice
# 或指定 GID
sudo usermod -g 1005 alice
​
#新主组必须已存在
#用户新建的文件将归属于新主组

修改登录shell

# 改为 zsh
sudo usermod -s /bin/zsh alice
​
# 禁止登录 ( 锁定为 nologin ) 
sudo usermod -s /usr/sbin/nologin alice
​
# 恢复 bash
sudo usermod -s /bin/bash alice

修改家目录

# 仅改 /etc/passwd 中的记录 , 不移动文件
sudo usermod -d /data/home/alice alice
​
# 修改路径并移动原有文件 ( 推荐 ) 
sudo usermod -d /data/home/alice -m alice

修改用户名

sudo usermod -l newname oldname
# 仅改登录名 , 家目录路径不变 ( 如需同时改家目录 , 加 -d -m ) 
sudo usermod -l alice smith -d /home/alice -m

锁定/解锁用户

# 临时锁定 ( 如员工休假 ) 
sudo usermod -L alice
grep alice /etc/shadow
# alice:!$6$xxx...:...    # 密码前多了 ! , 密码验证失败
​
# 解锁
sudo usermod -U alice

设置账户过期时间

# 设置 2026-12-31 过期
sudo usermod -e 2026-12-31 alice
​
# 取消过期限制
sudo usermod -e "" alice

修改UID

sudo usermod -u 2001 alice

3.4 密码管理

3.4.1 passwd

passwd 是 Linux 中用于设置和修改用户密码的命令 , 同时也承担着密码状态管理 ( 锁定/解锁 ) 、密码策略查看等职责。它直接修改 /etc/shadow 中的密码字段 , 是账户安全管理的核心工具。

  • 语法 : passwd [OPTIONS] [Username]

  • OPTIONS :

    • -l :锁定指定用户

    • -u : 解锁指定用户

    • -d :删除指定用户的密码

    • -e : 强制用户下次登录修改密码

    • -n mindays :指定最短使用期限

    • -x maxdays : 最大使用期限

    • -w warndays : 提前多少天开始警告

    • -i inactivedays : 非活动期限

    • -S : 显示密码状态信息

    • -k : 只修改已过期的密码

    • --stdin : 从标准输入接受用户密码

      echo "PASSWORD" | passwd  --stdin UserName

Username : 修改指定用户的密码 , 仅root用户权限 直接使用这用passwd命令 , 表示修改当前用户的密码

示例:

修改自己密码

>passwd
Changing password for alice.
Current password:           # 输入当前密码 ( 验证身份 ) 
New password:               # 输入新密码
Retype new password:        # 再次确认
passwd: password updated successfully

root修改他人密码

sudo passwd alice

查看密码状态

sudo passwd -S alice
​
#输出结果
alice P 09/19/2026 0 99999 7 -1

字段

含义

alice

用户名

P

状态 : P=有密码可用 , L=锁定 , NP=无密码

09/19/2026

上次修改密码的日期

0

密码最短使用天数(min days)

99999

密码最长使用天数(max days)

7

过期前警告天数(warn days)

-1

过期后锁定天数(inactive , -1=不锁定)

锁定账户, 在 /etc/shadow 的密码哈希前加 ! , 使密码验证永远失败。usermod -L 效果相同 , 但SSH 公钥认证仍可登录 , 如需彻底禁用需配合改 shell

sudo passwd -l alice
​
grep alice /etc/shadow
# alice:!$6$rounds=4096$abc...:...    # 多了 ! 前缀

解锁账户 , 移除 ! 前缀 , 恢复密码验证

sudo passwd -u alice
​
​
# 若账户本来无密码 , 解锁会报错 : 
passwd: unlocking the password would result in a passwordless account.
# 需先设置密码再解锁 , 或强制解锁 : sudo passwd -uf alice

强制下次登录改密码。将 /etc/shadow 中"上次修改日期"设为 0 , 使系统认为密码已过期。

sudo passwd -e alice

设置密码有效期

sudo passwd -n 7 -x 90 -w 14 -i 30 alice

选项

值

含义

-n 7

最短 7 天

防止频繁改密码

-x 90

最长 90 天

90 天后强制改密

-w 14

提前 14 天警告

登录时提示密码即将过期

-i 30

过期 30 天后锁定

宽限期后禁用账户

sudo chage -l alice
# Last password change                    : Sep 19, 2026
# Minimum number of days between password change      : 7
# Maximum number of days between password change      : 90
# Number of days of warning before password expires   : 14

删除密码。/etc/shadow 密码字段变空 , 账户无需密码即可登录(取决于 PAM 配置 , 通常本地终端可登录 ,SSH 可能仍拒绝)

sudo passwd -d alice

批量修改密码

#!/bin/bash
while IFS=',' read -r user pwd; do
    echo "$pwd" | sudo passwd --stdin "$user" > /dev/null
    sudo passwd -e "$user"    # 强制下次登录改密
    echo "Changed: $user"
done < users.csv

3.4.2 chpasswd

chpasswd 是 Linux 中用于批量修改用户密码的命令。它从标准输入(stdin)或文件中读取 用户名:密码 格式的数据 , 一次性更新多个用户的密码 , 是 passwd --stdin 的高效批量版。但是必须以root用户执行

  • 语法: chpasswd [选项]

  • 选项

    选项

    作用

    -c 或 --crypt-method

    指定加密算法(SHA512/SHA256/MD5/DES 等)

    -e 或 --encrypted

    输入的密码已是加密后的哈希 , 直接写入不再加密

    -m 或 --md5

    使用 MD5 加密(老式 , 不安全 ,不推荐)

    -s 或 --sha-rounds

    指定 SHA 算法的轮数(如 -s 5000)

    -R 或 --root

    在 chroot 环境下操作(救援模式)

    -h

    显示帮助

数据格式(每行一个用户)

用户名:密码
用户名:密码
...

示例

修改单个用户密码

echo "alice:secret123" | sudo chpasswd
​
#等价于
echo "secret123" | sudo passwd --stdin alice

批量修改多个用户密码

sudo chpasswd <<EOF
alice:pass123
bob:pass456
carol:pass789
EOF
​
#或者使用文件
# 先创建密码文件
cat > users.txt <<EOF
alice:pass123
bob:pass456
carol:pass789
EOF
​
# 执行批量修改
sudo chpasswd < users.txt

写入已加密的哈希密码。-e 模式下 , chpasswd 直接把哈希写入 /etc/shadow , 不再二次加密。

# 生成 SHA-512 哈希
HASH=$(openssl passwd -6 'mypassword')
echo "alice:$HASH" | sudo chpasswd -e

指定加密算法

# 使用 SHA-256
echo "alice:pass123" | sudo chpasswd -c SHA256
​
# 使用 SHA-512 并指定 5000 轮 ( 更慢但更安全 ) 
echo "alice:pass123" | sudo chpasswd -c SHA512 -s 5000

3.4.3 chage

chage(change age)是 Linux 中用于管理用户密码 aging 策略的命令。它专门修改 /etc/shadow 中与密码生命周期相关的 5 个字段: 上次修改日期、最短使用天数、最长使用天数、警告天数、过期后锁定天数。

  • 语法 : chage [OPTION] ...username:

  • OPTIONS :

    • -d : LAST_DAY

    • -E --expiredate : EXPIRE_DATE

    • -I /--inactive : INACTIVE

    • -m /--mindays : MIN_DAYS

    • -M/--maxdays : MAX_DAYS

    • -W / --warndays : WARN_DAYS

    • -l : 显示密码策略

这里解释密码过期参数

类型

控制字段

到期后表现

密码过期(-M)

shadow 第 5 字段

宽限期内可登录但强制改密 , 超期锁定

账户过期(-E)

shadow 第 8 字段

立即无法登录 , 无任何提示机会

示例

查看密码策略

sudo chage -l alice
​
#输出
Last password change                                    : Sep 19, 2026
Password expires                                        : Dec 18, 2026
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 7
Maximum number of days between password change          : 90
Number of days of warning before password expires       : 14

输出项

说明

Last password change

上次改密日期 ( 对应 shadow 第 3 字段 )

Password expires

密码过期日期 ( = 上次改密 + max days )

Password inactive

密码过期后锁定期限 ( 对应第 7 字段 )

Account expires

账户过期日期 ( 对应第 8 字段 , 与密码无关 )

Minimum days

两次改密最小间隔

Maximum days

密码有效期

Warning days

过期前提醒天数

强制定期改密码

sudo chage -M 90 -m 7 -W 14 alice
​
#-M 90 : 密码最长使用 90 天 , 到期必须修改
#-m 7 : 改密后 7 天内不能再次修改(防止绕过历史密码限制)
#-W 14 : 过期前 14 天开始登录时提示

设置账户过期时间

sudo chage -E 2026-12-31 alice
# 该账户在 2026-12-31 当天起无法登录 ( 无论密码是否有效 ) 
​
# 取消账户过期
sudo chage -E -1 alice

设置过期后的宽限时间

sudo chage -I 7 alice
​
#密码过期后 7 天内仍可登录 , 但登录时强制修改密码;超过 7 天账户彻底锁定。
# 不设宽限期 ( 过期立即锁定 ) 
sudo chage -I 0 alice
# 或 -1 表示不限制 ( 依赖系统默认 ) 
sudo chage -I -1 alice

强制用户下次修改密码

sudo chage -d 0 alice

3.5 用户其他管理命令

3.5.1 chsh

chsh(change shell)是 Linux 中用于修改用户登录 Shell 的命令。它直接修改 /etc/passwd 中用户的第 7 个字段(登录shell) , 决定用户登录后默认使用哪种命令解释器。

  • 语法: chsh [选项] [用户名]

  • 选项

    • -s/--shell : 直接指定新的 shell 路径

    • -l : 列出 /etc/shells 中所有可用的 shell

    • -v : 显示版本

文件/etc/shell 中有所有允许的shell文件

$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/dash
/usr/bin/zsh
/bin/zsh
/usr/sbin/nologin
/sbin/nologin
/usr/bin/git-shell

示例

查看当前可用shell

>chsh -l
​
#输出
/bin/sh
/bin/bash
/usr/bin/zsh
/bin/zsh
/usr/sbin/nologin

直接指定shell

# 修改自己
chsh -s /bin/zsh
​
# 修改他人(需 root)
sudo chsh -s /usr/sbin/nologin alice

批量修改

# 给所有已安装 zsh 的用户批量切换 ( 示例 ) 
for user in alice bob carol; do
    sudo chsh -s /bin/zsh $user
done

3.5.2 chfn

chfn(change finger)是 Linux 中用于修改用户 finger 信息的命令。这些信息存储在 /etc/passwd 的第五字段(GECOS 字段) , 包括用户的全名、办公地点、办公电话、家庭电话等 , 主要用于标识用户身份 , 方便他人联系。

GECOS 字段结构

alice:x:1001:1001:Alice Zhang,Room 302,010-12345678,010-87654321,other:/home/alice:/bin/bash
                           │         │          │           │         │
                           │         │          │           │         └─ 其他信息 ( Other ) 
                           │         │          │           └─ 家庭电话 ( Home Phone ) 
                           │         │          └─ 办公电话 ( Work Phone ) 
                           │         └─ 办公地点 ( Office/Building ) 
                           └─ 全名 ( Full Name ) 
                           
Alice Zhang,Room 302,010-12345678,010-87654321,other
(全名,办公地点,办公电话,家庭电话,其他信息)

  • 语法 : chfn [选项] [用户名]

  • 选项

    选项

    参数

    作用

    -f

    字符串

    设置全名 ( Full Name )

    -o

    字符串

    设置办公地点 ( Office/Building/Room )

    -p

    字符串

    设置办公电话 ( Office Phone )

    -h

    字符串

    设置家庭电话 ( Home Phone )

    -r

    字符串

    设置其他信息 ( Room Number , 部分系统支持 )

    -u

    —

    显示帮助

示例

交互式修改

>chfn
​
#提示过程
Changing the user information for alice
Enter the new value, or press ENTER for the default
        Full Name []: Alice Zhang
        Room Number []: Room 302
        Work Phone []: 010-12345678
        Home Phone []: 010-87654321
        Other []: DevOps Team

直接指定字段

# 设置全名
chfn -f "Alice Zhang"
​
# 同时设置多个字段
chfn -f "Alice Zhang" -o "Room 302" -p "010-12345678" -h "010-87654321"

3.5.3 finger

finger 是 Unix/Linux 系统中用于查询用户信息的命令。它显示用户的登录名、真实姓名、终端、登录时间、空闲时间、办公信息(GECOS 字段)、邮件状态以及 ~/.plan、~/.project 等文件内容。名字来源于英文"用手指指着某人"(指认、查询)。

  • 语法 : finger [选项] [用户名[@主机]]

  • 选项

    • -s : 简短格式 , 仅显示登录名、姓名、终端、空闲时间、登录时间、办公信息

    • -l : 长格式(默认) , 显示详细信息 , 包括邮件、plan、project、登录来源

    • -m : 精确匹配用户名(默认会模糊匹配真实姓名)

    • -p : 长格式时不显示 ~/.plan 和 ~/.project 内

示例

查看当前用户

>finger
#输出
Login     Name           Tty      Idle  Login Time   Office     Office Phone
alice     Alice Zhang    pts/0          Sep 19 23:18  Room 302   010-12345678
bob       Bob Li         pts/1    5     Sep 19 22:05  Room 201   010-87654321
root      root           pts/2    2:15  Sep 19 20:30

查看指定用户

>finger alice
#输出
Login: alice                    Name: Alice Zhang
Directory: /home/alice          Shell: /bin/bash
Office: Room 302, 010-12345678  Home Phone: 010-87654321
Last login: Fri Sep 19 23:18 (CST) on pts/0
Mail last read: Fri Sep 19 23:05 2026 (CST)
No Plan.

简短格式

finger -s alice
​
#输出
Login     Name           Tty      Idle  Login Time   Office     Office Phone
alice     Alice Zhang    pts/0          Sep 19 23:18  Room 302   010-12345678

3.5.4 su

su(substitute user / switch user)是 Linux 中用于切换用户身份的命令。它允许当前用户在不退出登录的情况下 , 临时以另一个用户(通常是 root)的身份执行命令或启动新的 shell 会话。

  • 语法 : su [opions...] [-] [user [args...]]

  • options

    • -/--login : 登录 shell , 完全模拟目标用户登录(加载其环境变量、切换到其家目录)。推荐使用

    • -c : 以目标用户身份执行单个命令 , 不启动交互 shell

    • -s : 指定要使用的 shell(目标用户的默认shell 被禁用时有用)

    • -m / -p : 保留当前环境变量(不切换到家目录 , PATH/USER 等不变)

    • -f : 不读取 shell 的启动文件(csh/tcsh 用 , bash 忽略)

    • -l/--login : 同 - , 明确表示 login shell

  • 切换用户的方式

    • su UserName : 非登录式切换 ,即不会读取目标用户的配置文件,不改变当前工作目录

    • su - UserName :登录式切换 ,会读取目标用户的配置文件 , 切换至目标家目录 , 完全切换

root su至其他用户无需密码 , 非root的用户切换时需要密码

示例

切换到root

# 方法1:知道 root 密码
su -
Password:           # 输入 root 密码
​
# 方法2:通过 sudo(不知道 root 密码,推荐)
sudo su -
# 或更简洁
sudo -i

切换到普通用户

su - alice
Password:           # 输入 alice 的密码(root 执行则无需密码)

执行单条命令(不切换shell)

su - -c "systemctl restart nginx"
# 以 root 身份执行重启命令,执行完立即返回原 shell
​
su - alice -c "whoami"
# 输出: alice

保留当前环境变量执行。需要在目标用户身份下 , 但使用当前用户的某些环境配置(如DISPLAY、代理设置) 。

su -m alice           # 保留当前环境变量
# 或
su -p alice

3.5.5 id

看用户的 UID、GID、所属所有组(主组 + 附加组) , 用来确认用户身份与组归属, 排错权限问题非常常用。

  • 语法 : id [OPTION]...[USER]

  • OPTIONS

    • -u : 显示UID

    • -g : 显示GID

    • -G : 输出所有组 ID(主组 + 附加组) , 只打印数字 ,逗号分隔

    • -n /--name : 和 u/g/G 搭配 , 输出名字而不是 ID

    • -r/--real : 显示真实 ID , 不是有效 ID(su/sudo 场景区分 real/effective id)

      普通用户 alice 执行sudo -i切 root

      real uid : alice 的UID

      effective uid : 0(root)

示例

# 只看UID
id -u alice
# 只看主组GID
id -g alice
# 输出所有组ID(主组+附加组)
id -G alice
​
# 输出用户名
id -un alice
# 输出主组名
id -gn alice
# 输出所有组名(主组+附加组)
id -Gn alice
​

4. 组管理

4.1 groupadd

Linux 创建用户组的命令 , 底层会修改 /etc/group 和 /etc/gshadow 文件。

  • 语法 : groupadd [option]...groupname

  • OPTIONS

    • -g GID :指明GID号

    • -r :创建系统组

    • -f /--force : 若组已存在不报错 ; 如果指定的 GID 已存在 , 自动换一个可用 GID

    • -o : 允许 GID 重复(多个组共用同一个 GID , 极少使用)

    • -K : 覆盖 /etc/login.defs 的默认配置 , 如 GID_MIN

示例

创建普通用户组(自动分配空闲GID)

groupadd dev
​
#在 /etc/group 新增一行:   dev:x:1002:
#在 /etc/gshadow新增一行:   dev:!::
#没有任何成员 ,需要用usermod -aG / gpasswd -a`添加用户

创建组, 手动指定GID

groupadd -g 2000 ops

创建系统组

groupadd -r nginx
​
#分配系统区间 GID(1~999)
#一般用于服务账号配套组

强制创建(即使组存在也不报错)

groupadd -f dev

允许重复GID(生产环境不推荐)

groupadd -o -g 1001 testgrp

4.2 groupdel

删除用户组 , 底层修改 /etc/group 和 /etc/gshadow。但是无法删除某个用户的主组。

  • 用法 : groupdel [options] groupname

  • options

    • -f : 强制删除组。即使是用户主组也尝试删除 ; 同时自动清理 /etc/gshadow 里残留记录

示例

删除普通附加组(无用户把它作为主组)

groupdel dev
​
#删除/etc/group中 dev 那一行
#删除/etc/gshadow中 dev 那一行
#不会删除任何用户 , 只删组本身

如果需要对应主组,可以直接删除对应用户或者修改对应用户主组

#直接删除对应用户
userdel xxx
groupdel dev
​
# 将xxx的主组改成root
usermod -g root xxx
groupdel dev
​

4.3 gpasswd

gpasswd 是 Linux 下管理用户组 /etc/group、/etc/gshadow的命令 , 核心用途:设置组密码、添加 / 移除组成员、设置组管理员。

  • 语法 : gpasswd [OPTION] group

  • OPTIONS

    • -a user : 将user添加至指定组中

    • -d user : 从指定组中移除用户

    • -M user1,user2... : 批量设置组成员(覆盖原有成员 , 慎用)

    • -A user1,user2... : 设置有管理权限的用户列表

    • -r : 删除组密码, 清空 /etc/gshadow 中组密码字段

    • -R : 限制组 , 仅组成员可以加入该组(需要密码时生效)

管理权限 , 表示该用户可以为该组 , 添加或者删除成员

组密码主要用户主要用于用户临时切换组访问文件或者运行命令 , 使用的命令为newgrp [group]

示例

给组设置密码。回车后交互式输入密码 , 写入 /etc/gshadow。

gpasswd testgroup

将用户添加到组(附属组)

gpasswd -a tom testgroup
​
#等价于: 
usermod -aG testgroup tom

从组移除用户

gpasswd -d tom testgroup

批量设置组成员(直接覆盖, 原有成员会被清空)

gpasswd -M tom,jim,lily testgroup

限制访问(非组成员不能用 newgrp 切换进来)

gpasswd -R testgroup

4.4 groupmod

修改已经存在的用户组信息 , 底层修改 /etc/group 和 /etc/gshadow。只能修改组名、GID;不能增删组员 , 增删组员要用 usermod/gpasswd。

  • 语法 : groupmod [选项] 组名

  • 选项

    • -g : 修改组的 GID

    • -n : 修改组名

    • -o : 允许 GID 重复 , 多个组共用同一个 GID(极少用)

示例

修改组名, GID 保持不变。把 dev 改名为 develop

groupmod -n develop dev

修改组GID

groupmod -g 2001 develop
​

同时修改组名和GID

groupmod -g 2002 -n ops_new ops

4.5 用户组管理

4.5.1 groupmems

groupmems 属于 shadow-utils 工具集 , 用来管理 /etc/group 里的附属组成员列表 , 只操作附加组成员 , 不能修改组密码 ,不能设置组管理员。

  • 语法 : groupmems [options] [action]

  • options:

    • -g ,--group groupname 更改为指定组(只有root)

  • Actions:

    • -a ,--add username : 指定用户加入组

    • -d ,--delete username : 从组中删除用户

    • -p ,--purge : 从组中清除所有成员

    • -l ,--list : 显示组成员列

不加 -g 的时候 , 命令默认操作当前登录用户的主组。

普通用户不加 -g , 只能管理自己的主组成员 ;

root 加 -g 组名 , 可以管理任意组的成员 ;

示例

root 查看指定组的附属成员

groupmems -g docker -l

root 添加用户到组(追加成员)

groupmems -a tom -g docker

root从组删除用户

groupmems -d tom -g docker

root一次性清空组里所有附属用户

groupmems -p -g docker

普通用户用法(无-g, 只能操作自己主组)

#假设当前用户 tom , 主组是 tom
​
# 查看自己主组的成员
groupmems -l
# 添加用户jack到自己的主组tom
groupmems -a jack
​

4.5.2 groups

查看用户所属所有组(主组 + 附属组) , 无修改能力 , 只做查询。

  • 语法 : groups [用户名...]

示例

查看当前用户自己的组

groups

查询单个用户

groups tom

一次性查询多个用户

groups tom bob
​
#输出
tom : tom sudo docker
bob : bob developers
​


参考链接:

CSDN:Linux下/etc/skel框架目录的简介与使用

博客园-骏马金龙:第2章 细说Linux系统用户/组管理(1)


熊熊