批量改密码应避免明文暴露,须用sshpass -f读取600权限密码文件;更优方案是免密登录后用chpasswd或passwd --stdin,注意格式、换行符及特殊字符处理。
用 sshpass + for 循环批量改密码,但别直接裸跑
明文密码写进脚本或命令行,等于把钥匙贴在服务器机箱上。必须用 sshpass -f 从文件读密码,且该文件权限得是 600(chmod 600 /path/to/passfile)。更稳妥的做法是提前用 ssh-copy-id 配好免密登录,改密码就走 ssh user@host 'passwd -d username && echo "newpass" | passwd --stdin username' —— 注意 --stdin 在 centos/rhel 有,ubuntu 默认没开,得装 passwd 的增强版或换 chpasswd。
chpasswd 批量同步用户权限时,格式和分隔符不能错
chpasswd 要求输入是 username:password 或 username:password:UID:GID:gecos:home_dir:shell 格式,字段间必须用 :,不能有空格。常见翻车点:导出的用户列表里混了注释行、Windows 换行符(\r\n)、或者密码含特殊字符(如 $、!)被 shell 展开。建议先用 sed -i 's/\r$//' users.txt 清回车,再用单引号包住整个字符串:ssh host 'chpasswd' 。
权限同步不是只改密码,/etc/group 和 /etc/sudoers.d/ 得单独处理
改完 /etc/shadow 只解决登录,组成员关系在 /etc/group,sudo 权限在 /etc/sudoers.d/。别用 usermod -aG 逐台执行——网络延迟叠加会超时。应该生成统一的 groupadd/gpasswd 命令集,或直接 rsync 同步清理过的 /etc/group 文件(注意备份原文件)。sudoers.d/ 下的配置文件名必须以 .conf 结尾,且内容语法必须通过 visudo -c 校验,否则整台机器 sudo 失效。
Ansible 是更稳的选择,但 ansible_ssh_pass 别硬编码在 inventory 里
用 ansible 批量操作时,密码应存在加密的 ansible-vault 文件中,通过 --ask-vault-pass 或环境变量注入。playbook 里改密码用 user 模块:password: "{{ newpass | password_hash('sha512') }}",别用明文 password 参数。容易漏的是:目标主机 Python 版本太低(user 模块依赖 python3-passlib),CentOS 7 默认没装,得先用 package 模块装好。另外,become: yes 必须显式声明,否则权限不够写 /etc/shadow。
真正麻烦的从来不是“怎么批量执行”,而是“怎么确保每台机器的状态一致且可回滚”。比如改完密码后没验证 SSH 是否还能连,或者同步 /etc/group 时覆盖了某台机器特有的组关系——这些细节不写进检查步骤,脚本跑得越快,翻车越彻底。

















