linux公钥批量分发无需手动输密码的核心是用sshpass或scp+echo替代交互式密码输入:先安装sshpass,生成无密钥对,再通过ssh-copy-id或直接追加公钥并设权限600,同时确保目标机用户、目录权限及sshd配置正确。

Linux 中实现公钥批量分发而不手动输密码,核心是绕过交互式密码输入环节。关键不在于“跳过密码”,而在于用自动化工具替代人工输入——比如 sshpass 配合 ssh-copy-id,或直接用 scp + echo 追加公钥内容,再统一修正权限。
用 sshpass 实现无交互分发
sshpass 是一个轻量级工具,能将密码作为参数传给 ssh 命令,避免卡在 password 提示上。适用于已有密码、但不想逐台敲的场景:
- 先安装:CentOS/RHEL 执行
yum install sshpass -y;Ubuntu/Debian 用apt install sshpass -y - 确保本地已生成密钥(如
ssh-keygen -t ed25519 -f ~/.ssh/batch_key,不设 passphrase) - 执行批量命令(以用户
ops、密码123456、目标列表srv{1..5}为例):for host in srv{1..5}; do sshpass -p '123456' ssh-copy-id -i ~/.ssh/batch_key.pub -o StrictHostKeyChecking=no ops@$host; done -
StrictHostKeyChecking=no避免首次连接时卡在 yes/no 确认,适合初始化阶段
用 scp + echo 手动追加公钥(更可控)
当目标服务器禁用密码登录、或 ssh-copy-id 不可用时,可直接上传并拼接公钥内容。这种方式完全避开交互,也便于嵌入脚本:
- 先从本地读取公钥:
PUBKEY=$(cat ~/.ssh/batch_key.pub) - 对每台目标机器执行:
sshpass -p '123456' ssh ops@$host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '$PUBKEY' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" - 注意单引号包裹
$PUBKEY外层用双引号,防止 shell 在本地提前展开变量 - 此方式不依赖 ssh-copy-id,兼容性更强,也方便做权限和目录结构校验
批量前必须统一的基础准备
无论用哪种方式,以下几点没做好,免密一定失败:
- 所有目标机器需存在对应用户(如
ops),且其家目录、~/.ssh目录存在,权限为700 -
~/.ssh/authorized_keys文件权限必须是600,否则 SSH 服务会拒绝加载 - 确认远程
sshd配置允许公钥认证:/etc/ssh/sshd_config中PubkeyAuthentication yes和AuthorizedKeysFile .ssh/authorized_keys已启用 - 若使用非标准端口(如 52113),所有命令中都要显式加
-p 52113
进阶建议:用 expect 替代 sshpass(适合复杂交互)
sshpass 无法处理多级提示(如连续 yes/no + password + sudo 密码)。这时可用 expect 脚本封装完整流程:
- 写一个
deploy.exp,内含 spawn、expect 匹配关键词、send 发送响应的逻辑 - 例如匹配
"yes/no"就 send"yes\r",匹配"password:"就 send"123456\r" - 配合 for 循环调用,就能全自动完成从连接、创建目录、写入公钥到改权限的全过程
- 注意 expect 脚本首行必须是
#!/usr/bin/expect -f,且需赋予执行权限











