useradd 是一个用于在Linux系统中创建新用户账户的核心命令。它是系统管理员最常用的工具之一,可以创建用户账户、设置用户属性、创建家目录,并配置用户的登录环境。
passwd命令为用户设置密码。
useradd [选项] 用户名
或者查看默认配置:
useradd -D [选项]
| 选项 | 说明 |
|---|---|
-c, --comment COMMENT |
用户的备注信息(通常为全名) |
-d, --home-dir HOME_DIR |
指定用户家目录 |
-e, --expiredate EXPIRE_DATE |
设置账户过期日期(YYYY-MM-DD) |
-f, --inactive INACTIVE |
密码过期后账户被禁用的天数 |
-g, --gid GROUP |
指定用户的主组名或GID |
-G, --groups GROUPS |
指定用户的附加组列表(逗号分隔) |
-m, --create-home |
创建用户家目录(默认在某些系统上不创建) |
-M, --no-create-home |
不创建用户家目录 |
-N, --no-user-group |
不创建与用户同名的组 |
-o, --non-unique |
允许创建重复UID的用户 |
-p, --password PASSWORD |
使用加密密码(不推荐,有安全隐患) |
-r, --system |
创建系统用户(UID < 1000) |
-s, --shell SHELL |
指定用户登录shell |
-u, --uid UID |
指定用户的UID |
-U, --user-group |
创建与用户同名的组(默认行为) |
-k, --skel SKEL_DIR |
指定skeleton目录(包含默认配置文件) |
-D, --defaults |
显示或修改默认值 |
--help |
显示帮助信息 |
# 创建一个名为john的用户
sudo useradd john
# 创建后为用户设置密码
sudo passwd john
# 验证用户是否创建
id john
grep john /etc/passwd
# 创建用户并自动创建家目录
sudo useradd -m john
# 创建用户并指定自定义家目录
sudo useradd -m -d /home/john_doe john
# 创建用户但不创建家目录
sudo useradd -M john
# 创建用户并指定全名、shell、主组
sudo useradd -c "John Doe" -s /bin/bash -g users john
# 创建用户并指定UID和GID
sudo useradd -u 1001 -g 100 john
# 创建用户并添加到附加组
sudo useradd -G wheel,developers,adm john
# 创建系统用户(UID < 1000)
sudo useradd -r systemuser
# 创建系统用户并指定shell
sudo useradd -r -s /sbin/nologin daemonuser
# 验证系统用户
id systemuser
# 系统用户的UID通常小于1000
# 创建账户在2024-12-31过期的用户
sudo useradd -e 2024-12-31 tempuser
# 创建密码30天后过期的用户
sudo useradd -f 30 john
# 查看账户过期信息
sudo chage -l tempuser
useradd的默认配置文件:
# 查看useradd默认配置
sudo useradd -D
# 或直接查看配置文件
cat /etc/default/useradd
配置文件示例:
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
用户创建的全局默认值:
# 查看登录默认配置
grep -E '^PASS_|^UID_|^GID_|^CREATE_HOME' /etc/login.defs
重要配置项:
# 密码过期配置
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_WARN_AGE 7
# UID/GID范围
UID_MIN 1000
UID_MAX 60000
SYS_UID_MIN 201
SYS_UID_MAX 999
GID_MIN 1000
GID_MAX 60000
SYS_GID_MIN 201
SYS_GID_MAX 999
# 是否创建家目录
CREATE_HOME yes
# 家目录权限
UMASK 077
skeleton目录包含创建用户家目录时的默认文件:
# 查看skeleton目录内容
ls -la /etc/skel/
# 常见的默认文件
.bash_logout
.bash_profile
.bashrc
.profile
可以自定义skeleton目录:
# 创建自定义skeleton目录
sudo mkdir -p /etc/skel_custom
sudo cp /etc/skel/.bashrc /etc/skel_custom/
sudo cp /etc/skel/.profile /etc/skel_custom/
# 添加自定义配置文件
sudo echo "alias ll='ls -la'" >> /etc/skel_custom/.bashrc
# 使用自定义skeleton创建用户
sudo useradd -m -k /etc/skel_custom/ newuser
用户账户信息存储在/etc/passwd文件中:
# 查看用户信息
grep john /etc/passwd
# 格式:用户名:密码占位符:UID:GID:GECOS:家目录:登录shell
# 示例:john:x:1001:1001:John Doe:/home/john:/bin/bash
加密密码和账户过期信息存储在/etc/shadow文件中:
# 查看用户密码信息(需要root权限)
sudo grep john /etc/shadow
# 格式:用户名:加密密码:最后修改:最小天数:最大天数:警告期:不活动期:过期日期:保留字段
组信息存储在/etc/group文件中:
# 查看组信息
grep john /etc/group
# 格式:组名:密码占位符:GID:成员列表
#!/bin/bash
# batch_create_users.sh - 批量创建用户
# 用户列表文件格式:用户名,全名,主组,附加组,shell
USER_LIST="user_list.csv"
DEFAULT_PASSWORD="Chang3Me!"
echo "开始批量创建用户..."
echo "用户列表文件: $USER_LIST"
echo ""
# 读取用户列表
while IFS=, read -r USERNAME FULL_NAME PRIMARY_GROUP SECONDARY_GROUPS SHELL; do
# 跳过注释行和空行
[[ "$USERNAME" =~ ^# ]] && continue
[[ -z "$USERNAME" ]] && continue
echo "创建用户: $USERNAME"
echo " 全名: $FULL_NAME"
echo " 主组: $PRIMARY_GROUP"
echo " 附加组: $SECONDARY_GROUPS"
echo " Shell: $SHELL"
# 构建useradd命令
CMD="sudo useradd -m"
CMD="$CMD -c \"$FULL_NAME\""
CMD="$CMD -s $SHELL"
if [ -n "$PRIMARY_GROUP" ]; then
CMD="$CMD -g $PRIMARY_GROUP"
fi
if [ -n "$SECONDARY_GROUPS" ]; then
CMD="$CMD -G $SECONDARY_GROUPS"
fi
CMD="$CMD $USERNAME"
# 执行创建命令
echo " 执行: $CMD"
eval $CMD
if [ $? -eq 0 ]; then
# 设置初始密码
echo "$USERNAME:$DEFAULT_PASSWORD" | sudo chpasswd
# 强制首次登录时修改密码
sudo passwd -e $USERNAME
echo " ✓ 用户 $USERNAME 创建成功"
else
echo " ✗ 用户 $USERNAME 创建失败"
fi
echo ""
done < "$USER_LIST"
echo "批量用户创建完成"
用户列表文件示例(user_list.csv):
# 用户名,全名,主组,附加组,shell
john,John Doe,users,wheel,sudo,/bin/bash
jane,Jane Smith,developers,adm,docker,/bin/bash
bob,Bob Johnson,users,,/bin/sh
alice,Alice Williams,developers,docker,/bin/zsh
#!/bin/bash
# create_web_user.sh - 创建Web服务器专用用户
USERNAME="webadmin"
WEB_ROOT="/var/www/html"
SERVICE_NAME="nginx"
echo "创建Web服务器用户: $USERNAME"
echo "Web根目录: $WEB_ROOT"
echo ""
# 创建系统用户,不允许登录
sudo useradd -r -s /sbin/nologin -d $WEB_ROOT $USERNAME
if [ $? -ne 0 ]; then
echo "用户创建失败"
exit 1
fi
echo "用户创建成功"
# 设置目录权限
sudo mkdir -p $WEB_ROOT
sudo chown -R $USERNAME:$USERNAME $WEB_ROOT
sudo chmod 755 $WEB_ROOT
# 创建日志目录
sudo mkdir -p /var/log/$USERNAME
sudo chown -R $USERNAME:$USERNAME /var/log/$USERNAME
# 如果使用nginx,配置运行用户
if [ "$SERVICE_NAME" = "nginx" ]; then
echo "配置nginx以用户 $USERNAME 运行"
sudo sed -i "s/^user .*/user $USERNAME;/" /etc/nginx/nginx.conf
sudo systemctl restart nginx
fi
echo ""
echo "Web用户配置完成"
echo "用户名: $USERNAME"
echo "家目录: $WEB_ROOT"
echo "Shell: /sbin/nologin (不允许登录)"
echo "用户ID: $(id -u $USERNAME)"
echo "组ID: $(id -g $USERNAME)"
#!/bin/bash
# create_developer.sh - 创建开发者用户
USERNAME="$1"
if [ -z "$USERNAME" ]; then
echo "用法: $0 用户名"
exit 1
fi
echo "创建开发者用户: $USERNAME"
echo ""
# 创建用户和家目录
sudo useradd -m -s /bin/bash -c "Developer Account" $USERNAME
# 设置初始密码
echo "设置初始密码..."
sudo passwd $USERNAME
# 创建开发目录
DEV_DIR="/home/$USERNAME/development"
sudo mkdir -p $DEV_DIR
sudo chown $USERNAME:$USERNAME $DEV_DIR
# 设置sudo权限
echo "配置sudo权限..."
echo "$USERNAME ALL=(ALL) NOPASSWD: /usr/bin/apt-get, /usr/bin/yum, /usr/bin/dnf" | sudo tee /etc/sudoers.d/$USERNAME
sudo chmod 440 /etc/sudoers.d/$USERNAME
# 配置bash环境
BASHRC="/home/$USERNAME/.bashrc"
sudo cat >> $BASHRC << 'EOF'
# 开发环境配置
export EDITOR=vim
export PATH="$HOME/.local/bin:$PATH"
# 别名
alias gs="git status"
alias gp="git pull"
alias gcm="git commit -m"
alias dockerps="docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'"
# 提示符
export PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
EOF
# 设置所有权
sudo chown $USERNAME:$USERNAME $BASHRC
echo ""
echo "开发者用户 $USERNAME 创建完成"
echo "家目录: /home/$USERNAME"
echo "开发目录: $DEV_DIR"
echo "已配置sudo权限和开发环境"
#!/bin/bash
# create_temporary_user.sh - 创建临时用户
USERNAME="temp_$(date +%Y%m%d_%H%M%S)"
EXPIRE_DATE=$(date -d "+30 days" +%Y-%m-%d)
PASSWORD=$(openssl rand -base64 12)
echo "创建临时用户..."
echo "用户名: $USERNAME"
echo "过期日期: $EXPIRE_DATE"
echo "初始密码: $PASSWORD"
echo ""
# 创建用户
sudo useradd -m -e $EXPIRE_DATE -c "Temporary Account" -s /bin/bash $USERNAME
# 设置密码
echo "$USERNAME:$PASSWORD" | sudo chpasswd
# 强制首次登录修改密码
sudo passwd -e $USERNAME
# 记录到日志
echo "$(date) - 创建临时用户: $USERNAME, 过期: $EXPIRE_DATE" >> /var/log/temp_users.log
echo "临时用户创建完成"
echo ""
echo "======================================"
echo "用户名: $USERNAME"
echo "密码: $PASSWORD"
echo "过期日期: $EXPIRE_DATE"
echo "请立即登录并修改密码"
echo "======================================"
passwd命令设置强密码,或强制首次登录修改/sbin/nologin或/bin/falseuseradd: user 'john' already exists
解决方案:
# 检查用户是否存在
id john
grep john /etc/passwd
# 如果要删除已存在用户重新创建
sudo userdel -r john
sudo useradd john
useradd: group 'developers' does not exist
解决方案:
# 先创建组
sudo groupadd developers
# 或使用现有组
sudo useradd -g users john
# 查看可用组
getent group
useradd: Permission denied.
useradd: cannot lock /etc/passwd; try again later.
解决方案:
# 使用sudo执行
sudo useradd john
# 检查文件权限
ls -l /etc/passwd
# 应该显示 -rw-r--r--
# 检查是否有其他进程锁定文件
sudo lsof /etc/passwd
useradd: UID 1001 is not unique
解决方案:
# 使用-o选项允许重复UID(不推荐)
sudo useradd -o -u 1001 john
# 或指定不同的UID
sudo useradd -u 1002 john
# 查看已使用的UID
cut -d: -f3 /etc/passwd | sort -n
useradd: cannot create directory /home/john
解决方案:
# 检查/home目录权限
ls -ld /home
# 确保有写权限
sudo chmod 755 /home
# 或指定其他目录
sudo useradd -m -d /opt/home/john john
# 手动创建家目录
sudo mkdir /home/john
sudo cp -r /etc/skel/. /home/john
sudo chown -R john:john /home/john
| 命令 | 说明 |
|---|---|
adduser |
交互式的用户创建工具(在某些发行版中是useradd的友好前端) |
usermod |
修改用户账户属性 |
userdel |
删除用户账户 |
passwd |
设置或修改用户密码 |
chage |
更改用户密码过期信息 |
groupadd |
创建新组 |
id |
显示用户身份信息 |
su |
切换用户身份 |
sudo |
以其他用户身份执行命令 |
vipw |
安全编辑/etc/passwd文件 |
-p选项在命令行中指定密码last、who等命令监控用户登录/etc/passwd、/etc/shadow、/etc/sudoers等文件权限正确# 查看当前默认值
sudo useradd -D
# 修改默认shell
sudo useradd -D -s /bin/zsh
# 修改默认家目录位置
sudo useradd -D -b /opt/home
# 修改默认skeleton目录
sudo useradd -D -k /etc/skel_custom/
# 修改默认组
sudo useradd -D -g users
#!/bin/bash
# migrate_user.sh - 从其他系统迁移用户
SOURCE_USER="$1"
TARGET_USER="$2"
if [ -z "$SOURCE_USER" ] || [ -z "$TARGET_USER" ]; then
echo "用法: $0 源用户名 目标用户名"
exit 1
fi
echo "迁移用户: $SOURCE_USER -> $TARGET_USER"
echo ""
# 获取源用户信息
SOURCE_UID=$(id -u $SOURCE_USER 2>/dev/null)
SOURCE_GID=$(id -g $SOURCE_USER 2>/dev/null)
SOURCE_GROUPS=$(id -Gn $SOURCE_USER 2>/dev/null | tr ' ' ',')
SOURCE_SHELL=$(getent passwd $SOURCE_USER | cut -d: -f7)
SOURCE_GECOS=$(getent passwd $SOURCE_USER | cut -d: -f5)
if [ -z "$SOURCE_UID" ]; then
echo "错误: 源用户 $SOURCE_USER 不存在"
exit 1
fi
echo "源用户信息:"
echo " UID: $SOURCE_UID"
echo " GID: $SOURCE_GID"
echo " 组: $SOURCE_GROUPS"
echo " Shell: $SOURCE_SHELL"
echo " 全名: $SOURCE_GECOS"
echo ""
# 创建目标用户
echo "创建目标用户..."
sudo useradd -m \
-u $SOURCE_UID \
-g $SOURCE_GID \
-G "$SOURCE_GROUPS" \
-s "$SOURCE_SHELL" \
-c "$SOURCE_GECOS" \
$TARGET_USER
if [ $? -eq 0 ]; then
echo "用户 $TARGET_USER 创建成功"
# 设置相同密码(需要源用户密码)
echo "请手动设置密码:"
sudo passwd $TARGET_USER
# 复制家目录内容(如果需要)
echo "是否复制家目录内容?(y/n)"
read -r RESPONSE
if [ "$RESPONSE" = "y" ]; then
sudo cp -r /home/$SOURCE_USER/. /home/$TARGET_USER/
sudo chown -R $TARGET_USER:$TARGET_USER /home/$TARGET_USER
echo "家目录内容已复制"
fi
echo "用户迁移完成"
else
echo "用户创建失败"
exit 1
fi
# 首先确保系统配置为使用LDAP
# 安装LDAP客户端工具
sudo apt-get install libnss-ldap libpam-ldap ldap-utils
# 配置LDAP客户端
sudo dpkg-reconfigure ldap-auth-config
# 创建本地用户,但主信息来自LDAP
# 这种情况通常不直接使用useradd,而是通过LDAP管理工具
| 特性 | useradd | adduser |
|---|---|---|
| 类型 | 低级工具 | 高级工具(Perl脚本) |
| 交互性 | 非交互式 | 交互式 |
| 易用性 | 需要指定所有选项 | 提示输入信息 |
| 自动化 | 适合脚本 | 适合手动操作 |
| 家目录 | 默认不创建(需-m选项) | 默认创建 |
| 密码 | 不设置密码(需passwd) | 提示设置密码 |
| 发行版支持 | 所有Linux发行版 | 主要是Debian/Ubuntu |
#!/bin/bash
# user_audit.sh - 用户账户审计工具
AUDIT_REPORT="/tmp/user_audit_$(date +%Y%m%d).txt"
echo "用户账户审计报告 - $(date)" > $AUDIT_REPORT
echo "======================================" >> $AUDIT_REPORT
echo "" >> $AUDIT_REPORT
# 1. 列出所有用户
echo "1. 系统用户列表:" >> $AUDIT_REPORT
echo "----------------" >> $AUDIT_REPORT
getent passwd | awk -F: '{printf "%-15s %-8s %-8s %s\n", $1, $3, $4, $5}' >> $AUDIT_REPORT
echo "" >> $AUDIT_REPORT
# 2. 空密码用户
echo "2. 空密码或弱密码用户:" >> $AUDIT_REPORT
echo "----------------------" >> $AUDIT_REPORT
sudo awk -F: '($2 == "" || $2 == "!" || $2 == "*") {print $1}' /etc/shadow >> $AUDIT_REPORT
echo "" >> $AUDIT_REPORT
# 3. 密码过期用户
echo "3. 密码即将过期用户(7天内):" >> $AUDIT_REPORT
echo "---------------------------" >> $AUDIT_REPORT
TODAY=$(date +%s)
while IFS=: read -r USER PW LAST PW_MIN PW_MAX WARN INACT EXPIRE; do
if [ -n "$EXPIRE" ] && [ "$EXPIRE" -gt 0 ]; then
EXPIRE_DAYS=$(( ($EXPIRE - $TODAY) / 86400 ))
if [ $EXPIRE_DAYS -le 7 ] && [ $EXPIRE_DAYS -ge 0 ]; then
echo "$USER: $EXPIRE_DAYS 天后过期" >> $AUDIT_REPORT
fi
fi
done < /etc/shadow
echo "" >> $AUDIT_REPORT
# 4. 长时间未登录用户
echo "4. 30天以上未登录的用户:" >> $AUDIT_REPORT
echo "----------------------" >> $AUDIT_REPORT
lastlog -b 30 | grep -v "Never logged in" | tail -n +2 >> $AUDIT_REPORT
echo "" >> $AUDIT_REPORT
# 5. 有sudo权限的用户
echo "5. 有sudo权限的用户:" >> $AUDIT_REPORT
echo "------------------" >> $AUDIT_REPORT
grep -Po '^sudo.*:\K.*$' /etc/group | tr ',' '\n' >> $AUDIT_REPORT
grep -r "^[^#].*ALL=(ALL)" /etc/sudoers.d/ 2>/dev/null | awk '{print $1}' >> $AUDIT_REPORT
echo "" >> $AUDIT_REPORT
echo "审计报告已生成: $AUDIT_REPORT"
cat $AUDIT_REPORT
#!/bin/bash
# cleanup_expired_users.sh - 自动清理过期账户
LOG_FILE="/var/log/user_cleanup.log"
TODAY=$(date +%Y-%m-%d)
echo "=== 过期用户清理 $(date) ===" | tee -a $LOG_FILE
# 检查/etc/shadow中的过期账户
while IFS=: read -r USER PW LAST PW_MIN PW_MAX WARN INACT EXPIRE; do
if [ -n "$EXPIRE" ] && [ "$EXPIRE" -gt 0 ]; then
# 将过期日期转换为YYYY-MM-DD格式
EXPIRE_DATE=$(date -d "1970-01-01 + $EXPIRE days" +%Y-%m-%d 2>/dev/null)
if [ "$EXPIRE_DATE" \< "$TODAY" ]; then
echo "发现过期账户: $USER (过期于: $EXPIRE_DATE)" | tee -a $LOG_FILE
# 禁用账户而不是删除
sudo usermod -L $USER
sudo chage -E 0 $USER
echo "账户 $USER 已被禁用" | tee -a $LOG_FILE
# 或者删除账户(谨慎使用)
# sudo userdel -r $USER
# echo "账户 $USER 已被删除" | tee -a $LOG_FILE
fi
fi
done < /etc/shadow
echo "清理完成" | tee -a $LOG_FILE
| 用途 | 命令示例 |
|---|---|
| 创建基本用户 | sudo useradd john |
| 创建用户和家目录 | sudo useradd -m john |
| 创建用户并指定全名 | sudo useradd -c "John Doe" john |
| 创建用户并指定UID | sudo useradd -u 1001 john |
| 创建用户并指定shell | sudo useradd -s /bin/bash john |
| 创建用户并指定主组 | sudo useradd -g users john |
| 创建用户并添加附加组 | sudo useradd -G wheel,sudo john |
| 创建系统用户 | sudo useradd -r systemuser |
| 创建带过期日的用户 | sudo useradd -e 2024-12-31 tempuser |
| 查看默认配置 | sudo useradd -D |
| 修改默认shell | sudo useradd -D -s /bin/zsh |