关于 user-management
面向 Linux 管理员的用户与访问管理实践指南,提供账户、组、sudo、PAM、LDAP 集成及批量操作和审计方法。
主要功能
- 01创建、修改和删除用户账户
- 02管理组与文件权限
- 03配置细粒度 sudo 权限
- 04设置 PAM 密码策略
- 05集成 LDAP 或 Active Directory
- 06批量配置用户并审计访问
适用场景
- 01为 Linux 服务器团队配置用户和组
- 02按命令或服务限制 sudo 权限
- 03将主机接入集中身份认证
- 04批量开通账户并检查访问权限
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill user-management安装后在 Claude Code 中输入/user-management确认已加载。
详细介绍
用户管理
在 Linux 系统上管理用户、组、权限、sudo 访问、PAM 模块和 LDAP 集成。包含用于批量用户操作和访问审计的实用脚本。
适用场景
- 在 Linux 服务器上创建和管理本地用户帐户
- 配置具有精细权限控制的 sudo 访问
- 为团队设置基于组的访问控制
- 将 Linux 主机与 LDAP 或 Active Directory 集成,以实现集中式身份验证
- 审计用户帐户、权限和访问模式
- 自动化批量用户的开通和撤销
前提条件
- 目标系统上的 root 或 sudo 访问权限
shadow-utils软件包(提供 useradd、usermod 等命令)——默认已安装- 用于 PAM 配置的
libpam-modules - LDAP 所需的软件包:
sssd、realmd、libpam-ldapd或nslcd - 用于审计的
auditd软件包
用户操作
创建用户
# Create a user with home directory, default shell, and comment
useradd -m -s /bin/bash -c "Jane Smith" jsmith
# Set the user's password interactively
passwd jsmith
# Create a user with a specific UID and primary group
useradd -m -s /bin/bash -u 1500 -g developers -c "Deploy Account" deploy
# Create a system account (no home, no login shell) for running services
useradd -r -s /usr/sbin/nologin -d /opt/myapp -c "MyApp Service Account" myapp
# Create a user with an expiration date (contractor access)
useradd -m -s /bin/bash -e 2025-12-31 -c "Contractor - Bob Lee" blee
# Create user and add to multiple supplementary groups at creation time
useradd -m -s /bin/bash -G docker,developers,ssh-users -c "Dev User" devuser
修改用户
# Add a user to a supplementary group (preserving existing groups with -a)
usermod -aG sudo jsmith
usermod -aG docker,developers jsmith
# Change the user's login shell
usermod -s /bin/zsh jsmith
# Change the user's home directory and move existing files
usermod -d /home/jsmith-new -m jsmith
# Lock a user account (disable login without deleting)
usermod -L jsmith
# Unlock a user account
usermod -U jsmith
# Set an account expiration date
usermod -e 2025-06-30 blee
# Change a user's login name
usermod -l jsmith-new jsmith
# Force password change on next login
chage -d 0 jsmith
# Set password aging: min 7 days, max 90 days, warn 14 days before
chage -m 7 -M 90 -W 14 jsmith
# View password aging info
chage -l jsmith
删除用户
# Remove a user and their home directory
userdel -r jsmith
# Remove a user but keep their home directory (for auditing)
userdel jsmith
# Find and reassign files owned by a deleted user (by UID)
find / -uid 1500 -exec chown newowner:newgroup {} \;
组管理
# Create a new group
groupadd developers
# Create a group with a specific GID
groupadd -g 2000 devops
# Add a user to a group
usermod -aG developers jsmith
# Alternative using gpasswd
gpasswd -a jsmith developers
# Remove a user from a group
gpasswd -d jsmith developers
# Set group administrators (can add/remove members without root)
gpasswd -A jsmith developers
# Delete a group
groupdel developers
# List all groups a user belongs to
groups jsmith
id jsmith
# List all members of a group
getent group developers
# Show all groups on the system
cat /etc/group | cut -d: -f1 | sort
Sudo 配置
# Always edit sudoers via visudo (syntax validation prevents lockout)
visudo
# Better: use drop-in files in /etc/sudoers.d/
visudo -f /etc/sudoers.d/developers
/etc/sudoers.d/developers
# Allow the developers group to restart specific services
%developers ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/systemctl status myapp
# Allow a deploy user full sudo with no password
deploy ALL=(ALL) NOPASSWD: ALL
# Allow ops team to run docker commands only
%ops ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/docker-compose
# Allow a user to run commands as a specific service account
jsmith ALL=(myapp) NOPASSWD: /opt/myapp/bin/*
# Restrict to specific hosts (useful with centralized sudoers)
jsmith dbservers=(root) /usr/bin/systemctl restart postgresql
# Log all sudo commands to a dedicated file
Defaults log_output
Defaults!/usr/bin/sudoreplay !log_output
Defaults logfile="/var/log/sudo.log"
# Require password re-entry every 5 minutes (default is 15)
Defaults timestamp_timeout=5
# Require password for sudo even if user has NOPASSWD elsewhere
Defaults:jsmith !authenticate
# Validate sudoers syntax without applying
visudo -c
# Check what sudo permissions a user has
sudo -l -U jsmith
# Test a specific sudo command as a user
sudo -u myapp /opt/myapp/bin/healthcheck.sh
文件权限和 ACL
# Standard permissions
chmod 755 /opt/myapp # rwxr-xr-x
chmod 640 /etc/myapp.conf # rw-r-----
chmod u+x script.sh # Add execute for owner
chmod g+w shared-dir/ # Add write for group
chmod o-rwx private-file # Remove all permissions for others
# Change ownership
chown deploy:developers /opt/myapp
chown -R deploy:developers /opt/myapp/ # Recursive
# Set the SGID bit (new files inherit group ownership)
chmod g+s /opt/shared/
# Set the sticky bit (only owner can delete their files)
chmod +t /tmp/shared/
# Access Control Lists (ACLs) for fine-grained control
# Grant read-execute to a specific user on a directory
setfacl -m u:jsmith:rx /opt/myapp/logs/
# Grant read-write to a group
setfacl -m g:developers:rw /opt/shared/
# Set default ACL (applied to new files created in the directory)
setfacl -d -m g:developers:rw /opt/shared/
# View ACLs
getfacl /opt/shared/
# Remove a specific ACL entry
setfacl -x u:jsmith /opt/myapp/logs/
# Remove all ACLs
setfacl -b /opt/shared/
PAM 配置
# PAM config files are in /etc/pam.d/
# Each file controls auth for a specific service (sshd, login, sudo, etc.)
# Enforce password complexity via pam_pwquality
# /etc/pam.d/common-password (Debian) or /etc/pam.d/system-auth (RHEL)
password requisite pam_pwquality.so retry=3 minlen=12 dcredit=-1 ucredit=-1 ocredit=-1 lcredit=-1
# Configure /etc/security/pwquality.conf
minlen = 12
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
maxrepeat = 3
dictcheck = 1
# Limit concurrent logins per user
# /etc/security/limits.conf
jsmith hard maxlogins 3
@developers hard maxlogins 5
# Lock account after 5 failed login attempts
# /etc/pam.d/common-auth (Debian)
auth required pam_faillock.so preauth silent deny=5 unlock_time=900
auth required pam_faillock.so authfail deny=5 unlock_time=900
# View failed login attempts
faillock --user jsmith
# Unlock a locked account
faillock --user jsmith --reset
LDAP / Active Directory 集成
# Install SSSD and realmd for AD integration (Ubuntu/Debian)
apt install -y sssd realmd adcli sssd-tools libnss-sss libpam-sss
# Install SSSD and realmd (RHEL/CentOS)
dnf install -y sssd realmd adcli sssd-tools oddjob oddjob-mkhomedir
# Discover and join an Active Directory domain
realm discover corp.example.com
realm join corp.example.com -U [email protected]
# Verify the join
realm list
# Allow specific AD groups to log in
realm permit -g "Linux [email protected]"
realm permit -g "[email protected]"
# Deny all except permitted groups
realm deny --all
realm permit -g "Linux [email protected]"
# Restart SSSD after config changes
systemctl restart sssd
# Test LDAP user lookup
id jsmith
getent passwd jsmith
# Grant sudo to an AD group
echo '%linux\ admins ALL=(ALL) ALL' > /etc/sudoers.d/ad-admins
批量用户管理脚本
从 CSV 批量创建用户
#!/bin/bash
# bulk-create-users.sh
# CSV format: username,fullname,groups,shell
# Example: jsmith,Jane Smith,developers;docker,/bin/bash
CSV_FILE="${1:?Usage: $0 <users.csv>}"
while IFS=',' read -r username fullname groups shell; do
# Skip header line
[[ "$username" == "username" ]] && continue
if id "$username" &>/dev/null; then
echo "SKIP: User $username already exists"
continue
fi
# Replace semicolons with commas for -G flag
group_list="${groups//;/,}"
useradd -m -s "$shell" -c "$fullname" -G "$group_list" "$username"
# Generate a random temporary password
temp_pass=$(openssl rand -base64 12)
echo "$username:$temp_pass" | chpasswd
chage -d 0 "$username" # Force password change at first login
echo "CREATED: $username (groups: $group_list) temp-pass: $temp_pass"
done < "$CSV_FILE"
快速访问审计命令
# List non-system users (UID >= 1000)
awk -F: '$3 >= 1000 && $3 < 65534 { printf "%-20s UID=%-6s Shell=%s\n", $1, $3, $7 }' /etc/passwd
# List users with sudo access
getent group sudo wheel 2>/dev/null
# Find accounts that have never logged in
lastlog | awk '$0 ~ /Never logged in/ { print $1 }'
# Find accounts with empty passwords
awk -F: '($2 == "" || $2 == "!") { print $1 }' /etc/shadow 2>/dev/null
故障排查
| 症状 | 诊断命令 | 常见修复方法 |
|---|---|---|
| 用户无法登录 | passwd -S username、faillock --user username | 解锁帐户、重置密码、检查 shell |
| 出现“not in sudoers”错误 | sudo -l -U username | 将用户添加到 sudo 组或创建 sudoers.d 文件 |
| 组成员身份未生效 | id username、groups username | 用户必须注销并重新登录,新组才会生效 |
| 找不到 LDAP/AD 用户 | id aduser、sssctl user-show aduser | 检查 SSSD 状态,清除缓存:sss_cache -E |
| 无权访问文件 | ls -la file、getfacl file | 修正所有权和权限,检查 SELinux 上下文 |
| 多次尝试失败后被 PAM 锁定 | faillock --user username | faillock --user username --reset |
| 未创建主目录 | 检查 /etc/login.defs 中的 CREATEHOME | 使用 useradd -m 或启用 pam_mkhomedir |
| 密码策略未生效 | 检查 /etc/pam.d/common-password | 安装并配置 pam_pwquality |
相关技能
linux-administration-- Linux 服务器常规管理ssh-configuration-- 为受管理用户配置基于 SSH 密钥的身份验证systemd-services-- 服务帐户和 systemd 用户实例performance-tuning-- 通过 cgroups 和 ulimits 设置每用户资源限制
评论
支持 Markdown