適用場景: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