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 "$@"
前提条件
-
网络连通性
- 确保所有主机之间能通过SSH互相访问
- 确认防火墙开放SSH端口(默认22)
-
权限准备
-
配置用户具有sudo权限
-
所有目标主机的用户需要具有SSH目录的写权限
-
-
依赖安装
- 在控制节点安装sshpass:
# CentOS/RHEL sudo yum install -y sshpass # Ubuntu/Debian sudo apt install -y sshpass
配置步骤
-
给脚本添加执行权限
chmod +x ssh_trust.sh
-
编辑脚本中主机配置文件
修改HOSTS
数组为实际环境配置:HOSTS=( # 格式:用户名@IP:端口:密码 "admin@10.0.0.1:22:S3curePass!1" "ops@10.0.0.2:2222:MyP@ssw0rd" )
-
执行脚本
./ssh_trust.sh
参数说明
参数格式 | 说明 |
---|---|
username@IP:port:password | 用户名@IP地址:SSH端口:密码 |
执行流程
-
密钥生成阶段
- 检查并安装sshpass
- 为每台主机生成SSH密钥对
-
指纹收集阶段
- 使用ssh-keyscan收集所有主机指纹
- 生成统一的known_hosts文件
-
分发配置阶段
- 部署authorized_keys和known_hosts文件
- 自动设置600权限
-
验证阶段
- 检查所有主机间的互信连接
注意事项
-
密码安全
脚本执行后会残留密码信息,建议执行后: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