适用场景:python
流行的自动化运维之一:ansible是基于ssh通讯来实现的。所以,使用ansible以前,须要先解决ansible服务端与各个被管理节点之间的ssh通讯问题。第一种方法是使用用户名和密码的方式进行ssh通讯,密码须要以明文方式保存在ansible的hosts文件中,存在泄漏密码的安全隐患。第二种方法是基于密钥来实现免密码的ssh通讯,所以须要先将本身的公钥发送给全部被管理节点。安全
如下脚本能够免交互地自动向多个远程主机发送公钥。脚本是使用python 2.7编写的,须要先安装pexpect模块,安装方法:easy_install pexpect运维
能够根据须要修改远程主机列表,远程主机用户,ssh端口号以及须要发送的公钥路径:ssh
#!/usr/bin/env python #coding: utf-8 import pexpect import sys import os def putPublicKey(publicKey,user,servers,port): for server in servers: child = pexpect.spawn("/usr/bin/ssh-copy-id -p %s -i %s %s@%s" %(port,publicKey,user,server)) index = child.expect(["yes/no","password","exist",pexpect.exceptions.EOF, pexpect.TIMEOUT]) if index != 0 and index != 1: print ("未向%s上传公钥匙"%(server)) child.close(force=True) else: print ("开始向%s上传公钥"%(server)) child.sendline("yes") child.expect("password") child.sendline("12345") child.expect("added") print ("已向%s上传公钥"%(server)) print print ("任务执行完成") if __name__ == '__main__': user = "root" #指定远程主机用户名 servers = ["lb1","lb2"] #指定远程主机列表 port = "2222" #指定远程主机的ssh端口 publicKey = "/home/ansible/.ssh/id_rsa.pub" #指定要上传的公钥 #若是指定的公钥不存在,自动建立 if not os.path.exists(publicKey): direname = os.path.dirname(publicKey) print("指定公钥不存在,将自动生成私钥和公钥,路径为:%s"%(direname)) child = pexpect.spawn("ssh-keygen -t rsa -P '' -f %s/id_rsa" %(direname)) child.expect(pexpect.exceptions.EOF) child.close(force=True) print ("已生成私钥和公钥") print putPublicKey(publicKey,user,servers,port)
效果:ide