批量服务器免密登录配置:从生成密钥到批量分发实操

管理多台 Linux 服务器时,如果每次登录都输密码,重复劳动不说,自动化脚本也没法跑。
批量服务器免密登录配置的核心只有两步:在管理机生成一对 SSH 密钥,然后把公钥追加到每台目标服务器的 ~/.ssh/authorized_keys。
难点不在原理,而在批量分发和排错。
下面按可以照做的顺序展开。

适用前提与准备工作

这套流程适合你有一台固定的管理机(本地电脑或跳板机),需要免密登录一批 Linux 服务器,系统一般是 CentOS、Ubuntu、Debian 等常见发行版。
需要满足几个条件:

  • 管理机能通过 SSH 用密码登录目标服务器,且知道各机器的 IP、端口、用户名。
  • 目标服务器开放了 SSH 端口,防火墙和云安全组没有拦截。
  • 建议先整理一份服务器清单文件,例如 hosts.txt,每行一个 IP,方便后续批量执行。

先在管理机生成密钥。
如果已有 ~/.ssh/id_rsa 且不想覆盖,可以换一个文件名:

ssh-keygen -t rsa -b 4096 -C "ops@admin" -f ~/.ssh/id_rsa

执行过程中会提示输入 passphrase,直接回车表示不设密码;
如果设了密码,免密登录时仍要输入该密码,达不到全自动效果,脚本场景建议留空。
生成完成后检查文件权限:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub

权限过松时,SSH 可能直接忽略密钥,表现为“还是让我输密码”。

用 ssh-copy-id 逐台分发公钥

服务器数量在十台以内,最简单的方式是 ssh-copy-id。
它会把公钥追加到目标机器的 authorized_keys,并自动处理目录权限。
假设目标用户是 root,端口是默认 22:

ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.10

如果 SSH 不是 22 端口,加上 -p 参数:

ssh-copy-id -i ~/.ssh/id_rsa.pub -p 2222 root@192.168.1.10

多台机器可以配合 for 循环,从清单文件读取 IP:

while read ip; do
  ssh-copy-id -i ~/.ssh/id_rsa.pub root@$ip
done < hosts.txt

执行时会逐台要求输入一次目标服务器密码,输入正确后公钥写入成功。
完成后立刻验证:

ssh root@192.168.1.10 "hostname && whoami"

如果不再提示密码,并且返回了主机名和用户名,说明这一台的免密已经生效。

用 Ansible 批量下发公钥

机器数量多、或者端口和用户不统一时,逐台输入密码依然很累。
这时可以用 Ansible 的 authorized_key 模块批量完成。
前提是控制机已安装 Ansible,并且能通过密码或已有密钥连上目标机。

先准备 inventory 文件 inventory.ini:

[web]
192.168.1.10
192.168.1.11
192.168.1.12

[web:vars]
ansible_user=root
ansible_ssh_pass=你的密码
ansible_ssh_common_args='-o StrictHostKeyChecking=no'

再执行一次性的公钥下发 playbook:

- hosts: web
  gather_facts: no
  tasks:
    - name: 下发 SSH 公钥
      authorized_key:
        user: root
        state: present
        key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"

保存为 push_key.yml 后运行:

ansible-playbook -i inventory.ini push_key.yml

看到 changed 或 ok 且没有 unreachable,就表示公钥已经写入。
之后可以把 inventory 中的明文密码去掉,改用密钥连接,避免密码留在文件里。

简化连接与批量验证

公钥分发成功后,可以在管理机写 ~/.ssh/config,给每台机器起别名,省去每次敲 IP 和端口:

Host web01
    HostName 192.168.1.10
    User root
    Port 22
    IdentityFile ~/.ssh/id_rsa

之后直接 ssh web01 即可。
批量验证时,用一段循环一次性检查所有机器:

while read ip; do
  echo "=== $ip ==="
  ssh -o BatchMode=yes -o ConnectTimeout=5 root@$ip "echo ok" 2>&1
done < hosts.txt

BatchMode=yes 的作用是禁止交互式输入密码,如果某台仍需密码,会直接报错而不是卡住。
输出全是 ok 就说明批量免密全部生效;
出现 Permission denied 或超时的机器需要单独排查。

常见报错与避坑要点

  • 仍然提示输入密码:先看目标机 ~/.ssh 是否为 700、authorized_keys 是否为 600,属主是否是登录用户。权限不对时 SSH 会拒绝使用公钥。
  • 公钥写到了错误用户:ssh-copy-id root@ip 写的是 root 的目录,如果你实际用 ubuntu 登录,需要改成 ubuntu@ip,两者互不通用。
  • Permission denied (publickey):检查目标机 /etc/ssh/sshd_config 中 PubkeyAuthentication 是否为 yes,修改后需要重载 sshd。
  • 连接超时:确认端口、云安全组和本机防火墙放行,先用 telnet ip 22 或 nc -zv ip 22 测通再谈免密。
  • 私钥别乱传:只需要分发公钥 id_rsa.pub,私钥 id_rsa 留在管理机并保持 600 权限。
  • 批量操作前先备份:如果要修改 sshd_config 或清理 authorized_keys,先复制原文件,避免把自己锁在服务器外。

两个高频疑问

免密后还需要保留密码登录吗? 建议保留一段时间作为回退通道,确认所有自动化脚本和登录都正常后,再考虑在 sshd_config 中关闭密码登录。
直接关闭而密钥又配错,可能导致无法登录。

换了管理机怎么办? 把新管理机的公钥按同样流程追加到目标服务器即可,旧公钥可以后续在 authorized_keys 中删除。
删除时按行操作,不要整文件清空,避免误删其他同事的密钥。

批量服务器免密登录配置本身不复杂,真正影响成功率的是权限、用户、端口和网络这几处细节。
建议先用一台机器跑通全流程,确认 ssh -o BatchMode=yes 能返回结果,再扩展到全部服务器,最后用验证脚本统一复查一遍。

分享到:
上一篇
自动化巡检脚本编写:用 Shell 定时检查服务器磁盘、内存与端口
下一篇
Docker持久化存储配置:容器数据不丢失的完整操作指南
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意