SSH主机免密互信自动化配置脚本使用指南

SSH主机免密互信自动化配置脚本使用指南

简介

本脚本用于自动化配置多台Linux主机之间的SSH免密登录,适用于集群环境下的互信配置。自动完成以下操作:

  • 密钥对生成与分发
  • 已知主机指纹收集(known_hosts)
  • 权限自动配置
  • 连接验证

完整代码

#!/bin/bash

# 样式定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # 清除颜色

# 检查依赖
check_dependencies() {
    if ! command -v sshpass &> /dev/null; then
        echo -e "${YELLOW}正在安装sshpass...${NC}"
        if ! sudo yum install -y sshpass; then
            echo -e "${RED}sshpass安装失败,请手动安装后重试${NC}"
            exit 1
        fi
        echo -e "${GREEN}sshpass安装成功${NC}"
    fi
}

# 配置参数(根据实际情况修改)
HOSTS=(
    "user1@192.168.1.101:22:password1"
    "user2@192.168.1.102:22:password2"
)

# 主程序
main() {
    check_dependencies
  
    local tmp_dir="ssh_key_tmp"
    mkdir -p "$tmp_dir"
  
    # 阶段1: 密钥生成与收集
    echo -e "${YELLOW}=== 开始密钥生成与收集 ===${NC}"
    declare -a pubkeys
    for entry in "${HOSTS[@]}"; do
        IFS="@:" read -r user host port pass <<< "$entry"
      
        echo -e "处理主机: ${YELLOW}$host${NC}"
      
        # 生成密钥对
        if sshpass -p "$pass" ssh -o StrictHostKeyChecking=no -p "$port" "$user@$host" \
            "mkdir -p ~/.ssh && chmod 700 ~/.ssh;
             if [ ! -f ~/.ssh/id_rsa ]; then 
                ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa;
             fi"; then
            echo -e "${GREEN}密钥生成成功${NC}"
        else
            echo -e "${RED}密钥生成失败${NC}"
            exit 1
        fi
      
        # 收集公钥
        local pubfile="$tmp_dir/${host}.pub"
        if sshpass -p "$pass" scp -P "$port" -o StrictHostKeyChecking=no \
            "$user@$host:~/.ssh/id_rsa.pub" "$pubfile" &> /dev/null; then
            pubkeys+=("$pubfile")
            echo -e "${GREEN}公钥收集成功${NC}"
        else
            echo -e "${RED}公钥收集失败${NC}"
            exit 1
        fi
    done
  
    # 阶段2: 收集主机公钥到known_hosts
    echo -e "\n${YELLOW}=== 收集主机公钥到known_hosts ===${NC}"
    local known_hosts_file="$tmp_dir/known_hosts"
    for entry in "${HOSTS[@]}"; do
        IFS="@:" read -r user host port pass <<< "$entry"
        echo "收集主机 $host 的公钥..."
        if ! ssh-keyscan -p "$port" -H "$host" >> "$known_hosts_file" 2>/dev/null; then
            echo -e "${RED}无法收集主机 $host 的公钥${NC}"
            exit 1
        fi
    done
    echo -e "${GREEN}所有主机公钥收集完成${NC}"
  
    # 阶段3: 合并公钥
    echo -e "\n${YELLOW}=== 合并公钥 ===${NC}"
    local auth_file="$tmp_dir/authorized_keys"
    cat "${pubkeys[@]}" > "$auth_file"
    echo "共合并 ${#pubkeys[@]} 个公钥"
  
    # 阶段4: 分发配置
    echo -e "\n${YELLOW}=== 开始分发配置 ===${NC}"
    for entry in "${HOSTS[@]}"; do
        IFS="@:" read -r user host port pass <<< "$entry"
      
        echo -e "配置主机: ${YELLOW}$host${NC}"
      
        # 上传授权文件
        if sshpass -p "$pass" scp -P "$port" -o StrictHostKeyChecking=no \
            "$auth_file" "$user@$host:~/.ssh/authorized_keys" &> /dev/null; then
            echo -e "${GREEN}授权文件上传成功${NC}"
        else
            echo -e "${RED}授权文件上传失败${NC}"
            exit 1
        fi
      
        # 上传known_hosts文件
        if sshpass -p "$pass" scp -P "$port" -o StrictHostKeyChecking=no \
            "$known_hosts_file" "$user@$host:~/.ssh/known_hosts" &> /dev/null; then
            echo -e "${GREEN}known_hosts文件上传成功${NC}"
        else
            echo -e "${RED}known_hosts文件上传失败${NC}"
            exit 1
        fi
      
        # 设置权限
        if sshpass -p "$pass" ssh -p "$port" "$user@$host" \
            "chmod 600 ~/.ssh/authorized_keys ~/.ssh/known_hosts" &> /dev/null; then
            echo -e "${GREEN}权限设置成功${NC}"
        else
            echo -e "${RED}权限设置失败${NC}"
            exit 1
        fi
    done
  
    # 阶段5: 验证配置
    echo -e "\n${YELLOW}=== 开始验证配置 ===${NC}"
    for src_entry in "${HOSTS[@]}"; do
        IFS="@:" read -r src_user src_host src_port src_pass <<< "$src_entry"
      
        for dst_entry in "${HOSTS[@]}"; do
            IFS="@:" read -r dst_user dst_host dst_port dst_pass <<< "$dst_entry"
          
            [ "$src_host" == "$dst_host" ] && continue
          
            echo -n "验证 $src_host -> $dst_host... "
            if ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no \
                -p "$dst_port" "$dst_user@$dst_host" "exit" &> /dev/null; then
                echo -e "${GREEN}成功${NC}"
            else
                echo -e "${RED}失败${NC}"
                exit 1
            fi
        done
    done
  
    # 清理临时文件
    rm -rf "$tmp_dir"
  
    echo -e "\n${GREEN}所有主机已完成互信配置${NC}"
}

main "$@"

前提条件

  1. 网络连通性

    • 确保所有主机之间能通过SSH互相访问
    • 确认防火墙开放SSH端口(默认22)
  2. 权限准备

    • 配置用户具有sudo权限

    • 所有目标主机的用户需要具有SSH目录的写权限

  3. 依赖安装

    • 在控制节点安装sshpass:
    # CentOS/RHEL
    sudo yum install -y sshpass
    
    # Ubuntu/Debian
    sudo apt install -y sshpass
    

配置步骤

  1. 给脚本添加执行权限

    chmod +x ssh_trust.sh
    
  2. 编辑脚本中主机配置文件
    修改HOSTS数组为实际环境配置:

    HOSTS=# 格式:用户名@IP:端口:密码
        "admin@10.0.0.1:22:S3curePass!1"
        "ops@10.0.0.2:2222:MyP@ssw0rd"
  3. 执行脚本

    ./ssh_trust.sh
    

参数说明

参数格式说明
username@IP:port:password用户名@IP地址:SSH端口:密码

执行流程

  1. 密钥生成阶段

    • 检查并安装sshpass
    • 为每台主机生成SSH密钥对
  2. 指纹收集阶段

    • 使用ssh-keyscan收集所有主机指纹
    • 生成统一的known_hosts文件
  3. 分发配置阶段

    • 部署authorized_keys和known_hosts文件
    • 自动设置600权限
  4. 验证阶段

    • 检查所有主机间的互信连接

注意事项

  • 密码安全
    脚本执行后会残留密码信息,建议执行后:

    shred -u ssh_trust.sh
    
  • 密钥覆盖警告
    会覆盖现有~/.ssh/authorized_keys,重要环境建议备份:

    cp ~/.ssh/authorized_keys ~/.ssh/authorized_keys.bak
    
  • 特殊环境

    • 如启用SELinux,需保持策略为允许SSH连接
    • 非标准端口需在防火墙中特别放行

常见问题排查

问题1:主机密钥验证失败

# 手动验证指纹(示例)
ssh-keyscan -p 22 10.0.0.1 >> ~/.ssh/known_hosts

问题2:权限不足错误

# 检查目录权限
ls -ld ~/.ssh
# 应显示drwx------

问题3:sshpass连接超时

# 检查网络连通性
tcping 10.0.0.1 22
# 验证目标SSH服务状态
systemctl status sshd

问题4:脚本卡在确认提示

# 在ssh命令添加-o StrictHostKeyChecking=no
ssh -o StrictHostKeyChecking=no user@host

如问题仍存在,可查看脚本执行时的详细输出:

bash -x ssh_trust.sh
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值