Linux useradd命令

useradd 是一个用于在Linux系统中创建新用户账户的核心命令。它是系统管理员最常用的工具之一,可以创建用户账户、设置用户属性、创建家目录,并配置用户的登录环境。

注意:useradd命令需要root权限(或sudo)才能执行。在大多数发行版中,创建用户后需要使用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 显示帮助信息

基本使用示例

示例1:创建基本用户

# 创建一个名为john的用户
sudo useradd john

# 创建后为用户设置密码
sudo passwd john

# 验证用户是否创建
id john
grep john /etc/passwd

示例2:创建用户并指定家目录

# 创建用户并自动创建家目录
sudo useradd -m john

# 创建用户并指定自定义家目录
sudo useradd -m -d /home/john_doe john

# 创建用户但不创建家目录
sudo useradd -M john

示例3:创建带详细信息的用户

# 创建用户并指定全名、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

示例4:创建系统用户

# 创建系统用户(UID < 1000)
sudo useradd -r systemuser

# 创建系统用户并指定shell
sudo useradd -r -s /sbin/nologin daemonuser

# 验证系统用户
id systemuser
# 系统用户的UID通常小于1000

示例5:创建带过期时间的用户

# 创建账户在2024-12-31过期的用户
sudo useradd -e 2024-12-31 tempuser

# 创建密码30天后过期的用户
sudo useradd -f 30 john

# 查看账户过期信息
sudo chage -l tempuser

配置文件

1. /etc/default/useradd

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

2. /etc/login.defs

用户创建的全局默认值:

# 查看登录默认配置
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

3. /etc/skel/ 目录

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

4. /etc/passwd 文件

用户账户信息存储在/etc/passwd文件中:

# 查看用户信息
grep john /etc/passwd

# 格式:用户名:密码占位符:UID:GID:GECOS:家目录:登录shell
# 示例:john:x:1001:1001:John Doe:/home/john:/bin/bash

5. /etc/shadow 文件

加密密码和账户过期信息存储在/etc/shadow文件中:

# 查看用户密码信息(需要root权限)
sudo grep john /etc/shadow

# 格式:用户名:加密密码:最后修改:最小天数:最大天数:警告期:不活动期:过期日期:保留字段

6. /etc/group 文件

组信息存储在/etc/group文件中:

# 查看组信息
grep john /etc/group

# 格式:组名:密码占位符:GID:成员列表

实际应用场景

场景1:批量创建用户

#!/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

场景2:创建Web服务器用户

#!/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)"

场景3:创建带有特定权限的开发者用户

#!/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权限和开发环境"

场景4:创建临时用户(有使用期限)

#!/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 "======================================"

用户账户管理最佳实践

用户管理最佳实践:
  1. 遵循命名规范:使用一致的命名规则(如姓名的首字母)
  2. 设置强密码策略:使用passwd命令设置强密码,或强制首次登录修改
  3. 使用适当的UID:普通用户UID ≥ 1000,系统用户UID < 1000
  4. 合理分组:根据职责将用户分配到适当的组
  5. 限制shell访问:对不需要登录的用户使用/sbin/nologin/bin/false
  6. 设置账户过期:为临时用户设置过期日期
  7. 记录审计日志:记录所有用户创建和修改操作
  8. 定期审查:定期审查和清理不再需要的用户账户

故障排除

问题1:用户已存在

useradd: user 'john' already exists

解决方案:

# 检查用户是否存在
id john
grep john /etc/passwd

# 如果要删除已存在用户重新创建
sudo userdel -r john
sudo useradd john

问题2:组不存在

useradd: group 'developers' does not exist

解决方案:

# 先创建组
sudo groupadd developers

# 或使用现有组
sudo useradd -g users john

# 查看可用组
getent group

问题3:权限不足

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

问题4:UID已存在

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

问题5:家目录创建失败

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文件

安全注意事项

  1. 避免在命令行中使用密码:不要使用-p选项在命令行中指定密码
  2. 使用强密码:创建用户后立即设置强密码
  3. 限制sudo权限:只为需要管理员权限的用户配置sudo
  4. 定期审计:定期审计用户账户,禁用或删除不再需要的账户
  5. 监控登录活动:使用lastwho等命令监控用户登录
  6. 保护敏感文件:确保/etc/passwd/etc/shadow/etc/sudoers等文件权限正确
  7. 使用账户锁定:对多次登录失败的账户进行锁定
  8. 设置密码策略:配置密码最小长度、过期时间等策略

高级用法

设置默认值

# 查看当前默认值
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
# 安装LDAP客户端工具
sudo apt-get install libnss-ldap libpam-ldap ldap-utils

# 配置LDAP客户端
sudo dpkg-reconfigure ldap-auth-config

# 创建本地用户,但主信息来自LDAP
# 这种情况通常不直接使用useradd,而是通过LDAP管理工具

useradd与adduser的区别

特性 useradd adduser
类型 低级工具 高级工具(Perl脚本)
交互性 非交互式 交互式
易用性 需要指定所有选项 提示输入信息
自动化 适合脚本 适合手动操作
家目录 默认不创建(需-m选项) 默认创建
密码 不设置密码(需passwd) 提示设置密码
发行版支持 所有Linux发行版 主要是Debian/Ubuntu

实用脚本示例

脚本1:用户账户审计工具

#!/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

脚本2:自动清理过期账户

#!/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

useradd命令速查表

用途 命令示例
创建基本用户 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