Linux 用户管理
Chen Kai BOSS

在 Linux 多用户、多任务环境中,用户与组的管理不只是"添加账号"这么简单——它直接决定了谁能登录、哪些进程以哪个身份运行、权限模型如何执行、以及 sudo 权限怎么分配。本文会从用户与组的概念模型( users vs groups 、 UID/GID 的含义与边界)讲起,系统梳理你真正会用到的命令(useradd/usermod/userdelgroupadd/groupmod/groupdelpasswd/chage),补齐安全机制(锁定账号、密码策略、 sudo 配置、/etc/sudoers 的正确写法),并详细解析核心系统文件(/etc/passwd/etc/shadow/etc/group/etc/gshadow/etc/skel 的字段含义与实际用途)。最后用实战案例(共享项目目录、服务账号配置、 sudo 权限分级、批量用户管理)把"如何设计合理的用户权限方案"落到实处,让你能独立完成从创建用户到权限分配再到安全加固的完整流程。

Linux 用户与组的核心概念

用户( User)与组( Group)的关系

Linux 是多用户系统,每个用户都有:

  • 唯一的用户名(如 alicebob
  • 唯一的 UID( User ID,数字标识)
  • 一个初始组( Primary Group, GID)
  • 零个或多个附加组( Supplementary Groups)

为什么要有组?

  • 方便权限管理(如"所有开发人员都能访问 /srv/project")
  • 避免给每个用户单独设置权限(维护成本高)

示例

  • 用户 alice 的初始组是 alice(默认创建同名组)
  • 附加组:developersdocker
  • 这样 alice 可以访问 developers 组和 docker 组拥有的资源

UID 和 GID 的边界

UID 范围 用途 示例
0 超级用户( root) root
1-999 系统用户(服务账号,不允许登录) nginx 、 mysql 、 www-data
1000-60000 普通用户(由管理员创建,允许登录) alice 、 bob 、 charlie

注意

  • CentOS 6 及更早版本,普通用户从 UID 500 开始
  • CentOS 7+ 和 Ubuntu,普通用户从 UID 1000 开始

为什么要区分系统用户和普通用户?

  • 系统用户(如 nginx)只用于运行服务,不需要登录( shell 设为 /sbin/nologin
  • 普通用户可以登录、运行程序、管理文件

核心系统文件详解

Linux 的用户信息分布在几个关键文件里:

1. /etc/passwd(公开的用户数据库)

存储所有用户的基本信息,任何用户都可以读取(但只有 root 可以修改)。

格式:每行代表一个用户,字段用冒号 : 分隔

1
username:x:UID:GID:comment:home:shell

示例

1
2
testuser:x:1001:1001:Test User:/home/testuser:/bin/bash
nginx:x:33:33:nginx user:/var/lib/nginx:/sbin/nologin

字段解释

  • username:登录名(如 testuser
  • x:密码占位符(真正的密码哈希在 /etc/shadow
  • UID:用户 ID( 1001)
    • 0: root 用户
    • 1-999:系统用户(服务账号)
    • 1000+:普通用户
  • GID:初始组 ID( 1001)
  • comment:注释信息( GECOS 字段,通常是用户全名或描述)
  • home:家目录(/home/testuser
  • shell:登录 shell(/bin/bash
    • /bin/bash:允许登录
    • /sbin/nologin:禁止登录(服务账号常用)

2. /etc/shadow(密码哈希和密码策略)

存储用户的密码哈希和密码过期策略,只有 root 可以读取

格式

1
username:password_hash:last_change:min:max:warn:inactive:expire:reserved

示例

1
testuser:$6$4kTxu1...:19103:0:99999:7:::

字段解释

  • username:用户名
  • password_hash:密码哈希
    • $6$...: SHA-512 加密
    • $5$...: SHA-256 加密
    • $1$...: MD5 加密(不推荐)
    • !*:账号被锁定
  • last_change:最后一次修改密码的日期(自 1970-01-01 起的天数)
  • min:密码最短使用期限(天数, 0 表示随时可改)
  • max:密码最长使用期限(天数, 99999 表示永不过期)
  • warn:密码过期前多少天开始警告(天数)
  • inactive:密码过期后多少天禁用账号
  • expire:账号过期日期(自 1970-01-01 起的天数)
  • reserved:保留字段

常见操作

1
2
3
4
sudo chage -l testuser  # 查看用户的密码策略
sudo chage testuser # 交互式修改密码策略
sudo chage -M 90 testuser # 设置密码最长使用期限为 90 天
sudo chage -E 2025-12-31 testuser # 设置账号过期日期

3. /etc/group(组信息)

存储所有组的基本信息。

格式

1
groupname:x:GID:member1,member2,member3

示例

1
2
developers:x:1001:alice,bob,charlie
docker:x:999:alice

字段解释

  • groupname:组名(如 developers
  • x:组密码占位符(真正的组密码在 /etc/gshadow,很少用)
  • GID:组 ID( 1001)
  • members:组成员列表(逗号分隔)

注意

  • 这里的成员列表只包含附加组成员(不包括初始组成员)
  • 比如 alice 的初始组是 alice( UID=GID=1001),她的附加组是 developersdocker,所以在 /etc/group 里只能在 developersdocker 的成员列表里看到她

4. /etc/gshadow(组密码和管理信息)

类似 /etc/shadow,存储组密码和详细的组管理信息(在大公司/复杂权限管理场景下会用到)。

格式

1
groupname:password:administrators:members

示例

1
developers:!::alice,bob,charlie
  • !:表示没有组密码
  • administrators:组管理员(可以管理组成员)
  • members:组成员列表

5. /etc/skel(家目录模板)

当创建新用户时,系统会把 /etc/skel 目录下的所有文件复制到新用户的家目录。

默认内容

1
ls -la /etc/skel

输出示例:

1
2
3
.bashrc
.bash_logout
.profile

用途

  • 为所有新用户提供统一的初始配置(如 .bashrc.vimrc 等)
  • 可以自定义 /etc/skel 来提供公司统一的环境配置

如果之前创建用户时没有创建家目录,可以手动初始化

1
2
3
sudo mkdir -p /home/username
sudo cp -r /etc/skel/. /home/username/
sudo chown -R username:username /home/username

用户管理命令

useradd:创建用户

基本用法

1
sudo useradd testuser

常用参数

  • -m:自动创建家目录(推荐)
  • -d PATH:指定家目录路径(默认 /home/username
  • -s SHELL:指定登录 shell(如 /bin/bash/bin/zsh/sbin/nologin
  • -g GROUP:指定初始组(默认创建同名组)
  • -G GROUPS:指定附加组(逗号分隔,如 developers,docker
  • -u UID:指定 UID(默认自动分配)
  • -c COMMENT:添加注释信息

实战示例

1. 创建普通用户

1
2
sudo useradd -m -s /bin/bash alice
sudo passwd alice # 设置密码

2. 创建服务账号(不允许登录)

1
sudo useradd -r -s /sbin/nologin nginx
  • -r:创建系统用户( UID < 1000)

3. 创建用户并指定初始组和附加组

1
2
sudo useradd -m -g developers -G docker,sudo bob
sudo passwd bob
  • -g developers:初始组是 developers
  • -G docker,sudo:附加组是 dockersudo

usermod:修改用户

基本用法

1
sudo usermod [选项] username

常用参数

  • -l NEWNAME:修改用户名
  • -d PATH:修改家目录
  • -m:配合 -d 使用,迁移原家目录内容到新位置
  • -s SHELL:修改登录 shell
  • -g GROUP:修改初始组
  • -G GROUPS:修改附加组(会覆盖原有附加组)
  • -aG GROUPS:追加附加组(推荐,不覆盖原有附加组)
  • -L:锁定用户(禁用密码)
  • -U:解锁用户

实战示例

  1. 将用户加入 sudo 组
1
2
sudo usermod -aG sudo alice  # Debian/Ubuntu
sudo usermod -aG wheel alice # CentOS/RHEL
  1. 修改用户的 shell
1
sudo usermod -s /bin/zsh alice
  1. 迁移用户家目录
1
sudo usermod -d /data/alice -m alice
  • -d /data/alice:新家目录
  • -m:迁移原家目录内容
  1. 锁定和解锁用户
1
2
sudo usermod -L alice  # 锁定(在 /etc/shadow 的密码哈希前加 `!`)
sudo usermod -U alice # 解锁

userdel:删除用户

基本用法

1
2
sudo userdel testuser  # 删除用户(保留家目录)
sudo userdel -r testuser # 删除用户及家目录

注意

  • 删除用户前先确认该用户没有正在运行的进程(ps -u testuser
  • 删除用户后,该用户创建的文件会变成"孤儿文件"(属主显示为 UID,如 1001

最佳实践:不要直接删除用户,而是先锁定

1
2
sudo usermod -L testuser  # 锁定用户(禁止登录)
sudo usermod -s /sbin/nologin testuser # 禁用 shell

之后确认没有问题再删除。

批量删除用户示例

1
2
3
4
5
6
#!/bin/bash
# 从文件读取用户列表并删除
while read username; do
sudo userdel -r "$ username"
echo "已删除用户:$ username"
done < users_to_delete.txt


组管理命令

groupadd:创建组

1
2
sudo groupadd developers  # 创建组
sudo groupadd -g 2000 testgroup # 指定 GID

groupmod:修改组

1
2
sudo groupmod -n newname oldname  # 修改组名
sudo groupmod -g 3000 developers # 修改 GID

groupdel:删除组

1
sudo groupdel testgroup

注意:不能删除用户的初始组(需要先删除用户或修改用户的初始组)。

查看组信息

1
2
getent group developers  # 查看 developers 组的信息
grep developers /etc/group # 同上(直接查看文件)

输出示例:

1
developers:x:1001:alice,bob,charlie

用户与组的关联操作

将用户加入组

1
sudo usermod -aG groupname username  # -a 表示追加(不覆盖原有附加组)

查看用户所属的组

1
2
groups username  # 查看用户所属的所有组
id username # 查看用户的 UID 、 GID 、附加组

输出示例:

1
uid=1001(alice) gid=1001(alice) groups=1001(alice),1002(developers),999(docker)

移除用户与某组的关联

1
sudo gpasswd -d username groupname  # 从组中删除用户

查看当前登录用户

1
2
3
4
whoami  # 显示当前用户名
id # 显示当前用户的 UID 、 GID 、附加组
who # 显示所有登录的用户
w # 更详细的版本(包括用户在干什么)

查看用户登录历史

1
2
3
last  # 显示用户登录历史
last username # 显示指定用户的登录历史
lastlog # 显示所有用户的最后登录时间


密码管理与安全策略

passwd:设置和修改密码

基本用法

1
2
passwd  # 修改当前用户密码
sudo passwd username # 修改指定用户密码

高级用法

1
2
3
4
sudo passwd -l username  # 锁定用户(禁用密码)
sudo passwd -u username # 解锁用户
sudo passwd -d username # 删除用户密码(允许无密码登录,不推荐)
sudo passwd -e username # 强制用户下次登录时修改密码

chage:密码过期策略

chage 用于管理用户的密码过期策略。

查看用户的密码策略

1
sudo chage -l username

输出示例:

1
2
3
4
5
6
7
Last password change                                    : Jan 28, 2025
Password expires : never
Password inactive : never
Account expires : never
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

常用操作

1
2
3
4
5
sudo chage -M 90 username  # 密码最长使用期限 90 天
sudo chage -m 7 username # 密码最短使用期限 7 天(防止频繁改密码绕过策略)
sudo chage -W 7 username # 密码过期前 7 天开始警告
sudo chage -E 2025-12-31 username # 设置账号过期日期
sudo chage -I 30 username # 密码过期后 30 天禁用账号

密码策略最佳实践(安全加固):

1
sudo chage -M 90 -W 7 -I 30 username
  • 密码最长使用期限 90 天
  • 过期前 7 天开始警告
  • 过期后 30 天禁用账号

密码复杂度策略(通过 PAM 配置): 编辑 /etc/pam.d/common-password( Debian/Ubuntu)或 /etc/pam.d/system-auth( CentOS/RHEL),添加:

1
password requisite pam_pwquality.so retry=3 minlen=12 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1

  • minlen=12:最小长度 12 位
  • dcredit=-1:至少 1 个数字
  • ucredit=-1:至少 1 个大写字母
  • ocredit=-1:至少 1 个特殊字符
  • lcredit=-1:至少 1 个小写字母

强制历史密码检查(防止重复使用旧密码):

1
password required pam_pwhistory.so remember=5

  • remember=5:记住最近 5 个密码,不允许重复使用

sudo 权限配置

为什么要用 sudo

问题:如果直接用 root 登录:

  • 风险高(一个 rm -rf / 就删光系统)
  • 日志里分不清是谁干的(都是 root)

解决:用普通用户登录,需要权限时用 sudo

优点

  • 日志里能看到是哪个用户执行了哪个 sudo 命令
  • 可以限制用户只能执行特定命令(如只能重启 nginx,不能删除文件)
  • 不需要告诉用户 root 密码

sudo 的工作原理

  1. 用户执行 sudo command
  2. sudo 检查 /etc/sudoers 文件,看该用户是否有权限
  3. 如果有权限, sudo 要求用户输入自己的密码(不是 root 密码)
  4. 验证通过后,以 root 身份执行命令

配置 sudoers

配置文件/etc/sudoers

重要永远用 visudo 编辑(不要直接 vim /etc/sudoers

1
sudo visudo

visudo 会检查语法,防止你写错导致 sudo 彻底锁死(连 root 都修复不了,只能重启到单用户模式修复)。

基本格式

1
user    host=(runas_user:runas_group) commands

示例

1. 给用户完整的 sudo 权限

1
alice ALL=(ALL:ALL) ALL
  • 第一个 ALL:在所有主机上
  • (ALL:ALL):可以以任何用户和组的身份运行
  • 最后一个 ALL:可以执行任何命令

2. 给组完整的 sudo 权限

1
2
%sudo ALL=(ALL:ALL) ALL  # Debian/Ubuntu(% 表示组)
%wheel ALL=(ALL:ALL) ALL # CentOS/RHEL

3. 允许用户执行特定命令(不需要密码)

1
alice ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx
  • NOPASSWD::不需要输入密码
  • /usr/bin/systemctl restart nginx:只允许重启 nginx

4. 允许用户执行多个命令

1
alice ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

快速方法:加入 sudo 组

Debian/Ubuntu

1
sudo usermod -aG sudo alice

CentOS/RHEL

1
sudo usermod -aG wheel alice

之后 alice 就可以用 sudo 执行任何命令了。

sudo 日志审计

sudo 的所有操作都会记录在日志里,方便审计。

查看 sudo 日志

1
2
sudo grep sudo /var/log/auth.log  # Debian/Ubuntu
sudo grep sudo /var/log/secure # CentOS/RHEL

查看某个用户的 sudo 历史

1
sudo grep "alice.*COMMAND" /var/log/auth.log

实时监控 sudo 操作

1
sudo tail -f /var/log/auth.log | grep sudo


实战场景

场景 1:创建共享项目目录

需求/srv/project 目录, developers 组的成员都能读写,其他人不能访问,新建文件自动继承 developers 组。

方案

1
2
3
4
5
6
7
sudo groupadd developers  # 创建组
sudo useradd -m -G developers alice # 创建用户并加入组
sudo useradd -m -G developers bob

sudo mkdir /srv/project
sudo chown :developers /srv/project # 属组改为 developers
sudo chmod 2770 /srv/project # SGID + 770
  • 2: SGID(新建文件自动继承 developers 组)
  • 770: owner 和 group 都是 rwx, others 无权限

验证

1
2
3
su - alice
touch /srv/project/test.txt
ls -l /srv/project/test.txt # 输出:-rw-r--r-- alice developers

场景 2:创建服务账号(如 Nginx)

需求:创建 nginx 用户,用于运行 Nginx 服务,不允许登录。

方案

1
sudo useradd -r -s /sbin/nologin -d /var/lib/nginx -M nginx
  • -r:创建系统用户( UID < 1000)
  • -s /sbin/nologin:禁止登录
  • -d /var/lib/nginx:指定家目录
  • -M:不创建家目录

场景 3:批量创建用户

假设你有一个用户列表 users.txt

1
2
3
alice
bob
charlie

方案

1
2
3
4
5
6
7
#!/bin/bash
while read username; do
sudo useradd -m -s /bin/bash "$ username"
echo "password123" | sudo passwd --stdin "$ username" # CentOS/RHEL
# 或 Ubuntu/Debian:
# echo "$ username:password123" | sudo chpasswd
done < users.txt

场景 4: sudo 权限分级

需求

  • alice 可以执行任何命令
  • bob 只能重启 nginx
  • charlie 只能查看日志

方案:编辑 sudo visudo

1
2
3
alice ALL=(ALL:ALL) ALL
bob ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
charlie ALL=(ALL) NOPASSWD: /usr/bin/tail, /usr/bin/less, /usr/bin/cat

场景 5:限制用户只能访问特定目录( chroot)

需求:限制 ftpuser 只能访问 /srv/ftp 目录,不能访问系统其他目录。

方案:使用 chroot jail(需要配置 SSH 或 FTP 服务)

SSH chroot 配置(编辑 /etc/ssh/sshd_config):

1
2
3
4
5
Match User ftpuser
ChrootDirectory /srv/ftp
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no

重启 SSH 服务:

1
sudo systemctl restart sshd

现在 ftpuser 登录后只能看到 /srv/ftp 目录,系统其他目录完全看不到。

场景 6:用户配额管理(防止某个用户占满磁盘)

需求:限制用户只能使用 10GB 磁盘空间。

方案:使用磁盘配额( quota)

1. 启用配额(在 /etc/fstab 里添加 usrquota):

1
/dev/sda1 /home ext4 defaults,usrquota 0 2

2. 重新挂载并初始化配额

1
2
3
sudo mount -o remount /home
sudo quotacheck -cugm /home
sudo quotaon /home

3. 设置配额

1
sudo edquota -u alice

在编辑器里设置:

1
2
3
Disk quotas for user alice (uid 1001):
Filesystem blocks soft hard inodes soft hard
/dev/sda1 0 10G 12G 0 0 0

  • soft:软限制(超过会警告)
  • hard:硬限制(无法超过)

4. 查看配额使用情况

1
2
quota -u alice  # 查看 alice 的配额使用
sudo repquota -a # 查看所有用户的配额

场景 7:禁用 root 直接登录(安全加固)

需求:禁止 root 用户通过 SSH 直接登录,强制使用普通用户 + sudo 。

方案:编辑 /etc/ssh/sshd_config

1
PermitRootLogin no

重启 SSH 服务:

1
sudo systemctl restart sshd

最佳实践: 1. 先创建一个有 sudo 权限的普通用户(如 admin) 2. 确认该用户可以 sudo su - 切换到 root 3. 再禁用 root 登录(否则可能把自己锁在外面)


总结与扩展阅读

这篇文章涵盖了 Linux 用户管理的核心内容:

  1. ✅ 用户与组的概念模型( users vs groups 、 UID/GID 边界)
  2. ✅ 核心系统文件详解(/etc/passwd/etc/shadow/etc/group/etc/gshadow/etc/skel
  3. ✅ 用户管理命令(useradd/usermod/userdelpasswd/chage
  4. ✅ 组管理命令(groupadd/groupmod/groupdel
  5. ✅ sudo 权限配置(/etc/sudoersvisudo、权限分级)
  6. ✅ 实战场景(共享目录、服务账号、批量创建、 sudo 分级)

扩展阅读

  • man useradd:查看 useradd 的详细手册
  • man sudoers:查看 sudoers 的详细配置说明
  • PAM( Pluggable Authentication Modules):更高级的认证框架

下一步

  • 《 Linux 文件权限》:学习如何管理文件/目录权限( rwx 、 SUID/SGID 、 ACL)
  • 《 Linux 系统服务管理》:学习如何管理服务、配置开机自启

到这里,建议已经从"会创建用户"升级到"能设计合理的用户权限方案、能配置 sudo 分级权限、能管理密码策略"。用户管理是 Linux 安全的基础,掌握了它,你就能更好地保护系统和数据。

  • 本文标题:Linux 用户管理
  • 本文作者:Chen Kai
  • 创建时间:2019-11-25 14:15:00
  • 本文链接:https://www.chenk.top/Linux-%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论