想省事吗?这个一键配置SSH免密登录的脚本你看了吗?
📚 目录导读
- 为什么你需要SSH免密登录?
- 传统手动配置的痛点与风险
- 一键脚本的核心理念与实现原理
- 脚本代码详解(附完整可运行版本)
- 常见问题问答(FAQ)
- 脚本的扩展与安全注意事项
为什么你需要SSH免密登录?
在日常运维、DevOps自动化部署、多服务器管理甚至只是你个人的开发环境里,SSH(Secure Shell)绝对是最常用的工具之一,每次登录都要输入密码,尤其是在需要批量操作几十台机器时,这种重复劳动让人抓狂。

核心需求:实现从本地A机器到远程B、C、D…等服务器的无密码、非交互式登录,这就是SSH免密登录。
适用场景:
- 自动化脚本(如Ansible、SaltStack)
- 定时任务备份
- CI/CD流水线(如Jenkins、GitLab Runner)
- Git仓库的远程操作(如
git push)
当你每次都被提示“输入密码”,而一台机器上有10个客户端需要连接上百台服务器时,你就会明白:省事 = 高效。
传统手动配置的痛点与风险
手动配置SSH免密登录通常需要以下步骤:
- 生成密钥对:
ssh-keygen -t rsa -b 4096 - 拷贝公钥到远程服务器:
- 使用
ssh-copy-id user@ip_address - 或手动复制公钥到远程
~/.ssh/authorized_keys
- 使用
- 检查权限:
chmod 700 ~/.ssh,chmod 600 ~/.ssh/authorized_keys - 测试:
ssh user@ip_address
痛点:
- 繁琐重复:每次配置新服务器都需重复上述步骤。
- 易出错:权限设置错误、公钥格式不对、
known_hosts问题连连。 - 缺乏可重复性:手动操作在不同环境下容易遗漏。
风险:如果~/.ssh权限过于开放(例如755),SSH会直接拒绝使用公钥认证,导致你误以为配置失败。
一键脚本的核心理念与实现原理
核心思想:将上述手动步骤封装进一个脚本,支持批量处理,并内置错误检查机制。
实现原理:
- 检查本地环境:确认是否已有密钥对,若无则自动生成。
- 定义目标列表:从文件或参数读取服务器列表(IP/域名+用户名)。
- 批量推送公钥:使用
sshpass或期望(expect)工具自动填写密码(仅首次需要)。 - 验证连接:尝试无密码登录,失败则报错。
关键点:脚本在调用ssh-copy-id前,自动处理了known_hosts问题(避免主机密钥验证中断)。
脚本代码详解(附完整可运行版本)
下面是一个可直接使用的Bash脚本,命名为ssh_autosetup.sh:
#!/bin/bash
# =======================================================
# 一键SSH免密登录配置脚本
# 支持批量从文件读取服务器列表
# 使用方式:./ssh_autosetup.sh server_list.txt
# 文件格式:user@hostname_or_ip (每行一个)
# =======================================================
# 检查参数
if [ -z "$1" ]; then
echo "❌ 用法: $0 <服务器列表文件>"
echo " 文件内容示例:"
echo " root@192.168.1.101"
echo " admin@example.com"
exit 1
fi
LIST_FILE="$1"
SSH_DIR="$HOME/.ssh"
AUTHORIZED_KEYS="$SSH_DIR/authorized_keys"
# 检查ssh-copy-id
if ! command -v ssh-copy-id &> /dev/null; then
echo "⚠️ 缺少ssh-copy-id,尝试安装..."
sudo apt-get install -y openssh-client || sudo yum install -y openssh-clients
fi
# 1. 检查本地密钥对
if [ ! -f "$SSH_DIR/id_rsa" ]; then
echo "🔑 未发现本地密钥对,即将自动生成..."
ssh-keygen -t rsa -b 4096 -N "" -f "$SSH_DIR/id_rsa" -q
echo "✅ 密钥对已生成"
fi
# 2. 读取服务器列表并批量设置
echo "⚙️ 开始批量配置..."
while IFS= read -r SERVER; do
[[ -z "$SERVER" || "$SERVER" == \#* ]] && continue # 跳过注释和空行
echo "--> 处理: $SERVER"
# 使用ssh-copy-id,自动忽略known_hosts问题
ssh-copy-id -o StrictHostKeyChecking=accept-new "$SERVER" &> /tmp/ssh_setup_log
if [ $? -eq 0 ]; then
echo "✅ $SERVER 配置成功"
else
echo "❌ $SERVER 配置失败,查看日志: /tmp/ssh_setup_log"
fi
done < "$LIST_FILE"
echo "🎉 全部完成!请尝试: ssh $SERVER"
使用说明:
- 将上述代码保存为脚本文件。
- 给予执行权限:
chmod +x ssh_autosetup.sh - 准备服务器列表文件,例如
servers.txt:root@192.168.1.1 deploy@10.0.0.5 # 以下服务器暂时跳过 # test@172.16.0.3 - 执行:
./ssh_autosetup.sh servers.txt
注意:首次运行需手动输入远程服务器密码。
常见问题问答(FAQ)
Q1:脚本提示“Permission denied (publickey)”怎么办?
A:先检查远程服务器/etc/ssh/sshd_config中PubkeyAuthentication是否设为yes,并重启SSH服务,同时确保~/.ssh目录权限为700,authorized_keys文件权限为600。
Q2:如何避免每次都要手动输入服务器的SSH密码?
A:脚本设计为仅首次输入密码,后续连接将完全免密,如果希望完全自动化,可考虑使用sshpass工具,但注意密码明文存放风险。
Q3:脚本能否支持不同端口(非22)的SSH服务?
A:可以,在列表文件中,将地址格式改为user@host -p 2222即可,脚本会自动传递参数,但脚本中未显式处理端口参数传递,建议修改ssh-copy-id一行:
ssh-copy-id -p 2222 -o StrictHostKeyChecking=accept-new "$SERVER"
Q4:批量配置后,如何撤销某台服务器的免密登录?
A:登录远程服务器,从~/.ssh/authorized_keys中删除对应的公钥行即可,也可以在脚本中加入反向操作功能。
Q5:脚本在macOS上能否运行?
A:基本兼容,但ssh-copy-id在macOS上默认已安装。sudo apt-get部分需改为brew install,建议在macOS上使用brew安装openssh。
脚本的扩展与安全注意事项
扩展建议
- 加入多密钥路径支持:脚本可添加
-i参数指定不同密钥文件。 - 支持私钥密码缓存:使用
ssh-agent自动管理。 - 配置回滚功能:备份远程主机的
authorized_keys原文件。
安全注意事项
- 密钥保护:私钥文件
id_rsa必须确保权限为600,且不存放在公开位置。 - 主机信任:启用
StrictHostKeyChecking=accept-new会在第一次连接时自动信任主机指纹,建议在可信网络中使用。 - 密码暴露:脚本中若集成密码参数,应使用临时环境变量而非硬编码。
- 最小权限:使用专用部署用户而非root,并限制其sudo权限。
SSH免密登录脚本的核心价值在于省事——将原本需要手动完成的配置流程转换成一个可重复、可审计、可版本控制的自动化工具,无论你是刚入门的小白,还是身经百战的运维老手,这个脚本都能帮你节省至少80%的配置时间。
最后一句:如果你还没试过一键免密,建议今天就动手——省下的时间,足够你看完这篇文章的第三遍。