非交互式批量改密码chpasswd

chpasswdpasswd非交互版本passwd 要人手敲两次确认,chpasswd标准输入读 用户名:密码 直接改完。它是批量建用户/改密码场景的核心工具。


1.基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 语法
chpasswd [选项] < 用户密码文件

# 最基础: 单条(手工管道)
echo "gaga:Passw0rd123" | chpasswd
sudo -u gaga ls /home # 验证密码生效

# 多条: 批量
cat users.txt
# alice:Al1ce@2024
# bob:Bo2b@2024
# carol:Ca3rol@2024

chpasswd < users.txt
# 三个用户密码一次性改完, 全程无交互

输入格式规则:

每行: 用户名:密码
  • 密码是明文 —— chpasswd 内部会过 PAM/shadow 加密(gcrypt/md5 取决于系统配置)
  • 用户名不存在 → 报错跳过该用户(不影响其他行)
  • 密码含冒号 → 用双引号包裹或改用其他写法(极少见, 一般避开)
  • 行尾不要有多余空格

2.常用选项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
选项        作用
─────────── ─────────────────────────────────────
-e ★加密输入: 输入行改成 用户名:加密密码:哈希算法长度
格式: user:$6$salt$hash (或 -h 查看支持算法)
直接把算好的哈希喂进去, 明文不落盘

-h 查看哈希算法(默认 crypt 或 yescrypt 因发行版而异)
CentOS7: $6$; Ubuntu20.04: $y$; Ubuntu24.04: $y$

-R <chroot> 在 chroot 环境里改(离线修系统, 如安装器/救援模式)
配合 rescue 模式给"装坏的"系统重置 root 密码:
chpasswd -R /mnt/sysroot

-f, --force 忽略错误强制继续(谨慎用)

--quiet 安静模式, 只保留错误输出(脚本里用)

结合 -e 把明文挡在外面(较安全的批量方案):

1
2
3
4
5
6
7
8
9
10
# 先生成哈希(离线/一次性终端)
python3 -c "import crypt; print(crypt.crypt('Al1ce@2024', '\$y\$' + 'salthere'))"
# 输出: $y$10$salthereXXXX...

# 写入文件(只有哈希, 无明文)
cat users.enc
# alice:$y$10$salthere...
# bob:$y$10$othersalt...

chpasswd -e < users.enc # 直接写哈希

3.批量创建用户

chpasswd 本身不建用户(只改已存在用户的密码),所以批量开户是 useradd + chpasswd 组合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 需求: 从 CSV 批量创建 10 个开发人员(部门组)
# dev_users.csv:
# gaga1,dev,1001
# gaga2,dev,1002
# ...

# 方案A: useradd -p (把加密哈希直接塞进, 一步到位)
# 需要先用 yescrypt 算法生成哈希
hash() {
# Ubuntu/Debian 自带 python3 crypt 模块
python3 -c "import crypt,sys; print(crypt.crypt(sys.argv[1], crypt.mksalt(crypt.CRYPT_YESCRYPT)) if sys.argv[1] else '')" "$1"
}
# 但很多老系统 crypt 模块被裁剪 → 用 openssl 更通用:
gen_hash() {
# 用法: gen_hash "明文密码"
openssl passwd -6 -salt "somesalt" "$1" # 或 -y (yescrypt) / -5 (sha256)
}

while IFS=, read -r user group uid; do
useradd -m -g "$group" -u "$uid" "$user"
done < dev_users.csv

# 批量设密码(明文版, 仅在内网可信环境用)
while IFS=, read -r user group uid; do
echo "${user}:Dev@Init${uid}"
done < dev_users.csv | chpasswd

更优雅的写法(一条命令,推荐):

1
2
3
4
5
6
# 一次性: useradd -p 直接带哈希, 建用户+设密码合并
echo "gaga1:$(openssl passwd -6 -salt s1 'Dev@1234')
gaga2:$(openssl passwd -6 -salt s2 'Dev@5678')" | chpasswd

# 或者 useradd -p 把哈希写进 /etc/shadow:
useradd -m -g dev -u 1001 gaga1 -p "$(openssl passwd -6 'Dev@1234')"

4.密码策略相关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 强制首次登录必须改密码(新建账号标配)
passwd -e alice # 把 expire 字段设为 0 → 下次登录必须改密

# 2. 立即过期(比 -e 更严)
chage -E 2026-01-01 alice # 指定日期过期
chage -d 0 alice # 上次密码设置日期=今天(配合策略)

# 3. 锁定/解锁账号(不是改密码, 是禁登录)
passwd -L alice # 锁定: shadow 里密码前加 !, 不能登录
passwd -U alice # 解锁
usermod -L alice # 等价
usermod -U alice

# 4. 查看策略
chage -l alice # 最短/最长天数、上次修改时间、过期时间

# 5. 批量强制90天过期(常见安全审计要求)
for u in dev1 dev2 dev3; do chage -M 90 "$u"; done
# 或批量:
usermod -e 2026-12-31 dev1 dev2 # 指定失效日期

5.维护常用命令

需求                          用什么
──────────────────────────    ─────────────────────────────────────
手工改单个用户密码(交互)      passwd
脚本/批量改密码(非交互)       chpasswd          ← 本主题
建用户+设密码一步到位        useradd -p "$(openssl passwd -6 ...)"
锁定/解锁用户                passwd -L/-U 或 usermod -L/-U
过期策略(90天)              chage -M 90 / usermod -e
root 密码忘了(救援模式)      单用户模式(重启进recovery) 或 chpasswd -R
批量从CSV建用户             useradd + chpasswd 组合脚本
Kerberos/AD 域用户          kpasswd / ldap(不在本机chpasswd管辖范围)