ssh-keygen免密登錄

#!/bin/bash

#Function:Script will automatically generate the current login account of the public key to send to 

#multiple remote hosts, in order to achieve the purpose of this machine SSH free login multiple remote host

#Usage:bash ssh-login-withoutpasswd.sh

#Date:2016/8

#Author:Jian


#運行該腳本前,請先安裝expect,否則腳本運行不成功,原理:將本機產生的公鑰id_rsa.pub用scp傳輸至遠程服務器

#的家目錄下的.ssh目錄中便可實現本機(注意是用本機產生公鑰的賬號)登陸遠程主機的目的

#需要注意的是要將遠程主機各個家目錄下的.ssh:chmod 700,其下面的文件全部:chmod 600

#在centos,rhel及ubuntu測試通過,如果成功將本機公鑰傳輸到遠程主機卻不能免密登陸,請檢查遠程主機的selinux和iptables

#需要的話,可自行添加日誌相關代碼


check_hosts_on () {

ping_out=`mktemp ping.XXXXXX`

hosts_online=`mktemp hosts_online.XXXXXX`

cd $current_dir

for ip in $(cat hostnamelist|awk -F : '{print $1}')

do

  ping -c1 -w1 $ip >/dev/null && echo "$ip is up" || echo "$ip is down"

done>>$ping_out

for ip_online in $(cat $ping_out|grep "up"|awk '{print $1}')

do

  grep "$ip_online" hostnamelist >> $hosts_online

done

}

authorized_file_transfer () {

#enter the directory where hostnamelist is located

#the hostnamelist file has a target host IP address that needs to be delivered

#save format as ipaddr:username:password,eg:192.168.1.10:root:123456,note that do not leave spaces

cd $current_dir

for remote_infor in `cat $hosts_online`

do

  remote_ip_addr=`echo "$remote_infor" | awk -F : '{print $1}'`

  remote_username=`echo "$remote_infor" | awk -F : '{print $2}'`

  remote_password=`echo "$remote_infor" | awk -F : '{print $3}'`

expect << EOF

  set timeout 10

  spawn ssh -o StrictHostKeyChecking=no $remote_username@$remote_ip_addr

  set timeout 10

  expect "$remote_username@$remote_ip_addr's password:"

  set timeout 10

  send "$remote_password\r"

  set timeout 10

  expect {

  "*#*" {send "mkdir -p ~/.ssh\r"}

  "*\$*" {send "mkdir -p ~/.ssh\r"}

  }

  set timeout 10

  expect {

  "*#*" {send "scp -o StrictHostKeyChecking=no $local_username@$local_ip_addr:$HOME/.ssh/id_rsa.pub ~/.ssh/authorized_keys_from_$local_ip_addr\r"}

  "*\$*" {send "scp -o StrictHostKeyChecking=no $local_username@$local_ip_addr:$HOME/.ssh/id_rsa.pub ~/.ssh/authorized_keys_from_$local_ip_addr\r"}

  }

  set timeout 10

  expect "$local_username@$local_ip_addr's password:"

  set timeout 10

  send "$local_host_passwd\r"

  set timeout 10

  expect {

  "*#*" {send "cat ~/.ssh/authorized_keys_from_$local_ip_addr >>  ~/.ssh/authorized_keys\r"}

  "*\$*" {send "cat ~/.ssh/authorized_keys_from_$local_ip_addr >>  ~/.ssh/authorized_keys\r"}

  }

  set timeout 10

  expect {

  "*#*" {send "chmod 700 ~/.ssh && chmod 600 ~/.ssh/* && rm -f ~/.ssh/authorized_keys_from_$local_ip_addr\r"}

  "*\$*" {send "chmod 700 ~/.ssh && chmod 600 ~/.ssh/* && rm -f ~/.ssh/authorized_keys_from_$local_ip_addr\r"}

  }

  set timeout 10

  expect {

  "*#*" {send "chown -R $remote_username: ~/.ssh\r"}

  "*\$*" {send "chown -R $remote_username: ~/.ssh\r"}

  }

  set timeout 10

  expect {

  "*#*" {send "exit\r"}

  "*\$*" {send "exit\r"}

  }

  set timeout 10

  expect eof

EOF

done

}

create_authorized_file () {

#using ssh-keygen to generate the key, the path is the default path, the empty password

  if [ -d ~/.ssh ];then

    ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

  else

    mkdir -p ~/.ssh

    ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

  fi

}

#get local IP address

local_ip_addr=`/sbin/ifconfig -a|grep inet|grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"|head -1`

local_host_passwd="123456"

#get the user name of the current login user

local_username=`whoami`

#get the directory where the current run script is located

current_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

cd $current_dir

#first determine whether the host list file exists

if [ -f hostnamelist ]; then

#detect which hosts online, which offline

  check_hosts_on

  if grep "down" $ping_out >/dev/null; then

    echo "Warning:$(sed -n '/down/p' $ping_out|wc -l) hosts offline:"

    sed -n '/down/p' $ping_out

    echo "$(sed -n '/up/p' $ping_out|wc -l) hosts online:"

    sed -n '/up/p' $ping_out

  else

    echo "The hosts in the hostnamelist are all online!"

  fi

  if [ -f ~/.ssh/id_rsa ] && [ -f ~/.ssh/id_rsa.pub ]; then

    authorized_file_transfer

    chown -R $local_username: ~/.ssh/

    chmod 600 ~/.ssh/* 

    chmod 700 ~/.ssh

    rm -f $ping_out

    rm -f $hosts_online

    exit 0

  else

    create_authorized_file

    authorized_file_transfer

    chown -R $local_username: ~/.ssh/

    chmod 600 ~/.ssh/* 

    chmod 700 ~/.ssh

    rm -f $ping_out

    rm -f $hosts_online

    exit 0

  fi

else

  echo "Error:the important file 'hostnamelist' has been lost"

  echo "Now,creat it,but you still write something inside,the format is as follows:"

  touch hostnamelist

  echo "remote_ip_addr:remote_user_name:remote_host_password"

  exit 0

fi


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章