用户与权限管理

瑞克 0 阅读 linux服务

用户与权限管理

写在前面:如果说Linux系统是一栋大楼,那用户就是大楼里的住户,权限就是每个住户的"门禁卡"——决定了谁能进哪些房间、能做什么事。本章将深入Linux的安全核心,带你理解用户体系、掌握权限管理,让你的系统既安全又好用。


3.1 UID体系:Linux的"身份证制度"

生活类比

想象一所学校:校长(root)拥有最高权限,各处室主任(系统用户)各自管理特定事务,普通师生(普通用户)只能在自己的权限范围内活动。Linux用UID(User ID)来标识每个用户的身份,就像学校给每个人发的工号。

UID分类体系

UID范围用户类型说明类比
0超级管理员(root)拥有所有权限,可为所欲为校长——啥都能管
1-999系统用户运行系统服务的专用账户各处室——管自己那一摊
1000+普通用户日常使用的账户师生——权限有限

重要概念

# 查看当前用户的UID
id
# 输出示例:uid=1000(teacher) gid=1000(teacher) groups=1000(teacher),4(adm),27(sudo)

# 查看root的UID
id root
# 输出:uid=0(root) gid=0(root) groups=0(root)

# 查看所有用户(观察UID分布)
cat /etc/passwd | awk -F: '{print $1, $3}' | sort -t' ' -k2 -n | head -20

多发行版UID差异

发行版系统用户UID范围普通用户起始UID说明
RHEL系(CentOS/RHEL/麒麟V10服务器)1-9991000RHEL 7+ 统一标准
Debian系(Ubuntu/Debian/麒麟V10桌面)1-9991000Debian 8+ 统一标准
旧版RHEL(CentOS 5/6)1-499500老系统注意
旧版Debian(Debian 6及以前)1-9991000

注意:虽然现代发行版标准已统一,但如果你管理的是老系统,要注意UID分界线的差异。


想一想:为什么Linux要给系统服务创建专用的系统用户(如nginx、mysql),而不是让它们都用root运行?(提示:想想"最小权限原则"——如果一个人只需要看门的权限,你会把保险柜钥匙也给他吗?)


3.2 用户信息文件:/etc/passwd 和 /etc/shadow

3.2.1 /etc/passwd —— 用户的"户口本"

# 查看passwd文件
cat /etc/passwd

每行格式(用冒号分隔的7个字段):

teacher:x:1000:1000:数学老师张老师:/home/teacher:/bin/bash
   │    │  │    │       │              │            │
   │    │  │    │       │              │            └── 登录Shell
   │    │  │    │       │              └── 家目录
   │    │  │    │       └── 用户描述信息(GECOS字段)
   │    │  │    └── GID(主组编号)
   │    │  └── UID(用户编号)
   │    └── 密码占位符(x表示密码存在shadow中)
   └── 用户名

字段详解

字段序号名称说明示例
1用户名登录时使用的名字teacher
2密码占位x表示密码在shadow中x
3UID用户唯一编号1000
4GID主组编号1000
5描述用户全名或描述数学老师
6家目录用户的主目录路径/home/teacher
7Shell用户的命令解释器/bin/bash

常见Shell类型

Shell路径说明
bash/bin/bash最常用的交互式Shell
sh/bin/sh基础Shell(POSIX标准)
zsh/bin/zsh功能丰富的增强Shell
/sbin/nologin-禁止登录(服务用户专用)
/bin/false-禁止登录(另一种方式)
# 查看系统中有哪些Shell可用
cat /etc/shells

# 查看使用bash的用户
grep "/bin/bash" /etc/passwd

# 查看被禁止登录的用户(系统服务用户)
grep -c "/sbin/nologin" /etc/passwd

3.2.2 /etc/shadow —— 密码的"保险柜"

sudo cat /etc/shadow   # 需要root权限

每行格式(用冒号分隔的9个字段):

teacher:$6$rAnDoM$HaSh...:19797:0:99999:7:::
   │         │              │    │   │    │
   │         │              │    │   │    └── 密码最长使用天数
   │         │              │    │   └── 密码最短修改间隔
   │         │              │    └── 上次修改密码的天数
   │         │              └── GID(主组编号)
   │         └── 加密后的密码($6$=SHA-512)
   └── 用户名

特殊密码字段含义

字段值含义
*!账号被锁定
!!密码未设置
空密码(极度危险!)
# 查看哪些账号没有设置密码(安全审计)
sudo awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow

3.2.3 /etc/group —— 组的"花名册"

cat /etc/group

每行格式

sudo:x:27:teacher,admin
 │   │  │     │
 │   │  │     └── 组成员列表(逗号分隔)
 │   │  └── GID(组编号)
 │   └── 密码占位
 └── 组名

想一想:为什么密码不直接存在/etc/passwd中,而要单独放在/etc/shadow中?(提示:/etc/passwd是所有用户都能读的,想想这对密码意味着什么?)


3.3 用户管理命令

3.3.1 useradd —— 创建新用户

# 基本创建用户
sudo useradd zhangsan

# 创建用户并设置详细信息(推荐)
sudo useradd -m -s /bin/bash -c "数学老师张三" -G sudo,wheel zhangsan
# -m 创建家目录  -s 指定Shell  -c 描述信息  -G 附加组

# 创建系统用户(运行服务用)
sudo useradd -r -s /sbin/nologin -d /opt/myapp myapp

# 创建后必须设置密码
sudo passwd zhangsan

常用参数-m(创建家目录) -s(Shell) -d(家目录路径) -g(主组) -G(附加组) -c(描述) -e(过期日期) -r(系统用户) -u(指定UID)

多发行版差异

项目RHEL系Debian系
默认Shell/bin/bash/bin/sh
默认创建家目录否(需加-m)
管理员组名wheelsudo
# RHEL系/麒麟V10服务器版:将用户加入管理员组
sudo usermod -aG wheel zhangsan

# Debian系/Ubuntu/麒麟V10桌面版:将用户加入管理员组
sudo usermod -aG sudo zhangsan

3.3.2 usermod —— 修改用户信息

# 修改Shell
sudo usermod -s /bin/zsh zhangsan

# 添加用户到附加组(-aG 最常用!)
sudo usermod -aG docker zhangsan
# 注意:-a 是 append(追加),不加-a会替换所有附加组!

# 锁定/解锁用户账号
sudo usermod -L zhangsan       # 锁定(禁止登录)
sudo usermod -U zhangsan       # 解锁

# 设置账号过期日期
sudo usermod -e 2025-06-30 zhangsan

# 修改家目录(-m同时迁移文件)
sudo usermod -d /data/zhangsan -m zhangsan

常见错误usermod -G 不带 -a 会清除用户原来的所有附加组!一定要用 usermod -aG

3.3.3 userdel —— 删除用户

sudo userdel zhangsan          # 删除用户(保留家目录)
sudo userdel -r zhangsan       # 删除用户及其家目录(推荐)

# 删除前检查清单
sudo ps aux | grep zhangsan    # 检查进程
sudo find / -user zhangsan     # 检查文件所有权

警告:删除用户前请确认该用户没有正在运行的进程和crontab任务。

3.3.4 passwd —— 密码管理

passwd                     # 修改自己的密码
sudo passwd zhangsan       # root修改他人密码
sudo passwd -e zhangsan    # 强制下次登录修改密码
sudo passwd -l zhangsan    # 锁定密码
sudo passwd -u zhangsan    # 解锁密码
sudo passwd -S zhangsan    # 查看密码状态(PS=已设置, LK=锁定, NP=无密码)

3.3.5 chage —— 密码过期策略

sudo chage -l zhangsan                 # 查看密码策略
sudo chage -M 90 -W 7 zhangsan        # 90天过期,提前7天警告
sudo chage -E 2025-12-31 temp_user    # 设置账号过期日期

想一想:为什么系统管理员应该设置密码过期策略?但如果密码过期太频繁(比如每周改一次),用户会怎么做?这反而会造成安全隐患吗?(提示:想想"Post-it密码"问题)


3.4 组管理

生活类比

组(Group)就像公司的部门。一个人可以属于多个部门(附加组),但有一个"主部门"(主组)。权限分配时,可以按部门统一授权,而不必一个个设置。

3.4.1 groupadd / groupmod / groupdel

sudo groupadd teachers              # 创建新组
sudo groupadd -g 2000 developers    # 创建组并指定GID
sudo groupmod -n math_teachers teachers  # 修改组名
sudo groupdel math_teachers         # 删除组

3.4.2 gpasswd —— 组成员管理

sudo gpasswd -a zhangsan teachers   # 添加用户到组
sudo gpasswd -d zhangsan teachers   # 从组中移除用户
grep teachers /etc/group            # 查看组成员

3.5 基本权限:rwx

3.5.1 权限基础回顾

ls -l /etc/hosts
# -rw-r--r-- 1 root root 209 Mar 15 10:30 /etc/hosts

权限分为三组

-rw-r--r--
 │││││││││
 ││││││└┘── 其他用户(others):r-- = 只读
 │││└┘───── 所属组(group):r-- = 只读
 └┘──────── 文件所有者(owner):rw- = 读写

3.5.2 chmod —— 修改权限

数字法(推荐,最简洁):r=4, w=2, x=1,三组权限各求和后拼成三位数。

chmod 644 homework.txt      # owner=rw-, group=r--, others=r--
chmod 755 script.sh         # owner=rwx, group=r-x, others=r-x
chmod 600 private_key.pem   # owner=rw-, group=---, others=---
chmod -R 755 /var/www/html/ # 递归修改目录权限

字母法(语义更清晰):u=所有者, g=组, o=其他, a=所有人;+=添加, -=移除

chmod u+x script.sh         # 给所有者添加执行权限
chmod go-w data.txt         # 给组和其他用户去掉写权限
chmod a=r config.txt        # 给所有人设置只读

3.5.3 chown / chgrp —— 修改所有者和组

sudo chown zhangsan homework.txt              # 修改所有者
sudo chown zhangsan:teachers homework.txt     # 修改所有者和组(最常用)
sudo chgrp teachers homework.txt              # 只修改组
sudo chown -R www-data:www-data /var/www/html/  # 递归修改

权限实战

# SSH密钥权限(权限不对SSH会拒绝使用!)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa          # 私钥必须600
chmod 644 ~/.ssh/id_rsa.pub      # 公钥可以644

想一想:一个文件权限设置为777,任何人都能读写执行。这在什么情况下是合理的?在什么情况下是严重的安全隐患?(提示:想想/tmp目录和Web服务器配置文件)


3.6 特殊权限:SUID、SGID、Sticky Bit

3.6.1 SUID(Set User ID)—— "借壳办事"

类比:就像学校打印机——虽然你是普通老师(普通用户),但使用打印机时你"借用"了管理员的权限(SUID),所以你能操作打印机,但不能碰管理员的其他东西。

# 查看SUID的经典例子:passwd命令
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root 68208 Mar 15 /usr/bin/passwd
#     s                                  ← 注意这个s!
# passwd命令属于root,但普通用户也能执行
# 执行时临时获得root权限,才能修改/etc/shadow

# 设置SUID
chmod u+s /path/to/program
# 或
chmod 4755 /path/to/program
# 4 = SUID位,755 = 基本权限

# 查看系统中所有SUID文件(安全审计)
find / -perm -4000 -type f 2>/dev/null

3.6.2 SGID —— "组内共享"

# 对目录设置SGID:目录中新建的文件自动继承目录的组
sudo mkdir /data/shared
sudo chgrp teachers /data/shared
sudo chmod 2775 /data/shared     # 2=SGID

# 此后任何人在此目录创建的文件,组都是teachers

3.6.3 Sticky Bit —— "只删自己的"

# 经典例子:/tmp目录(任何人都能创建文件,但只能删除自己的)
chmod 1777 /data/upload          # 1=Sticky Bit

特殊权限数字速查

特殊权限数字前缀字母标识位置常用场景
SUID4所有者执行位(s)passwd等需要提权的命令
SGID2组执行位(s)团队共享目录
Sticky1其他执行位(t)/tmp等公共目录
# 完整权限示例:SUID + 755
chmod 4755 /usr/bin/myprogram
# 显示:-rwsr-xr-x

# 完整权限示例:SGID + Sticky + 770
chmod 3770 /data/team_dir
# 显示:drwxrws--T

想一想:如果你发现一个程序同时设置了SUID和属于root用户,这可能带来什么安全风险?攻击者会如何利用这个程序?


3.7 ACL(访问控制列表):更精细的权限控制

生活类比

基本权限就像"大门门禁"——只能区分"住户/访客/外人"三种身份。而ACL就像"精确到每个人的门禁卡"——你可以让张老师只能看301教室,李老师能看301和302,王主任能看所有教室。

3.7.1 查看ACL

# 查看文件的ACL
getfacl /data/homework.txt
# 输出包含:文件信息、所有者权限、组权限、其他用户权限
# 以及任何额外的ACL条目(如特定用户/组的权限)

3.7.2 设置ACL

# 给特定用户设置权限
setfacl -m u:zhangsan:rw /data/homework.txt

# 给特定组设置权限
setfacl -m g:math_dept:rwx /data/project/

# 设置默认ACL(新文件自动继承)
setfacl -d -m u:zhangsan:rwx /data/project/

# 删除特定用户的ACL
setfacl -x u:zhangsan /data/homework.txt

# 删除所有ACL
setfacl -b /data/homework.txt

# 递归设置
setfacl -R -m u:zhangsan:rwx /data/project/

setfacl参数速查

参数说明示例
-m修改/添加ACLsetfacl -m u:user:rwx file
-x删除指定ACL条目setfacl -x u:user file
-b删除所有ACLsetfacl -b file
-d设置默认ACL(仅目录)setfacl -d -m u:user:rwx dir/
-R递归操作setfacl -R -m u:user:r dir/
-k删除默认ACLsetfacl -k dir/

ACL实战场景

# 场景:学校共享教学目录
# math_dept组可读写,admin可完全控制,其他人只能查看

sudo mkdir /data/teaching
sudo chown root:math_dept /data/teaching
sudo chmod 2770 /data/teaching                    # SGID + 组全权
sudo setfacl -m u:admin:rwx /data/teaching        # 给管理员完全控制
sudo setfacl -d -m u:admin:rwx /data/teaching     # 默认ACL继承

想一想:如果没有ACL,你想让张三能读某个文件、李四能写某个文件、王五什么都不能做,你需要怎么设置?有了ACL之后呢?


3.8 sudo配置:让普通人也能"临时当领导"

生活类比

sudo就像"临时授权"——你不是校长(root),但校长可以授权你在特定情况下使用校长的印章。而且每次使用都会记录在案,方便审计。

3.8.1 为什么要用sudo?

做法优点缺点
直接用root登录方便极度危险、无法审计、误操作不可逆
使用sudo安全、可审计、权限可控需要配置

3.8.2 visudo —— 编辑sudo配置

# 使用visudo编辑sudoers文件(自动语法检查,防止配错导致无法sudo!)
sudo visudo

# 如果习惯用vim编辑
sudo visudo    # 默认使用vi/vim
# 或在文件开头设置:Defaults editor=/usr/bin/vim

sudoers文件语法

# 格式:用户 主机=(以谁的身份) 可以执行的命令

# 允许zhangsan以root身份执行所有命令(需要密码)
zhangsan  ALL=(ALL:ALL) ALL

# 允许lisi执行所有命令(不需要密码)
lisi      ALL=(ALL:ALL) NOPASSWD: ALL

# 允许wangwu只能执行systemctl相关命令
wangwu    ALL=(ALL) /usr/bin/systemctl

# 允许teachers组的所有成员执行所有命令
%teachers ALL=(ALL:ALL) ALL

常用配置示例

# 推荐做法:在sudoers.d目录下创建单独文件(更清晰)
echo "zhangsan ALL=(ALL:ALL) ALL" | sudo tee /etc/sudoers.d/zhangsan
sudo chmod 440 /etc/sudoers.d/zhangsan

# 或直接加入管理员组
sudo usermod -aG wheel zhangsan     # RHEL系
sudo usermod -aG sudo zhangsan      # Debian系

多发行版sudo差异

操作RHEL系Debian系
管理员组wheelsudo
sudoers默认配置%wheel ALL=(ALL) ALL%sudo ALL=(ALL:ALL) ALL
sudoers.d目录/etc/sudoers.d//etc/sudoers.d/
添加sudo用户usermod -aG wheel userusermod -aG sudo user

3.8.3 sudo的使用方式

# 以root身份执行命令
sudo systemctl restart nginx

# 以其他用户身份执行命令
sudo -u zhangsan touch /home/zhangsan/test.txt

# 切换到root shell
sudo -i

# 查看当前用户的sudo权限
sudo -l

# 查看sudo日志
sudo grep sudo /var/log/auth.log         # Debian系
sudo grep sudo /var/log/secure           # RHEL系

想一想:如果你给一个实习生配置了NOPASSWD: ALL的sudo权限,可能会发生什么问题?你会怎么配置才能既让实习生能工作,又不会搞坏系统?


3.9 PAM简介:可插拔认证模块

生活类比

PAM(Pluggable Authentication Modules)就像学校的"安检系统"——它是模块化的,你可以自由组合不同的安检方式:刷卡、指纹、人脸识别。换一种安检方式不需要重建整个安检通道,只需要换一个模块。

PAM的作用

用户请求登录
     │
     ▼
┌────────────┐
│  应用程序   │ ← sshd, login, su, sudo, passwd...
│  (如sshd)   │
└─────┬──────┘
      │ 调用
      ▼
┌────────────┐
│   PAM层    │ ← 统一的认证接口
└─────┬──────┘
      │ 按顺序执行模块
      ▼
┌────────────┐  ┌────────────┐  ┌────────────┐
│ 密码验证    │→│ 账户检查    │→│ 会话管理    │
│ pam_unix   │  │ pam_nologin│  │ pam_limits │
└────────────┘  └────────────┘  └────────────┘

PAM配置文件位置

# 查看PAM配置目录
ls /etc/pam.d/
# sshd, su, sudo, login... ← 每个服务一个配置文件

多发行版PAM差异

配置RHEL系Debian系
全局认证/etc/pam.d/system-auth/etc/pam.d/common-auth
密码策略/etc/pam.d/system-auth/etc/pam.d/common-password
密码复杂度pam_pwqualitypam_pwqualitypam_cracklib
登录失败锁定pam_faillockpam_tally2pam_faillock

PAM实用配置示例

# 限制su切换到root(只有wheel组成员可以)
# 编辑 /etc/pam.d/su,取消注释:
# auth required pam_wheel.so use_uid

# 配置密码复杂度(编辑common-password或system-auth)
# password requisite pam_pwquality.so retry=3 minlen=8 ucredit=-1 lcredit=-1 dcredit=-1

# 限制登录失败次数(防止暴力破解)
# auth required pam_faillock.so deny=5 unlock_time=600

警告:修改PAM配置前务必备份,并保持一个root终端不关闭作为"应急通道"!配置错误可能导致所有用户无法登录。


想一想:如果不用PAM,每个程序(sshd、login、sudo)都需要自己实现密码验证逻辑,这会造成什么问题?PAM的"可插拔"设计解决了什么问题?(提示:想想"标准化接口"的好处)


3.10 多发行版默认配置差异汇总

配置项RHEL系 (CentOS/RHEL/麒麟V10服务器)Debian系 (Ubuntu/Debian/麒麟V10桌面)
root默认状态有密码,可直接登录密码锁定,通过sudo管理
管理员组wheelsudo
默认Shell/bin/bash/bin/bash(Ubuntu sh→dash)
用户家目录默认权限700755(Ubuntu)/ 755(Debian)
umask默认值022022
密码加密算法SHA-512 (6)yescrypt (y, Debian 12+) / SHA-512
用户创建默认组同名私有组同名私有组
sudoers管理visudo + /etc/sudoers.d/visudo + /etc/sudoers.d/
密码策略工具pam_pwqualitypam_pwquality / pam_cracklib
家目录加密不支持Ubuntu可选加密家目录
默认密码过期99999天(永不过期)99999天(永不过期)
# 查看你当前系统的默认用户配置模板
cat /etc/default/useradd         # RHEL系
# 或
cat /etc/adduser.conf            # Debian系

# 查看默认umask
umask
# 大多数系统默认022,意味着新建文件644,新目录755

# 修改默认umask(更安全的设置)
# 编辑 /etc/profile 或 /etc/login.defs
# UMASK 027    ← 新建文件640,新目录750(更安全)

本章小结

知识点核心命令/文件
用户体系root(UID=0) / 系统(1-999) / 普通(1000+)
用户信息/etc/passwd / /etc/shadow / /etc/group
创建用户useradd -m -s /bin/bash username
修改用户usermod -aG group username
删除用户userdel -r username
密码管理passwd / chage
锁定/解锁usermod -L / usermod -U
组管理groupadd / gpasswd -a / gpasswd -d
基本权限chmod 755 / chown user:group
特殊权限SUID(4) / SGID(2) / Sticky(1)
ACLgetfacl / setfacl -m
sudo配置visudo / /etc/sudoers.d/
PAM/etc/pam.d/

运维常用命令精选

以下是用户与权限管理的"高频命令",建议熟练掌握。

用户审计"五件套"

# 1. 查看当前登录用户
who
w                # 更详细

# 2. 查看最近的登录历史
last -n 20

# 3. 查看登录失败记录
lastb -n 20      # 需要root权限

# 4. 查看UID为0的用户(应该是root,多了就说明有问题)
awk -F: '$3 == 0 {print $1}' /etc/passwd

# 5. 查看有登录Shell的用户
grep -v "nologin\|false" /etc/passwd | awk -F: '{print $1}'

安全巡检脚本

#!/bin/bash
# 快速安全巡检
echo "=== UID为0的用户 ==="
awk -F: '$3 == 0 {print $1}' /etc/passwd

echo "=== 空密码账号 ==="
sudo awk -F: '($2 == "" || $2 == "!") {print $1}' /etc/shadow

echo "=== SUID文件 ==="
find / -perm -4000 -type f 2>/dev/null

echo "=== 777权限文件 ==="
find /etc /usr /bin -perm 777 -type f 2>/dev/null

echo "=== 可登录用户 ==="
grep -v "nologin\|false" /etc/passwd | awk -F: '{print $1}'

批量用户管理

# 从文件批量创建用户(users.txt格式:用户名:密码:描述)
while IFS=: read -r username password comment; do
    sudo useradd -m -s /bin/bash -c "$comment" "$username"
    echo "$username:$password" | sudo chpasswd
done < users.txt

# 批量锁定离职员工账号
for user in employee1 employee2; do
    sudo usermod -L "$user"
    sudo usermod -s /sbin/nologin "$user"
done

权限排查技巧

# 查看文件访问路径上每一级的权限
namei -l /path/to/file

# 测试某个用户能否访问文件
sudo -u zhangsan cat /data/secret.txt

# 查看某个用户属于哪些组
groups zhangsan
id zhangsan

趣味命令专栏

学习用户管理也可以很有趣!

# 1. 看看系统中有多少个"幽灵用户"(有账号但从不登录)
sudo lastlog | grep "Never logged in"

# 2. 谁是最"勤劳"的用户?(登录次数最多)
last | awk '{print $1}' | sort | uniq -c | sort -rn | head -10

# 3. 当前有谁在用你的服务器
w

# 4. 用cowsay提醒安全意识
cowsay -f tux "不要使用123456作为密码!"

# 5. 看看root有多"孤独"(UID为0的用户应该只有root)
awk -F: '$3==0' /etc/passwd
# 如果输出超过一行,说明有安全隐患!

# 6. 随机密码生成器(数学老师可以用这个讲排列组合!)
openssl rand -base64 16

本章思考题

  1. 解释UID 0、UID 1-999、UID 1000+ 分别代表什么类型的用户。为什么不应该给普通用户分配UID 0?
  2. 一个文件的权限显示为 -rwsr-xr--,请分析这表示什么?SUID在这里的作用是什么?
  3. 用数字法写出以下权限:所有者可读写执行,组可读可执行,其他人无权限。
  4. 为什么推荐使用sudo而不是直接su切换到root?列举至少3个理由。
  5. 设计一套学校教学机房的用户和权限方案:需要区分管理员、教师和学生三种角色,每种角色应该有什么样的权限?