想省事吗?这个一键配置SSH免密登录的脚本你看了吗?

wen 实用脚本 46

想省事吗?这个一键配置SSH免密登录的脚本你看了吗?

📚 目录导读

  • 为什么你需要SSH免密登录?
  • 传统手动配置的痛点与风险
  • 一键脚本的核心理念与实现原理
  • 脚本代码详解(附完整可运行版本)
  • 常见问题问答(FAQ)
  • 脚本的扩展与安全注意事项

为什么你需要SSH免密登录?

在日常运维、DevOps自动化部署、多服务器管理甚至只是你个人的开发环境里,SSH(Secure Shell)绝对是最常用的工具之一,每次登录都要输入密码,尤其是在需要批量操作几十台机器时,这种重复劳动让人抓狂。

想省事吗?这个一键配置SSH免密登录的脚本你看了吗?

核心需求:实现从本地A机器到远程B、C、D…等服务器的无密码、非交互式登录,这就是SSH免密登录。

适用场景

  • 自动化脚本(如Ansible、SaltStack)
  • 定时任务备份
  • CI/CD流水线(如Jenkins、GitLab Runner)
  • Git仓库的远程操作(如git push

当你每次都被提示“输入密码”,而一台机器上有10个客户端需要连接上百台服务器时,你就会明白:省事 = 高效。


传统手动配置的痛点与风险

手动配置SSH免密登录通常需要以下步骤:

  1. 生成密钥对ssh-keygen -t rsa -b 4096
  2. 拷贝公钥到远程服务器
    • 使用 ssh-copy-id user@ip_address
    • 或手动复制公钥到远程~/.ssh/authorized_keys
  3. 检查权限chmod 700 ~/.sshchmod 600 ~/.ssh/authorized_keys
  4. 测试ssh user@ip_address

痛点

  • 繁琐重复:每次配置新服务器都需重复上述步骤。
  • 易出错:权限设置错误、公钥格式不对、known_hosts问题连连。
  • 缺乏可重复性:手动操作在不同环境下容易遗漏。

风险:如果~/.ssh权限过于开放(例如755),SSH会直接拒绝使用公钥认证,导致你误以为配置失败。


一键脚本的核心理念与实现原理

核心思想:将上述手动步骤封装进一个脚本,支持批量处理,并内置错误检查机制。

实现原理

  1. 检查本地环境:确认是否已有密钥对,若无则自动生成。
  2. 定义目标列表:从文件或参数读取服务器列表(IP/域名+用户名)。
  3. 批量推送公钥:使用sshpass或期望(expect)工具自动填写密码(仅首次需要)。
  4. 验证连接:尝试无密码登录,失败则报错。

关键点:脚本在调用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"

使用说明

  1. 将上述代码保存为脚本文件。
  2. 给予执行权限:chmod +x ssh_autosetup.sh
  3. 准备服务器列表文件,例如servers.txt
    root@192.168.1.1
    deploy@10.0.0.5
    # 以下服务器暂时跳过
    # test@172.16.0.3
  4. 执行:./ssh_autosetup.sh servers.txt

注意:首次运行需手动输入远程服务器密码。


常见问题问答(FAQ)

Q1:脚本提示“Permission denied (publickey)”怎么办? A:先检查远程服务器/etc/ssh/sshd_configPubkeyAuthentication是否设为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原文件。

安全注意事项

  1. 密钥保护:私钥文件id_rsa必须确保权限为600,且不存放在公开位置。
  2. 主机信任:启用StrictHostKeyChecking=accept-new会在第一次连接时自动信任主机指纹,建议在可信网络中使用。
  3. 密码暴露:脚本中若集成密码参数,应使用临时环境变量而非硬编码。
  4. 最小权限:使用专用部署用户而非root,并限制其sudo权限。

SSH免密登录脚本的核心价值在于省事——将原本需要手动完成的配置流程转换成一个可重复、可审计、可版本控制的自动化工具,无论你是刚入门的小白,还是身经百战的运维老手,这个脚本都能帮你节省至少80%的配置时间。

最后一句:如果你还没试过一键免密,建议今天就动手——省下的时间,足够你看完这篇文章的第三遍。

抱歉,评论功能暂时关闭!