背景: 有時候我們在兩個主機之間復制文件的時候,提示輸入密碼,很不方便,那如何免密碼復制呢?,就是使用通過linux公鑰和秘鑰,建立雙機信任關系。
在整理之前,我先說下ssh免密碼的要點 :
你想免密碼登陸到哪個主機哪個用戶, 就把你自己的公鑰文件內容追加到遠程主機對應用戶下的authorized_keys文件中(對面可能沒有這個文件,創建即可)。
1. 生成秘鑰,並添加信任
我的環境中node1的ip是192.168.168.201,node2的ip是192.168.168.202.
[root@node1 ~]# ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa #生成rsa [root@node1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.168.202 #復制201的公鑰到202機器上,這樣就可以使用在201機器上免密碼登錄202機器了。 [root@node2 ~]# ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa #生成rsa [root@node2 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.168.201 #復制202的公鑰到201機器上,這樣就可以使用在202機器上免密碼登錄201機器了。
注意:
- 如果遠程主機的端口非22端口,需要指定-p port選項。
- ssh-copy-id是由openssh-clients包提供,沒有這個命令可以安裝這個包。
- centos6,7使用ssh-copy-id的時候可以不用指定-i選項,centos5必須指定的。
2.信任自己主機
[root@node1 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.168.201 [root@node2 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.168.202
3.測試
[root@node1 ~]# ssh 192.168.168.202 'ip addr show dev eth0 ' 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:50:56:3f:42:13 brd ff:ff:ff:ff:ff:ff inet 192.168.168.202/24 brd 192.168.168.255 scope global eth0 inet6 fe80::250:56ff:fe3f:4213/64 scope link valid_lft forever preferred_lft forever [root@node2 ~]# ssh 192.168.168.201 'ip addr show dev eth0' 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:c9:20:88 brd ff:ff:ff:ff:ff:ff inet 192.168.168.201/24 brd 192.168.168.255 scope global eth0 inet 192.168.168.200/24 brd 192.168.168.255 scope global secondary eth0 inet6 fe80::20c:29ff:fec9:2088/64 scope link valid_lft forever preferred_lft forever
4 自動配置免密碼登陸
這里有個情況, 有一個跳板機,內部好多自己的服務器。遠程只能通過跳板機遠程內部服務器,現在需要在跳板機上免密碼登陸內部的服務器。
4.1 各個機器上面需要先生成各自的公鑰和密碼
4.2 跳板機編寫腳本和配置文件如下
#!/bin/bash #================================================ #FileName :expect_ssh.sh #Author :zhaojiedi #Description: #DateTime :2018-01-05 08:26:06 #Version :V1.0 #Other : #================================================ host_username_password_file=hosts.txt # install expect rpm -q expect &>/dev/null || yum install -yq expect &>/dev/null # create id_rsa.pub file pubkey=~/.ssh/id_rsa.pub if [ ! -e "$pubkey" ] ; then ssh-keygen -P "" -t rsa -f ~/.ssh/id_rsa fi while read host username password ; do con=${username}"@"${host} echo $password expect <<EOF set timeout 20 spawn ssh-copy-id $con expect { "yes/no" { send "yes\n" ; exp_continue } "password:" { send "${password}\n"; exp_continue } } EOF done < $host_username_password_file
樣例的配置文件是這樣的。
[root@centos74 bin]$ cat hosts.txt 172.18.46.6 root oracle
4.3 集群主機免密碼配置
上面的跳板機配置免密碼登陸都是單向的, 但是對於集群環境我們需要配置任意2個主機的主機信任的。
#!/bin/bash # 配置項 # 文件格式是 ip usename password port 中間使用空格分割 host_username_password_file=/root/hosts.txt # 配置是否copy文件到其他目標主機上去,只有第一個執行的主機需要copy,其他不需要的 need_copy_to_other=0 src_host="current_host_ip" #echo $# if [ "$#" -eq 0 ] ; then need_copy_to_other=1 else src_host=$1 fi # 安裝 expect rpm -q expect &> /dev/null || yum install -yq expect &>/dev/null # 創建 秘鑰文件 pubkey=~/.ssh/id_rsa.pub prikey=~/.ssh/id_rsa if [ ! -e "$pubkey" ] ; then ssh-keygen -P "" -t rsa -f $prikey &>/dev/null fi while read host username password port ; do if [ -z "$host" ] ; then continue fi printf "%16s=======>%-16s\n" $src_host $host #echo "==============================$host $username $password $port ========================================= " con=${username}"@"${host} cmd_with_argv="ssh-copy-id -p $port $con " #echo $password expect <<-EOF set timeout 600 log_user 0 spawn -noecho $cmd_with_argv expect { "yes/no" { send "yes\n"; exp_continue } "password:" { send "${password}\n"; exp_continue } } EOF &> /dev/null if [ "$need_copy_to_other" -eq 1 ] ; then ip a | grep $host &> /dev/null if [ "$?" -ne 0 ] ; then #echo "==>復制必要的文件到遠程主機($host)上去" scp -q -p -P $port $host_username_password_file $host:$host_username_password_file scp -q -p -P $port $0 $host:$0 #echo "==>在目標主機${host}上執行下" ssh -f -p $port $con "$0 $host " fi fi done < $host_username_password_file sleep 2
[root@localhost ~]# cat hosts.txt 192.168.46.151 root oracle 22 192.168.46.152 root oracle 22 192.168.46.153 root oracle 22 192.168.46.154 root oracle 22 192.168.46.157 root oracle 22
使用方式
[root@localhost ~]# /root/expect.sh current_host_ip=======>192.168.46.151 current_host_ip=======>192.168.46.152 current_host_ip=======>192.168.46.153 192.168.46.152=======>192.168.46.151 192.168.46.152=======>192.168.46.152 192.168.46.152=======>192.168.46.153 current_host_ip=======>192.168.46.154 192.168.46.153=======>192.168.46.151 192.168.46.152=======>192.168.46.154 192.168.46.153=======>192.168.46.152 192.168.46.152=======>192.168.46.157 192.168.46.153=======>192.168.46.153 current_host_ip=======>192.168.46.157 192.168.46.154=======>192.168.46.151 192.168.46.153=======>192.168.46.154 192.168.46.154=======>192.168.46.152 192.168.46.153=======>192.168.46.157 192.168.46.154=======>192.168.46.153 192.168.46.154=======>192.168.46.154 192.168.46.154=======>192.168.46.157