前言

在生产环境中,尤其是集群之间,为了能够使机器之间免密访问,通常需要配置ssh keys 互信,一两台机器手动也会很快处理好,但如果是多台机器,手动做互信就显得有点力不从心了,有可能还会配置错误,为了能够一键化完成自动配置,以下使用shell脚本实现自动互信过程。

一、实现脚本

脚本名称为:autoexssh.sh,执行脚本前需要在各个服务器上安装expect包,可以使用yum方式安装,也可以使用源码编译安装,Depend On You 。

#!/bin/bash

###################################################################
# @Author:             Shaohua                                    #
# @Date:               2021-03-31 14:40:32                        #
# @Last Modified by:   Shaohua                                    #
# @Last Modified time: 2021-03-31 14:43:57                        #
###################################################################
 
#Define Current Directory 
CURRENT_DIR=$(cd "$(dirname $0)";pwd)

#Define Toplevel Directory
TOPLEVEL_DIR=$(cd ${CURRENT_DIR}/..;pwd)

IPLIST=$(cat ${CURRENT_DIR}/iplist)
if [ $# -ne 2 ];then
    echo "Usage:sh $0 用户名 密码"
    exit 99
fi
USER=$1
PASSWD=$2

rm -rf ${CURRENT_DIR}/ssh/
rm -f authorized_keys

for ip in $IPLIST;do
    mkdir -p ${CURRENT_DIR}/ssh/${ip}

#删除已存在的id_rsa.pub
/usr/bin/expect <<EOF
    spawn ssh ${USER}@${ip} rm -f ~/.ssh/*
    expect {
        "*yes/no*" { send "yes\r";exp_continue }
        "*password*" { send "${PASSWD}\r";exp_continue}
    }
#每台服务器生成 rsa 加密文件
    spawn ssh ${USER}@${ip} ssh-keygen -t rsa
    expect {
        "*yes/no*" { send "yes\r";exp_continue }
        "*password*" { send "${PASSWD}\r";exp_continue}
        "Overwrite*" { send "y\r";exp_continue}
        "Enter file in which to save the key*" { send "\r"; exp_continue}
        "Enter passphrase*" { send "\r";exp_continue }
        "Enter same passphrase again*" { send "\r"; exp_continue }
    }
#将每台服务器的id_rsa.pub文件放置于独立的文件夹
    spawn scp ${USER}@${ip}:~/.ssh/id_rsa.pub ${CURRENT_DIR}/ssh/${ip}/
    expect {
        "*yes/no*" { send "yes\r";exp_continue}
        "*password*" { send "${PASSWD}\r";exp_continue}
    }
EOF
done


#将所有的 id_rsa.pub 放置到 authorized_keys中
for ip in $IPLIST;do
    cat ${CURRENT_DIR}/ssh/${ip}/id_rsa.pub >> ${CURRENT_DIR}/authorized_keys
    chmod 600 ${CURRENT_DIR}/authorized_keys
done

#将 authorized_keys 放入到 每台服务器主机的 ~/.ssh/目录下
for ip in $IPLIST;do
/usr/bin/expect <<EOF
    spawn scp ${CURRENT_DIR}/authorized_keys ${ip}:~/.ssh/
    expect {
        "*yes/no*" { send "yes\r";exp_continue}
        "*password*" { send "${PASSWD}\r";exp_continue}
    }
EOF
done


#所有服务器之间的相互连接避免提示符出现
for ip in $IPLIST;do
/usr/bin/expect <<EOF
    spawn ssh ${ip} date
    expect {
        "*yes/no*" { send "yes\r";exp_continue }
        "*password*" { send "${PASSWD}\r";exp_continue}
    }
EOF
done

#生成 remote_ssh 供远程服务器可以执行互相访问脚本,避免第一次连接出现手动交互的情况
cat > ${CURRENT_DIR}/remote_ssh<<eof
IPLIST="$(echo $(cat ${CURRENT_DIR}/iplist))"
for ip in \${IPLIST} ;do
USER=\$(whoami)
/usr/bin/expect <<EOF
        spawn ssh \${USER}@\${ip} date
        expect {
                "*yes/no*" { send "yes\r";exp_continue}
                "*password*" { send "${PASSWD}\r"; exp_continue}
        }
EOF
done
eof


#拷贝远程 remote_ssh 脚本,并在各节点远程执行
for ip in $IPLIST;do
        scp ./remote_ssh  $ip:~/
/usr/bin/expect <<EOF
        spawn ssh ${USER}@${ip} sh ~/remote_ssh
        expect {
                "*yes/no*" { send "yes\r";exp_continue}
                "*password*" { send "${PASSWD}\r"; exp_continue}
        }
EOF
done

二、配置文件

配置文件为各个节点中的主机名称,因此,执行脚本之前需要将所有节点中的主机名解析hosts文件放置在每个节点下的/etc/下,当然也可以直接使用ip地址。如下,有6台服务器:

host1
host2
host3
host4
host5
host6

三、演示示例

这里有10台节点。

hosts 文件

[root@node01 ~]# tail -10 /etc/hosts
10.10.20.70 node01.com  node01
10.10.20.71 node02.com  node02
10.10.20.72 node03.com  node03
10.10.20.73 node04.com  node04
10.10.20.74 node05.com  node05
10.10.20.75 node06.com  node06
10.10.20.76 node07.com  node07
10.10.20.77 node08.com  node08
10.10.20.78 node09.com  node09
10.10.20.79 node10.com  node10

iplist 文件

[root@node01 autossh]# cat iplist 
node01
node02
node03
node04
node05
node06
node07
node08
node09
node10

执行

[root@node01 autossh]# sh autoexssh.sh
Usage:sh autoexssh.sh 用户名 密码

指定用户和密码

[root@node01 autossh]# sh autoexssh.sh root redhat

输出部分如下:

结语

该脚本如果使用在 root 用户下可以任意执行,如果是普通用户执行,注意授权普通用户的执行权限和目录写入权限。脚本获取方式:

git clone https://github.com/DeveloperHonor/ssh-keys.git