expect实现配置机器信任关系

利用expect的交互功能,自动配置信任机器之间的信任关系。

代码里会判断机器是否生成了秘钥,如果没有生成过,则自动帮助你执行 ssh-keygen

ssh_expect.sh 程序依赖expect 命令,用户可以通过同路径的 hosts.properties 文件配置需要设置的信任关系

ssh_expect.sh 程序源码

#!/bin/sh

HOSTS_PROPERTIES="hosts.properties"

expect_ssh_copy_id()
{
  if [ "$#" -ne "5" ]; then
     echo "expect_ssh_copy_id <remoteUser> <remoteHostname> <password> <localUserhome> <timeout>";
     exit 1;
  fi
  local remoteUser=$1
  local remoteHostname=$2
  local password=$3
  local localUserhome=$4
  local timeout=$5
  
  expect -c "
    set timeout $timeout 
    spawn ssh-copy-id -i $localUserhome/.ssh/id_rsa.pub $remoteUser@$remoteHostname
    expect {
      "*yes/no" { send "yes
"; exp_continue }
      "*assword:" { send "$password
" }
    } 
    expect eof
  " > /dev/null 2>&1

}

expect_ssh_keygen()
{
  if [ "$#" -ne "2" ]; then
     echo "expect_ssh_keygen <localUserhome> <timeout>";
     exit 1;
  fi
  local localUserhome=$1;
  local timeout=$2;
  if [ -f ${localUserhome}/.ssh/id_rsa.pub -a -f ${localUserhome}/.ssh/id_rsa ] ; then
     echo -e "	${localUserhome}/.ssh has created id_rsa.pub and id_rsa"
  else
     echo -e "	${localUserhome}/.ssh has not created id_rsa.pub and id_rsa.pub"
     expect -c "
       set timeout $timeout
       spawn ssh-keygen
       expect {
        "*save the key*id_rsa*" {send "
"; exp_continue }
        "*verwrite*y/n*" { send "y
"; exp_continue }
        "*passphrase*passphrase*" { send "
"; exp_continue }
        "*same passphrase*" {send "
" }
       }
       expect eof
       exit 0
     " > /dev/null 2>&1
     if [ "$?" -eq "0" ] ; then 
       echo -e "	create id_rsa.pub,id_rsa successfully"
     else
       echo -e "	create id_rsa.pub,id_rsa faild"
     fi
  fi

}

configure_trust_relation()
{
  if [ "$#" -ne "5" ]; then 
     echo "configure_trust_relation <remoteUser> <remoteHostname> <password> <localUserhome> <timeout>";
     exit 1;
  fi
  local remoteUser=$1
  local remoteHostname=$2
  local password=$3
  local localUserhome=$4
  local timeout=$5

  expect -c "
   
    set timeout $timeout 
    set trust true
    set passwdRight true

    #
    # checking remote machine is be trusted
    # if trust, return 0
    # if not trust, return 1
    # if passwd wrong, return 2
    #
    spawn ssh $remoteUser@$remoteHostname

    expect {
      "*yes/no" { send "yes
" ; exp_continue }
      "*assword:" { send "$password
" ; set trust false }
    } 

    expect {
      "*assword:" { send "03" ; set passwdRight false }
    }
  
    if { "$passwdRight" == "false" } {
       expect eof
       exit 2 
    }
   
    expect { *$* }
    
    send "exit
"
    sleep 1
    if { "$trust" == "false" } {
      expect eof
      exit 1
    }
    expect eof
    exit 0
  " > /dev/null 2>&1

  rn=$?
  if [ "$rn" -eq "1" ] ; then
    echo -e "	${remoteUser}@${remoteHostname} is not be trusted, then exec ssh-copy-id to remote machine"
    #expect_ssh_keygen $localUserhome $timeout
    expect_ssh_copy_id $remoteUser $remoteHostname $password $localUserhome $timeout
  else if [ "$rn" -eq "0" ] ; then
    echo -e "	${remoteUser}@${remoteHostname} is be trusted"
  else if [ "$rn" -eq "2" ] ; then
    #echo -e "	${remoteHostname}@${remoteUser}'s passwd is wrong"
    echo -e "	@@@@@@@ ERROR @@@@@@@"
    echo -e "	@@@@@@@ [${remoteUser}@${remoteHostname}] passwd is wrong @@@@@@@"
  fi
  fi
  fi
}

function configure_all_hosts()
{

   local localUserhome=$1
   local timeout=$2

   expect_ssh_keygen $localUserhome $timeout
   cat ${filepath}/${hosts_properties} | grep -v "<" | grep -v "#" | while read line
   do
      local remoteHostname=$(echo $line | awk -F ' ' '{print $1}')
      local remoteUser=$(echo $line | awk -F ' ' '{print $2}')
      local password=$(echo $line | awk -F ' ' '{print $3}')

      echo "************* [ $remoteUser@$remoteHostname ] *************"

      ping -c 1 $remoteHostname > /dev/null 2>&1

      if [ a"$?" != "a0" ] ; then
         echo -e "	@@@@@@@ ERROR @@@@@@@"
         echo -e "	@@@@@@@ [$remoteHostname] cannot be connected @@@@@@@"
         continue;
      fi


      configure_trust_relation $remoteUser $remoteHostname $password $localUserhome $timeout

   done

}

main()
{

  echo "************* [ BEGIN ] *************"
  which expect > /dev/null 2>&1
  if [ "$?" -ne "0" ]; then
    echo "expect is not exists"
    exit 1;
  fi

  hosts_properties=${HOSTS_PROPERTIES}
  filepath=$( cd "$(dirname $0)"; pwd; )
  localUserhome=$(cd ~;pwd;);
  timeout=5;

  configure_all_hosts ${localUserhome} ${timeout};
  
  echo "************* [ OVER ] *************"
}

main

hosts.properties 文件内容

#<hostname>   <user>      <password>
r730xd-c1    sdbadmin    sdbadmin
r730xd-c2    sdbadmin    sdbadmin
chen         root        root123
r730xd-c3    sdbadmin    sdbadmin
chen2        root        root1907
r730xd-c2    root        root1907

程序执行方法

sh ssh_expect.sh

输出

************* [ BEGIN ] *************
    /home/sdbadmin/.ssh has not created id_rsa.pub and id_rsa.pub
    create id_rsa.pub,id_rsa successfully
************* [ sdbadmin@r730xd-c1 ] *************
    sdbadmin@r730xd-c1 is not be trusted, then exec ssh-copy-id to remote machine
************* [ sdbadmin@r730xd-c2 ] *************
    sdbadmin@r730xd-c2 is not be trusted, then exec ssh-copy-id to remote machine
************* [ root@chen ] *************
    @@@@@@@ ERROR @@@@@@@
    @@@@@@@ [chen] cannot be connected @@@@@@@
************* [ sdbadmin@r730xd-c3 ] *************
    sdbadmin@r730xd-c3 is not be trusted, then exec ssh-copy-id to remote machine
************* [ root@chen2 ] *************
    @@@@@@@ ERROR @@@@@@@
    @@@@@@@ [chen2] cannot be connected @@@@@@@
************* [ root@r730xd-c2 ] *************
    root@r730xd-c2 is not be trusted, then exec ssh-copy-id to remote machine
************* [ OVER ] *************
原文地址:https://www.cnblogs.com/chenfool/p/3762537.html