脚本自动配置ssh互信

  • Post author:
  • Post category:其他



前言


此脚本虽然是

python

脚本,但是里面调用了太多

os.system

命令

(

囧,哥的

python

太水了

)

,只要懂

shell

脚本,就可用

shell

来完成自动配置

ssh

互信脚本。为何当初没有使用

except

,因为本公司的

centos

中没有携带

except

安装包,

centos

还是精简版,很多依赖包都没有。我不想太折腾。


我会一点

python,

使用

python

是理所当然的。原计划用

python paramiko

模块来实现密码放文件里登陆,但是

paramiko

安装编译需要

gcc

环境。精简的

centos

也没有,弄了半天,几十个依赖包弄得我头晕眼花,大小达到

50M

,不通用,懒得做了。


现在的这个脚本需要手动输入远程主机密码,不适用于成百上千台服务器部署

ssh

互信。在网上找了很久,确认

ssh

不支持脚本输入密码。


由于我的业务上经常也就同时做

10

台以内的

ssh

互信,这个脚本就满足需求了。

ssh

配置互信重点


1



、不交互自动生成密钥文件




ssh-keygen



-f



-P

参数,生成密钥不需要交互。如下:

rm -rf ~/.ssh/

/usr/bin/ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ”

cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys

2



自动添加



/etc/hosts



中主机名与

IP



对应关系,并推送到远端主机


这个简单,手动配置或脚本配置都行。互信成功后,用脚本批量推送就行了。


3



、推送密钥文件至远端主机


最简单的方法:

scp  -r /root/.ssh root@hostb:/root


但是咱公司精简的

centos

没有关闭

selinux

。拷贝过去还是不能无密码登陆

(

不信可自己测试

)

。如果采用输入两次密码,第一次登陆上去关闭

selinux

,第二次拷贝

/root/.ssh

过去也可以

(

不想梅开二度

)

。我采用的是另一种方法,只需输入一次密码即可。怎么实现的?见代码。



第一次登陆交互需要输入

yes



获取对端公钥

.ssh

文件拷贝过去后,第一次登陆会让你输入

yes

接收公钥,而且,不止自己登陆对方要输入

yes,

每一台登陆远端主机都要输入

yes,

如果一共

10

台服务器,每台输入

9

次,共需要输入

81

次。这个怎么破?见代码。


执行效果

[root@VueOS scripts]#

python ssh_trust.py

Input node’s info. Usage:hosta/192.168.0.101. Press Enter is complete.

Please input Node info:

nodea/192.168.2.151


#


获取节点信息,主机名与


IP


,生产中尽量使用主机名,方便以后环境迁移

check ip address success!

Input node’s info. Usage:hosta/192.168.0.101. Press Enter is complete.

Please input Node info:

nodeb/192.168.2.158

check ip address success!

Input node’s info. Usage:hosta/192.168.0.101. Press Enter is complete.

Please input Node info:

Are you sure you want  to set ssh mutual trust? (yes/no)

yes


#


是否要设置互信?


因为本次互信是我部署其它程序的前提。互信一次就能配置成功,程序可能多次失败,不需要每次运行都做互信。

Generating public/private rsa key pair.

Created directory ‘/root/.ssh’.

Your identification has been saved in/root/.ssh/id_rsa.

Your public key has been saved in/root/.ssh/id_rsa.pub.

The key fingerprint is:

79:97:67:36:e5:db:0d:4c:8e:20:63:a2:59:f6:bf:17root@VueOS

The key’s randomart image is:

+–[ RSA 2048]—-+

|                 |

|                 |

|     + + .   . .|

|    = + + . * o |

|   o   S . + O .|

|        o .E+ o+|

|         .  . .o|

|          ..    |

|         ..     |

+—————–+


#


自动生成完密钥后,把密钥拷贝到其它节点

Scp ssh key file too another node…

The authenticity of host ‘nodeb(192.168.2.158)’ can’t be established.

RSA key fingerprint isc6:2d:8e:e0:a1:e1:2e:c3:77:c7:1d:ef:92:7c:41:ba.

Are you sure you want to continueconnecting (yes/no)?

yes

Warning: Permanently added’nodeb,192.168.2.158′ (RSA) to the list of known hosts.

root@nodeb’s password:


#


输入远端节点密码

copy ssh file successful

Done

Warning: Permanently added’nodea,192.168.2.151′ (RSA) to the list of known hosts.

local nodea RsaKey remote nodea issuccessful

local nodea RsaKey remote nodeb issuccessful

known_hosts                                                                                      100%  802     0.8KB/s  00:00

hosts                                                                                             100%   84    0.1KB/s   00:00

[root@VueOS scripts]#

ssh nodeb

Last login: Fri Apr  4 15:34:06 2014 from 192.168.2.72

[root@VueOS ~]#

exit

logout

Connection to nodeb closed.

[root@VueOS scripts]#

ssh nodea

Last login: Fri Apr  4 11:55:58 2014 from hosta

[root@VueOS ~]#

exit

logout

Connection to nodea closed.


#


如上所示,互信自动配置成功。





脚本代码

[root@VueOS scripts]# cat ssh_trust.py
#!/usr/bin/python
import datetime
import os,sys,time
import commands
#这个函数是校验IP合法性的。
def check_ip(ipaddr):
        import sys
        addr=ipaddr.strip().split('.')
        #print addr
        if len(addr) != 4:
                print "check ip address failed!"
                sys.exit()
        for i in range(4):
                try:
                        addr[i]=int(addr[i])
                except:
                        sys.exit()
                if addr[i]<=255 and addr[i]>=0:
                        pass
                else:
                        print "check ip address failed!"
                        sys.exit()
                i+=1
        else:
                print "check ip address success!"
node_dict={}
host_all=[]
host_ip_all={}
#这个函数获取输入的节点信息,并校验输入的IP是否合法。
def get_nodes():
        while True:
                node=raw_input("""Input node's info. Usage: hosta/192.168.0.101. Press Enter is complete.
Please input Node info:  """)
                if len(node)==0:
                                return 2
                node_result=node.strip().split('/')
                host_ip_all[node_result[0]]=[node_result[1],'']
                #print node_result
                if len(node_result[0])==0:
                        print "Hostname is failed!"
                        sys.exit()
                check_ip(node_result[1])
                #node_dict[node_result[0]]=[node_result[1]]
                host_all.append(node_result[0])
                #print node_dict
                local_ip_status,local_ip_result=commands.getstatusoutput("""ifconfig |grep 'inet addr'|awk -F '[: ]+' '{print $4}' """)
                local_ip=local_ip_result.split('\n')
                #print host_all
                if len(host_all)==1:
                        if node_result[1] in local_ip:
                                pass
                        else:
                                print "The first IP must be native IP."
                                sys.exit()
#这个函数生成ssh密钥文件,简单的3条shell命令
def create_sshkey_file():
        os.system("rm -rf ~/.ssh/")
        os.system("/usr/bin/ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''    ")
        os.system("cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys")
#这个函数配置/etc/hosts文件
def add_etc_hosts():
    for i in host_ip_all.keys():
        #print host_ip_all.keys()
        #判断/etc/hosts是否存在
        if os.path.exists('/etc/hosts'):
                pass
        else:
                os.system("touch /etc/hosts")
        #删除掉原有主机名项,并添加新的对应关系
        os.system("sed -i '/%s/d' /etc/hosts"%i)
        #print i,host_ip_all[i][0]
        os.system(''' echo '%s %s\r' >>/etc/hosts '''%(host_ip_all[i][0],i))
        #with open('/etc/hosts','ab') as f :
        #       f.write('%s  %s\r'%(host_ip_all[i][0],i))
#拷贝ssh密钥文件
def scp_sshkey():
        #把/root/.ssh文件放在/tmp下,并开使其生效。
        os.system("sed -i /tmp/d /etc/exports")
        os.system("echo '/tmp *(rw)' >>/etc/exports")
        os.system("exportfs -r")
        os.system("cp -a /root/.ssh /tmp")
        os.system("chmod 777 /tmp")
        os.system("/etc/init.d/iptables stop")
        os.system("chmod 777 /tmp/.ssh/id_rsa")
        os.system("chmod 777 /tmp/.ssh")
        print 'Scp ssh key file too another node...'
        print host_all[1:]
        localhost=host_all[0]
        local_ip=host_ip_all[localhost][0]
        #输入一次密码,登陆上去后执行了N条命令,挂载nfs,拷贝.ssh,修改权限,卸载等等。
        for i in host_all[1:]:
                os.system('''/usr/bin/ssh %s "/bin/umount -lf /mnt >/dev/null 2 &>1;/bin/mount %s:/tmp /mnt ;rm -rf /root/.ssh;mkdir /root/.ssh;sleep 3; /bin/cp -a /mnt/.ssh/* /root/.ssh/ ;echo 'copy ssh file successful';/bin/chmod 600 /root/.ssh/id_rsa;/bin/chmod 700 /root/.ssh;/bin/umount -lf /mnt "'''%(i,local_ip))
        print "Done"
#测试ssh互信是否成功
def test_sshkey(host):
    for host_n in host_all:
        try:
                #to gain public key
                #使用StrictHostKeyChecking跳过公钥接收提示。并远程执行命令,连上了自然会输出成功信息。
                os.system(''' ssh  -o  "StrictHostKeyChecking no" %s "echo -e local %s RsaKey remote %s  is successful" '''%(host_n,host_all[0],host_n))
        except:
                print "\033[31mlocal %s RsaKey remote %s is fail.\033[0m"%(host_all[0],host_n)
else:
        #全部测试完成后,把known_hosts文件拷贝到所有主机。一台服务器获取了所有公钥,那拷贝到远端自然是所有节点都有对方公钥了。
        for host_m in host_all[1:]:
                #copy ~/.ssh/known_hosts file to another host...
                os.system("""/usr/bin/scp ~/.ssh/known_hosts %s:~/.ssh/known_hosts"""%host_m)
                # copy hosts file to another host...
                os.system("""/usr/bin/scp /etc/hosts %s:/etc/hosts """%host_m)
#函数执行部分
get_nodes()
a=raw_input("Are you sure you want  to set ssh mutual trust? (yes/no) ").strip()
#提示一下,做不做互信要让用户选择。
if a=="yes":
        create_sshkey_file()
        add_etc_hosts()
        scp_sshkey()
        test_sshkey('192.168.2.73')
elif a=="no":
#输入no就代表互信已做好了。接下来执行别的代码。
        pass
else:
        print 'Byebye,Please input yes or no.'
        sys.exit()



版权声明:本文为weixin_34191845原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。