用户与权限管理
大约 14 分钟约 4135 字
用户与权限管理
简介
Linux 系统通过用户和用户组机制实现多用户环境下的资源隔离与安全控制。用户与权限管理是系统安全的基础,涵盖用户账号的创建与删除、用户组管理、sudo 提权配置、文件权限控制以及 ACL 访问控制列表等内容,是每一位 Linux 运维工程师必须熟练掌握的核心技能。
特点
用户管理
创建与删除用户
# 创建新用户(自动创建家目录和同名用户组)
useradd -m -s /bin/bash zhangsan
# 创建用户并指定附加组
useradd -m -s /bin/bash -G docker,wheel devuser
# 创建系统用户(无登录shell,用于服务运行)
useradd -r -s /sbin/nologin nginx
# 创建用户并指定UID和家目录
useradd -u 2000 -d /data/home/wangwu -m wangwu
# 设置用户密码
passwd zhangsan
# 删除用户(保留家目录)
userdel zhangsan
# 删除用户并同时删除家目录和邮件目录
userdel -r zhangsan用户信息修改
# 修改用户备注信息
usermod -c "运维管理员" zhangsan
# 修改用户的主组
usermod -g developers zhangsan
# 添加附加组(不影响已有附加组)
usermod -aG docker zhangsan
# 修改用户的登录Shell
usermod -s /bin/zsh zhangsan
# 锁定用户账号
usermod -L zhangsan
# 解锁用户账号
usermod -U zhangsan
# 查看用户信息
id zhangsan
finger zhangsan用户组管理
组的创建与维护
# 创建用户组
groupadd developers
# 创建用户组并指定GID
groupadd -g 3000 ops
# 修改组名称
groupmod -n devteam developers
# 修改组GID
groupmod -g 3500 ops
# 删除用户组
groupdel devteam
# 查看用户所属的所有组
groups zhangsan
# 查看组内所有成员
getent group docker
# 将用户添加到组(另一种方式)
gpasswd -a zhangsan docker
# 将用户从组中移除
gpasswd -d zhangsan dockerSudo 权限管理
配置 sudo 权限
# 使用visudo安全编辑sudoers文件
visudo
# 常用sudoers配置示例:
# 允许用户执行所有命令(等价于root)
zhangsan ALL=(ALL) ALL
# 允许用户组无密码执行所有命令
%docker ALL=(ALL) NOPASSWD: ALL
# 允许用户仅执行特定命令
devuser ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
# 允许用户以特定身份执行命令
deploy ALL=(nginx) /bin/systemctl restart nginx
# 允许用户组无密码执行特定类别命令
%ops ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/journalctlSudo 使用与审计
# 以root身份执行命令
sudo yum update -y
# 以指定用户身份执行命令
sudo -u nginx cat /var/log/nginx/access.log
# 查看当前用户的sudo权限
sudo -l
# 切换到root用户
sudo -i
# 查看sudo执行日志
cat /var/log/secure | grep sudo
journalctl -u sshd | grep "session opened"文件权限管理
chmod 权限设置
# 数字方式设置权限
chmod 755 /data/app # rwxr-xr-x
chmod 644 /data/config.ini # rw-r--r--
chmod 700 /root/.ssh # rwx------
# 符号方式设置权限
chmod u+x /data/scripts/deploy.sh # 给属主添加执行权限
chmod g+w /data/shared # 给属组添加写权限
chmod o-r /data/secret # 移除其他人的读权限
chmod a+r /data/public/readme.txt # 所有人可读
# 递归设置目录权限
chmod -R 755 /data/web
# 设置特殊权限
chmod u+s /usr/bin/passwd # SUID:执行时以属主身份运行
chmod g+s /data/shared # SGID:新文件继承组
chmod o+t /tmp # Sticky Bit:仅属主可删除chown 属主属组修改
# 修改文件属主
chown nginx /data/web/html
# 修改文件属组
chgrp nginx /data/web/html
# 同时修改属主和属组
chown nginx:nginx /data/web -R
# 引用其他文件的权限设置
chown --reference=/etc/nginx/nginx.conf /data/web/nginx.confchattr 文件属性
# 设置文件不可修改(即使是root也不能修改)
chattr +i /etc/resolv.conf
# 查看文件属性
lsattr /etc/resolv.conf
# 移除不可修改属性
chattr -i /etc/resolv.conf
# 设置文件只能追加内容
chattr +a /var/log/secure
# 设置目录下新建文件自动压缩
chattr +c /data/archives
# 设置文件删除时安全擦除
chattr +s /data/secret.key用户密码策略
密码复杂度与过期策略
# 查看当前密码策略
cat /etc/login.defs | grep -E "PASS_MAX|PASS_MIN|PASS_WARN"
# 修改密码过期策略(影响新创建的用户)
# /etc/login.defs 关键参数:
PASS_MAX_DAYS 90 # 密码最长使用天数
PASS_MIN_DAYS 0 # 密码最短使用天数(0 表示可以随时改)
PASS_MIN_LEN 8 # 密码最小长度
PASS_WARN_AGE 7 # 密码过期前几天开始警告
UID_MIN 1000 # 普通用户 UID 起始值
UID_MAX 60000 # 普通用户 UID 最大值
# 查看用户密码状态
chage -l zhangsan
# 修改用户密码策略
chage -M 90 zhangsan # 密码有效期 90 天
chage -m 7 zhangsan # 两次修改密码的最小间隔 7 天
chage -W 14 zhangsan # 过期前 14 天开始警告
chage -I 30 zhangsan # 过期后 30 天账号被锁定
chage -E 2025-12-31 zhangsan # 账号到期日
chage -d 0 zhangsan # 强制下次登录时修改密码
# 批量设置用户密码过期
for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do
chage -M 90 -W 14 -I 30 $user
done
# 查找永不过期的用户(安全隐患)
awk -F: '($5 == "" || $5 == "99999" || $5 == "never") {print $1, $5}' /etc/shadow安装并配置 pam_pwquality
# 安装 pam_pwquality(替代已废弃的 pam_cracklib)
yum install -y libpwquality
# 配置密码复杂度规则
cat > /etc/security/pwquality.conf << 'EOF'
# 密码最小长度
minlen = 12
# 最少包含几类字符(大写、小写、数字、特殊字符)
minclass = 3
# 最少包含几个大写字母
ucredit = -1
# 最少包含几个小写字母
lcredit = -1
# 最少包含几个数字
dcredit = -1
# 最少包含几个特殊字符
ocredit = -1
# 新密码与旧密码最多允许几个字符相同
difok = 5
# 密码中允许的最大连续相同字符数
maxrepeat = 3
# 密码中允许的最大单调字符序列长度(如 1234, abcd)
maxsequence = 3
# 检查密码是否包含用户名
usercheck = 1
# 检查密码是否包含字典中的常见单词
dictcheck = 1
# 密码复杂度评分阈值(越高越复杂)
enforcing = 1
# 新旧密码至少有几个字符不同
# 密码重试次数
retry = 3
EOF登录失败锁定策略
# /etc/pam.d/system-auth 中配置登录失败锁定
# 在 auth 模块中添加(CentOS 7):
auth required pam_faillock.so preauth silent audit deny=5 unlock_time=1800
auth sufficient pam_unix.so nullok
auth [default=die] pam_faillock.so authfail audit deny=5 unlock_time=1800
auth required pam_faillock.so sofar
# 在 account 模块中添加:
account required pam_faillock.so
# 查看用户的登录失败记录
faillock --user zhangsan
# 手动解锁用户
faillock --user zhangsan --reset
# 查看所有被锁定的用户
faillock
# 配置说明:
# deny=5 — 连续失败 5 次后锁定
# unlock_time=1800 — 锁定 1800 秒(30分钟)
# unlock_time=0 — 永久锁定,需要管理员手动解锁用户审计与安全
登录审计
# 查看当前登录用户
who
w # 更详细信息,包括在执行的命令
uptime # 系统负载和登录用户数
# 查看登录历史
last # 成功登录记录
last -f /var/log/btmp # 失败登录记录
last -10 zhangsan # 指定用户的最近 10 次登录
# 查看失败登录尝试
lastb | head -20
cat /var/log/btmp | lastb | awk '{print $3}' | sort | uniq -c | sort -rn | head
# 实时监控登录事件
tail -f /var/log/secure | grep -E "session opened|session closed|Failed password"
# 查看 SSH 登录情况
journalctl -u sshd --since "today" | grep -E "Accepted|Failed|Invalid"用户操作审计
# 使用 auditd 审计用户特权操作
yum install -y audit
# 监控 sudo 命令执行
auditctl -w /usr/bin/sudo -p x -k sudo-usage
# 监控关键文件的修改
auditctl -w /etc/passwd -p wa -k passwd-changes
auditctl -w /etc/shadow -p wa -k shadow-changes
auditctl -w /etc/sudoers -p wa -k sudoers-changes
auditctl -w /etc/ssh/sshd_config -p wa -k sshd-config-changes
# 监控用户切换操作
auditctl -w /var/run/utmp -p wa -k session-activity
# 查看审计日志
ausearch -k sudo-usage --interpret
ausearch -k passwd-changes --interpret
ausearch -m USER_LOGIN -sv no
# 生成审计报告
aureport -x # 可执行文件报告
aureport -au # 审计事件摘要
aureport -m # 按类型分类的报告
aureport -l # 登录报告
aureport -f # 文件访问报告使用 pam_tally2 / faillock 锁定策略
# CentOS 6 使用 pam_tally2
# 查看登录失败次数
pam_tally2 --user zhangsan
# 重置失败计数
pam_tally2 --user zhangsan --reset
# 在 /etc/pam.d/system-auth 中配置
# auth required pam_tally2.so deny=5 unlock_time=1800 even_deny_root root_unlock_time=60
# even_deny_root — 对 root 也生效
# root_unlock_time — root 的锁定时间(秒)用户生命周期管理
批量用户管理脚本
#!/bin/bash
# batch_user_manage.sh — 批量用户管理
# 批量创建用户
create_users() {
local group=$1
shift
for user in "$@"; do
if id "$user" &>/dev/null; then
echo "用户 $user 已存在,跳过"
continue
fi
useradd -m -s /bin/bash -G "$group" "$user"
echo "${user}:$(openssl rand -base64 12)" | chpasswd
chage -d 0 "$user" # 首次登录强制改密码
echo "创建用户 $user 成功"
done
}
# 批量删除用户
delete_users() {
for user in "$@"; do
if ! id "$user" &>/dev/null; then
echo "用户 $user 不存在,跳过"
continue
fi
userdel -r "$user" 2>/dev/null
echo "删除用户 $user 成功"
done
}
# 查找过期用户
find_expired_users() {
echo "=== 已过期用户 ==="
while IFS=: read -r user _; do
status=$(chage -l "$user" 2>/dev/null | grep "Account expires" | awk -F: '{print $2}' | tr -d ' ')
if [[ "$status" != "never" ]] && [[ -n "$status" ]]; then
expire_date=$(date -d "$status" +%s 2>/dev/null)
now=$(date +%s)
if [[ "$expire_date" -lt "$now" ]]; then
echo "$user — 过期于 $status"
fi
fi
done < /etc/passwd
}
# 查找空闲用户(超过 90 天未登录)
find_idle_users() {
echo "=== 超过 90 天未登录的用户 ==="
for user in $(awk -F: '$3 >= 1000 && $7 != "/sbin/nologin" {print $1}' /etc/passwd); do
last_login=$(lastlog -u "$user" -t 90 | grep -v "Never" | tail -1)
if [[ -z "$last_login" ]]; then
echo "$user — 超过 90 天未登录"
fi
done
}用户目录权限初始化
# 设置用户家目录默认权限
# /etc/login.defs
UMASK 027
# 创建用户后初始化家目录结构
setup_homedir() {
local user=$1
local home=$(eval echo "~$user")
mkdir -p $home/{.ssh,.config,logs,scripts,data}
# 设置目录权限
chmod 700 $home/.ssh
chmod 755 $home/{.config,logs,scripts}
chmod 700 $home/data
# 创建 .bashrc 自定义配置
cat >> $home/.bashrc << 'BASHRC'
# 自定义别名
alias ll='ls -alF --color=auto'
alias grep='grep --color=auto'
alias cls='clear'
alias h='history | tail -20'
# 历史记录配置
export HISTSIZE=10000
export HISTFILESIZE=20000
export HISTTIMEFORMAT='%F %T '
export HISTCONTROL=ignoredups:ignorespace
shopt -s histappend
# 安全:不允许覆盖已有文件
set -o noclobber
BASHRC
chown -R $user:$user $home
echo "家目录初始化完成: $home"
}系统用户与特殊账户
系统内置用户说明
# 查看系统用户(UID < 1000)
awk -F: '$3 < 1000 {printf "%-20s UID=%-6s Shell=%s\n", $1, $3, $7}' /etc/passwd
# 常见系统用户及用途:
# root UID=0 超级管理员
# bin UID=1 系统命令文件属主
# daemon UID=2 系统守护进程
# adm UID=3 系统日志查看
# lp UID=4 打印服务
# mail UID=8 邮件服务
# nobody UID=65534 NFS 匿名访问
# sshd UID=74 SSH 服务
# nginx UID=997 Nginx 服务
# mysql UID=27 MySQL 服务
# redis UID=998 Redis 服务
# 查看可登录的系统用户(安全隐患)
awk -F: '$3 < 1000 && $7 !~ /nologin|false|sync|halt|shutdown/ {print $1, $7}' /etc/passwdnsswitch 与用户解析顺序
# 用户解析顺序配置
cat /etc/nsswitch.conf | grep passwd
# passwd: files sss
# 解析顺序说明:
# files — 本地 /etc/passwd
# sss — SSSD(LDAP/AD 集成)
# ldap — 直接 LDAP 查询
# nis — NIS/YP
# 验证用户解析结果
getent passwd zhangsan # 查询所有来源
getent passwd zhangsan@LDAP_DOMAIN # 指定 LDAP 域查询
# 查看当前系统的认证来源
authconfig --test 2>/dev/null | grep -E "nss|pam"Sudo 安全加固
Sudoers 高级配置
# visudo 编辑,使用 @include 引入独立配置文件
# /etc/sudoers.d/ 目录下的文件会被自动加载
# 创建按用户分组的 sudo 配置
cat > /etc/sudoers.d/developers << 'EOF'
# 开发人员 — 只允许管理应用服务
Cmnd_Alias APP_CMDS = /usr/bin/systemctl restart app-*, /usr/bin/systemctl status app-*, \
/usr/bin/docker restart app-*, /usr/bin/docker logs app-*, \
/usr/bin/tail -f /var/log/app/*.log
%developers ALL=(root) APP_CMDS
EOF
# 运维人员 — 允许更多系统管理命令
cat > /etc/sudoers.d/ops << 'EOF'
Cmnd_Alias SYS_CMDS = /usr/bin/systemctl, /usr/bin/journalctl, /usr/bin/firewall-cmd, \
/usr/bin/docker, /usr/bin/docker-compose, /usr/bin/netstat, \
/usr/bin/ss, /usr/bin/ip
Cmnd_Alias PKG_CMDS = /usr/bin/yum, /usr/bin/rpm, /usr/bin/dnf
%ops ALL=(root) SYS_CMDS, PKG_CMDS
EOF
# 设置权限:
chmod 440 /etc/sudoers.d/developers
chmod 440 /etc/sudoers.d/ops
# Sudo 日志增强 — 记录完整的命令和会话
cat > /etc/sudoers.d/logging << 'EOF'
# 记录 sudo 命令的输入输出
Defaults log_input, log_output
Defaults logfile="/var/log/sudo-io/%{user}/%{tty}/%{year}%{month}%{day}%{hour}%{minute}%{second}"
Defaults iolog_dir="/var/log/sudo-io"
# 记录每次 sudo 执行的命令
Defaults syslog=auth
Defaults log_host, log_year
EOF
# 查看 sudo 会话记录
sudo -l
journalctl -t sudo
ls -la /var/log/sudo-io/Sudo 常见安全陷阱
# 陷阱 1:允许用户编辑任意文件
# 危险写法:devuser ALL=(ALL) /usr/bin/vi
# 用户可以通过 vi 的 :!command 执行任意命令
# 安全替代:
devuser ALL=(ALL) /usr/bin/vi /etc/myapp/*.conf
# 陷阱 2:允许 sudo su
# 危险写法:devuser ALL=(ALL) /usr/bin/su
# 等同于给予 root 权限
# 安全替代:使用 sudo -i 并配合命令白名单
# 陷阱 3:通配符滥用
# 危险写法:devuser ALL=(ALL) /usr/bin/systemctl *
# 安全替代:精确指定服务名
devuser ALL=(ALL) /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart redis
# 检查当前 sudoers 配置中的安全隐患
visudo -cACL 访问控制
ACL 配置与管理
# 查看文件的ACL设置
getfacl /data/project
# 给用户添加读写执行权限
setfacl -m u:zhangsan:rwx /data/project
# 给用户组添加只读权限
setfacl -m g:developers:rx /data/project
# 设置默认ACL(新建文件自动继承权限)
setfacl -d -m u:zhangsan:rwx /data/project
# 移除指定用户的ACL
setfacl -x u:zhangsan /data/project
# 清除所有ACL设置
setfacl -b /data/project
# 递归设置ACL
setfacl -R -m u:devuser:rwx /data/project
# 备份和恢复ACL
getfacl -R /data/project > /root/acl_backup.txt
setfacl --restore=/root/acl_backup.txt优点
缺点
总结
用户与权限管理是保障 Linux 系统安全的基石。通过合理规划用户和用户组、严格配置 sudo 提权规则、正确设置文件权限和 ACL,可以构建起完善的安全防护体系。建议遵循最小权限原则,定期审计用户账号和权限配置,及时清理无用账号,确保系统安全性始终处于可控状态。
关键知识点
- 部署类主题的核心不是“装成功”,而是“稳定运行、可排障、可回滚”。
- 同一个服务通常至少要关注版本、目录、端口、权限、数据、日志和备份。
- Linux 问题经常跨越系统层、网络层、服务层和应用层。
项目落地视角
- 把安装步骤补成可重复执行的清单,必要时写成脚本或配置文件。
- 把配置目录、数据目录、日志目录和挂载点明确拆开。
- 上线前检查防火墙、SELinux、时区、磁盘、系统服务和健康检查。
常见误区
- 使用 latest 或未固定版本,导致环境不可复现。
- 只验证启动成功,不验证持久化、开机自启和故障恢复。
- 遇到问题先改配置而不是先看日志和依赖链路。
进阶路线
- 继续补齐 systemd、性能监控、安全加固和备份恢复。
- 把单机操作升级成 Docker、Kubernetes 或 IaC 方案。
- 建立标准化运维手册,包括巡检、扩容、回滚和灾备演练。
适用场景
- 当你准备把《用户与权限管理》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合单机环境初始化、中间件快速搭建、测试环境验证和生产部署前准备。
- 当服务稳定性依赖端口、权限、目录、网络和系统参数时,这类主题会直接影响成败。
落地建议
- 固定版本号与镜像标签,避免“latest”带来的不可预期变化。
- 把配置、数据、日志目录拆开管理,并记录恢复步骤。
- 上线前确认端口、防火墙、SELinux、时区和磁盘空间。
排错清单
- 先查 systemctl、容器日志和应用日志,确认失败发生在哪一层。
- 检查端口占用、目录权限、挂载路径和网络连通性。
- 如果是新环境问题,优先对比与已知正常环境的差异。
复盘问题
- 如果把《用户与权限管理》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《用户与权限管理》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《用户与权限管理》最大的收益和代价分别是什么?
