#!/bin/bash
set -euo pipefail
# 基础环境配置
setenforce 0 >/dev/null 2>&1 || true
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
systemctl stop firewalld >/dev/null 2>&1 || true
systemctl disable firewalld >/dev/null 2>&1 || true
cd /etc/yum.repos.d/
rm -f ./*.repo
cat > centos.repo <<-EOF
[centos]
name=Local Repo
baseurl=file:///mnt
enabled=1
gpgcheck=0
EOF
cd
mount /dev/sr0 /mnt >/dev/null 2>&1 || true
yum clean all >/dev/null
yum makecache >/dev/null
yum install -y expect wget >/dev/null
# 核心参数(根据实际环境修改)
LOCAL_HOST="192.168.59.141" # 本机IP
REMOTE_HOSTS=("192.168.59.136") # 远程主机列表
ALL_HOSTS=("$LOCAL_HOST" "${REMOTE_HOSTS[@]}")
USER="root"
PASSWORD="123123" # 远程主机密码(确保正确)
SSH_DIR="/root/.ssh"
CONNECT_TIMEOUT=5 # SSH连接超时时间(秒)
# 函数:安全SSH交互(通用版,返回命令输出)
ssh_with_expect() {
local host=$1
local cmd=$2
local output=$(/usr/bin/expect <<-EOF
set timeout $CONNECT_TIMEOUT
spawn ssh -o StrictHostKeyChecking=no $USER@$host "$cmd"
expect {
"*yes/no" { send "yes\r"; exp_continue }
"*password:" { send "$PASSWORD\r"; exp_continue }
timeout { send_user "连接超时:$host\n"; exit 1 }
eof
}
set result \$expect_out(buffer)
send_user \$result
exit 0
EOF
)
echo "$output"
}
# 函数:生成SSH密钥对(支持本机/远程)
generate_ssh_key() {
local host=$1
if [ "$host" == "$LOCAL_HOST" ]; then
echo "生成本机[$host] SSH密钥对..."
mkdir -p "$SSH_DIR" && chmod 700 "$SSH_DIR"
ssh-keygen -t rsa -b 2048 -f "$SSH_DIR/id_rsa" -q -N ''
else
echo "生成远程主机[$host] SSH密钥对..."
ssh_with_expect "$host" "mkdir -p $SSH_DIR && chmod 700 $SSH_DIR && ssh-keygen -t rsa -b 2048 -f $SSH_DIR/id_rsa -q -N ''"
fi
}
# 函数:获取主机公钥(支持本机/远程)
get_host_pubkey() {
local host=$1
if [ "$host" == "$LOCAL_HOST" ]; then
cat "$SSH_DIR/id_rsa.pub"
else
ssh_with_expect "$host" "cat $SSH_DIR/id_rsa.pub"
fi
}
# 函数:向目标主机写入公钥(支持本机/远程)
append_pubkey_to_host() {
local src_host=$1
local dest_host=$2
local pubkey=$(get_host_pubkey "$src_host")
if [ "$dest_host" == "$LOCAL_HOST" ]; then
echo "本机[$dest_host] 写入 $src_host 公钥..."
echo "$pubkey" >> "$SSH_DIR/authorized_keys"
chmod 600 "$SSH_DIR/authorized_keys"
else
echo "远程主机[$dest_host] 写入 $src_host 公钥..."
ssh_with_expect "$dest_host" "echo '$pubkey' >> $SSH_DIR/authorized_keys && chmod 600 $SSH_DIR/authorized_keys"
fi
}
# 步骤1:清理旧密钥(避免重复)
echo "清理旧SSH密钥..."
rm -f "$SSH_DIR/id_rsa" "$SSH_DIR/id_rsa.pub" "$SSH_DIR/authorized_keys"
for host in "${REMOTE_HOSTS[@]}"; do
ssh_with_expect "$host" "rm -f $SSH_DIR/id_rsa $SSH_DIR/id_rsa.pub $SSH_DIR/authorized_keys"
done
# 步骤2:为所有主机生成新密钥对
for host in "${ALL_HOSTS[@]}"; do
generate_ssh_key "$host"
done
# 步骤3:配置本机自免密
echo "配置本机[$LOCAL_HOST]自免密..."
cat "$SSH_DIR/id_rsa.pub" >> "$SSH_DIR/authorized_keys"
chmod 600 "$SSH_DIR/authorized_keys"
chmod 700 "$SSH_DIR"
# 步骤4:配置所有主机互免密
for src_host in "${ALL_HOSTS[@]}"; do
for dest_host in "${ALL_HOSTS[@]}"; do
if [ "$src_host" != "$dest_host" ]; then
append_pubkey_to_host "$src_host" "$dest_host"
fi
done
done
# 验证免密(关键验证步骤)
echo -e "\n===== 免密登录验证 ====="
for host in "${ALL_HOSTS[@]}"; do
echo -n "验证本机到 $host 免密:"
ssh -o ConnectTimeout=$CONNECT_TIMEOUT -o StrictHostKeyChecking=no $USER@$host "echo 验证成功" >/dev/null 2>&1 && echo "✅" || echo "❌"
done
echo "脚本执行完成,具体问题可根据验证结果排查"
linux服务器免密脚本分享
于 2025-05-12 23:33:31 首次发布