shell(49) : 多个服务器批量设置相互免密

写在前面

  • CentOS Linux release 7.9.2009 (Core) 系统已验证
  • 默认root账户, 其他账户无效
  • 创建auto_mm.sh必须vi创建文件然后粘贴

1.安装expect

1.1.在线安装

bash 复制代码
yum install -y tcl
yum install -y expect

1.2.离线安装(选其中一个即可)

1.2.1.在能联通公网的机器导出rpm包到不能联通公网的机器安装

参考 shell(30) : yum导出依赖包并离线安装_yum 导出包-CSDN博客

bash 复制代码
repotrack expect

1.2.2.百度网盘下载

待补充 ...

1.2.3.CSDN下载

待补充 ...

2.填下ip和密码信息(填好直接粘贴即可)

bash 复制代码
cat > ips <<'EOF'
192.168.1.1 abc123
192.168.1.2 abc123
EOF

若执行失败则创建ips文件, 填入以下内容

bash 复制代码
192.168.1.1 abc123
192.168.1.2 abc123

3.创建执行脚本 auto_mm.sh , 粘贴以下

bash 复制代码
#!/usr/bin/bash
path="$(cd "$(dirname "$0")" && pwd)"
cd $path

function info() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "$DATE_N|INFO|$@ "
}

function warning() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[33m$DATE_N|WARINIG|$@ \033[0m"
}

function success() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[32m$DATE_N|SUCCESS|$@ \033[0m"
}

function error() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[31m$DATE_N|ERROR|$@ \033[0m"
  exit
}

cat >create_mm.sh <<'EOF'
ssh-keygen -t rsa -N '' <<EOF
/root/.ssh/id_rsa
yes


\EOF
EOF
sed -i "s#\\\\\EOF#EOF#g" create_mm.sh

rm -rf auto_mm_mys

if ! test -e ips; then
		error "[ips]文件不存在"
fi

echo "-----------------[拉取公钥]-----------------"
while read line; do
  ip=$(echo $line | awk '{print $1}')
  pass=$(echo $line | awk '{print $2}')
  # 创建ssh秘钥
  expect <<EOF
     spawn ssh root@$ip "ls /root/.ssh/id_rsa.pub |wc -l > /root/auto_mm_rs"
       expect {
            "yes/no" { send "yes\n";exp_continue}  
            "password" { send "$pass\n"}
       }
       expect eof
EOF

  expect <<EOF
     spawn scp root@$ip:/root/auto_mm_rs ./
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF

  rs=$(cat auto_mm_rs)
  if [ $rs -eq 0 ]; then
    warning "$ip未创建ssh秘钥, 执行创建ssh秘钥"
    expect <<EOF
     spawn scp create_mm.sh root@$ip:/root
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF
    expect <<EOF
     spawn ssh root@$ip "sh /root/create_mm.sh"
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF
    sleep 1s
    expect <<EOF
     spawn ssh root@$ip "ls /root/.ssh/id_rsa.pub |wc -l > /root/auto_mm_rs"
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF

    expect <<EOF
     spawn scp root@$ip:/root/auto_mm_rs ./
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF
    rs=$(cat auto_mm_rs)
    if [ $rs -eq 0 ]; then
      error "[$ip]ssh秘钥创建失败"
    else
      success "[$ip]ssh秘钥创建成功"
    fi
  else
    warning "$ip已创建ssh秘钥"
  fi
  # 拉取ssh公钥
  expect <<EOF
     spawn scp root@$ip:/root/.ssh/id_rsa.pub ./
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF
  if ! test -e id_rsa.pub; then
    error "[$ip]ssh公钥拉取失败"
  fi
  cat id_rsa.pub >>auto_mm_mys
  success "[$ip]拉取公钥成功"
done <ips

echo "-----------------[发送公钥]-----------------"
while read line; do
  ip=$(echo $line | awk '{print $1}')
  pass=$(echo $line | awk '{print $2}')
  expect <<EOF
     spawn scp auto_mm_mys root@$ip:/root
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF
  expect <<EOF
     spawn ssh root@$ip "cat /root/auto_mm_mys >> /root/.ssh/authorized_keys"
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$pass\n"}
       }
       expect eof
EOF
done <ips

echo "-----------------[验证]-----------------"
cat >auto_mm_yz.sh <<'EOF'
function info() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "$DATE_N|INFO|$@ "
}

function warning() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[33m$DATE_N|WARINIG|$@ \033[0m"
}

function success() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[32m$DATE_N|SUCCESS|$@ \033[0m"
}

function error() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[31m$DATE_N|ERROR|$@ \033[0m"
}
EOF

while read line; do
  ip=$(echo $line | awk '{print $1}')
  pass=$(echo $line | awk '{print $2}')
  echo "ssh $ip -o PreferredAuthentications=publickey -o StrictHostKeyChecking=no \"date\" > /dev/null 2>&1" >>auto_mm_yz.sh
  cat >>auto_mm_yz.sh <<'EOF'
if [ $? -eq 0 ]; then
EOF
  echo "    success \"[local_ip] ====> [$ip]设置免密成功\"" >>auto_mm_yz.sh
  echo "else" >>auto_mm_yz.sh
  echo "    warning \"[local_ip] ====> [$ip]设置免密失败\"" >>auto_mm_yz.sh
  echo "fi" >>auto_mm_yz.sh
done <ips
sed -i "s#local_ip#\$1#g" auto_mm_yz.sh


cat > yz.sh <<'EOF'
#!/usr/bin/bash

function info() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "$DATE_N|INFO|$@ "
}

function warning() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[33m$DATE_N|WARINIG|$@ \033[0m"
}

function success() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[32m$DATE_N|SUCCESS|$@ \033[0m"
}

function error() {
  DATE_N=$(date "+%Y-%m-%d %H:%M:%S.%N" | cut -b 1-23)
  echo -e "\033[31m$DATE_N|ERROR|$@ \033[0m"
}

function yz() {
  ssh $1 -o PreferredAuthentications=publickey -o StrictHostKeyChecking=no "date" >/dev/null 2>&1
  if [ $? -eq 0 ]; then
    success "=================[$1]配置免密成功================="
    info "验证【[$1]】对所有服务器的免密配置"
    scp auto_mm_yz.sh root@$1:/root
    ssh root@$1 "sh /root/auto_mm_yz.sh $1"
  else
    warning "=================[$1]配置免密失败================="
    expect <<EOF
     spawn scp auto_mm_yz.sh root@$1:/root
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$2\n"}
       }
       expect eof
\EOF
    info "验证【[$1]】对所有服务器的免密配置"
    expect <<EOF
     spawn ssh root@$1 "sh /root/auto_mm_yz.sh $1"
       expect {
            "yes/no" { send "yes\n";exp_continue} 
            "password" { send "$2\n"}
       }
       expect eof
\EOF
  fi
}

EOF
sed -i "s#\\\\\EOF#EOF#g" yz.sh

while read line; do
  ip=$(echo $line | awk '{print $1}')
  pass=$(echo $line | awk '{print $2}')
  echo "yz $ip $pass" >> yz.sh
done <ips

sh yz.sh

# 清理
rm -rf auto_mm_mys
rm -rf auto_mm_rs
rm -rf auto_mm_yz.sh
rm -rf create_mm.sh
rm -rf id_rsa.pub
rm -rf yz.sh

4.执行脚本

bash 复制代码
sh auto_mm.sh
相关推荐
DYWorker0012 分钟前
第1课:基于正点原子RK3568开发板读懂Linux内核
linux·运维·网络
GlobalInfo20 分钟前
全球及中国机器人现场部署服务行业研究报告(2026版):市场现状、行业前景与占有率分析
大数据·运维·人工智能
Android系统攻城狮22 分钟前
Linux FFmpeg深度解析之avformat_open_input调用流程与实战(一)
linux·运维·ffmpeg·车载音视频·ffmpeg音视频·音视频进阶手册
分布式存储与RustFS37 分钟前
把 LSM 引擎直接架在对象存储上:slatedb 能不能跑在 RustFS 上?
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
深圳恒讯42 分钟前
国外云服务器部署企业官网,怎样确定配置、IP 与后续扩容方案?
运维·服务器·tcp/ip
java_logo1 小时前
Docker 部署 Excalidraw:轻松搭建手绘风格白板
运维·docker·容器·excalidraw·白板·轩辕镜像
吹什么轩1 小时前
linux系统复习:Ext 文件系统(一个文件在磁盘上到底长什么样)
linux·运维·服务器
吹什么轩1 小时前
linux系统复习:全景串联
linux·运维·服务器
m0_547486661 小时前
《Ubuntu Linux操作系统与实验教程》全套PPT课件2026
linux·ubuntu·操作系统
Elastic 中国社区官方博客1 小时前
5 分钟内将 56 页扫描文档转化为带引用的答案:面向搜索无法读取的文档的检索增强生成流水线
大数据·运维·人工智能·elasticsearch·搜索引擎·信息可视化·全文检索