SSH 爲 Secure Shell 的縮寫,由 IETF 的網絡小組(Network Working Group)所制定;SSH 爲創建在應用層基礎上的安全協議。SSH 是目前較可靠,專爲遠程登陸會話和其餘網絡服務提供安全性的協議。利用 SSH 協議能夠有效防止遠程管理過程當中的信息泄露問題.python
paramiko是用python語言寫的一個模塊,遵循SSH2協議,支持以加密和認證的方式,進行遠程服務器的鏈接。paramiko支持Linux, Solaris, BSD, MacOS X, Windows等平臺經過SSH從一個平臺鏈接到另一個平臺。利用該模塊,能夠方便的進行ssh鏈接和sftp協議進行sftp文件傳輸。mysql
#基於ssh,用於鏈接遠程服務器作操做:遠程執行命令,上傳或下載文件 import paramiko #建立一個ssh對象 client = paramiko.SSHClient() #2.解決問題:首次鏈接,會出現 # Are you sure you want to continue connecting (yes/no)? yes # 自動選擇yes # 容許鏈接不在know_hosts文件中的主機 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #3.鏈接服務器 client.connect(hostname='172.25.254.19',port=22,username='root',password='westos') #4.執行操做 stdin,stdout,stderr = client.exec_command('hostname')#標準輸入,標準輸出,標準錯誤輸出。 #Execute a command on the SSH server. A new `.Channel` is opened and # the requested command is executed. The command's input and output # streams are returned as Python ``file``-like objects representing # stdin, stdout, and stderr. #5.獲取命令的執行結果 res = stdout.read().decode('utf-8')#使結果具備可讀性 print(res) #6.斷開鏈接 client.close()
批量鏈接host.txt文件中的主機,返回執行結果
格式:172.25.254.1:22:root:westosios
import paramiko with open('host.txt') as f: #保證host.txt文件在當前目錄下 hostinfos = f.readlines() #列表形式,['172.25.254.1:22:root:westos\n', '172.25.254.2:22:root:westos\n', '172.25.254.3:22:root:westos\n', '172.25.254.19:22:root:westos\n'] for hostinfo in hostinfos: hostinfo = hostinfo.strip() #去掉空格,字符串格式,172.25.254.2:22:root:westos print('正在鏈接%s主機' %(hostinfo.split(':')[0])) hostname,port,username,passwd = hostinfo.split(':') try: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=hostname,port=port,username=username,password=passwd) stdin,stdout,stderr = client.exec_command('hostname') res = stdout.read().decode('utf-8') print('結果爲:',res) except Exception as e : print("Connection is failed,the reason is :",e) finally: client.close() print("鏈接結束")
免密登陸遠程主機
首先在須要鏈接的主機上生成一對公鑰和私鑰,本機獲取到須要鏈接的主機的私鑰時,就能夠經過公私鑰配對,登錄遠程主機。
這裏須要id_rsa存放你所鏈接的主機的私鑰web
import paramiko from paramiko.ssh_exception import NoValidConnectionsError, AuthenticationException def conn(cmd,hostname,port=22,username='root'): client = paramiko.SSHClient() private_key = paramiko.RSAKey.from_private_key_file('id_rsa')#id_rsa存放私鑰 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: client.connect(hostname=hostname, port=port,username=username,pkey=private_key) except NoValidConnectionsError as e: print('...鏈接失敗...') except AuthenticationException as e: print('...密碼錯誤...') else: stdin, stdout, stderr = client.exec_command(cmd) result = stdout.read().decode('utf-8') print(result) finally: client.close() if __name__=='__main__': for count in range(13,20): hostname = '172.25.254.%s' %(count) print('正在鏈接主機:',hostname) conn('hostname',hostname) print("...鏈接結束...")
sftp是Secure File Transfer Protocol的縮寫,安全文件傳送協議。能夠爲傳輸文件提供一種安全的網絡的加密方法。sql
import paramiko tran = paramiko.Transport('172.25.254.19',22) tran.connect(username='root',password='westos') sftp = paramiko.SFTPClient.from_transport(tran) #class SFTPClient(BaseSFTP, ClosingContextManager) #SFTP client object. # Used to open an SFTP session across an open SSH `.Transport` and perform # remote file operations. # Instances of this class may be used as context managers. sftp.put('/home/kiosk/PycharmProjects/day18/07_pratice.py','/mnt/practice.py') sftp.get('/mnt/passwd','hallo') tran.close()
使paramiko模塊執行本身想要的操做shell
import paramiko import os from paramiko.ssh_exception import NoValidConnectionsError, AuthenticationException, SSHException class SshRrmote(object): def __init__(self,cmd,hostname,port,username,passwd): self.hostname = hostname self.passwd = passwd self.cmd = cmd self.username = username self.port = port def run(self): """默認調用的內容""" # cmd hostname # put local_file remote_file # get remote_file local_file cmd_str = self.cmd.split()[0] # cmd # 類的反射, 判斷類裏面是否能夠支持該操做? if hasattr(self, 'do_' + cmd_str): # do_cmd getattr(self, 'do_' + cmd_str)() else: print("目前不支持該功能") def do_cmd(self): client = paramiko.SSHClient() try: client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=self.hostname,port=int(self.port),username=self.username,password=self.passwd) except NoValidConnectionsError as e: print('...鏈接失敗...') except AuthenticationException as e: print('...密碼錯誤...') else: cmd = ' '.join(self.cmd.split()[1:]) stdin, stdout, stderr = client.exec_command(cmd) result = stdout.read().decode('utf-8') print('執行結果',result) finally: print('斷開%s的鏈接' %(self.hostname)) client.close() def do_get(self): #有待改進,由於鏈接多個主機時,會覆蓋文件 print('開始下載') try: trans = paramiko.Transport(self.hostname,int(self.port)) trans.connect(username=self.username,password=self.passwd) print('hello') except SSHException as e: print("鏈接失敗") else: sftp = paramiko.SFTPClient.from_transport(trans) cmd = self.cmd.split()[1:] if len(cmd)==2: sftp.get(cmd[0],cmd[1]) print("下載文件%s成功,並保存爲%s" %(cmd[0],cmd[1])) else: print("參數有誤") trans.close() def do_put(self): # put /tmp/passwd /tmp/passwd # 將本機的/tmp/passwd文件上傳到遠程主機的/tmp/passwd; print("開始上傳") #注意你使用的用戶是否爲kiosk try: trans = paramiko.Transport(self.hostname, int(self.port)) trans.connect(username=self.username, password=self.passwd) except SSHException as e: print("鏈接失敗") else: sftp = paramiko.SFTPClient.from_transport(trans) cmd = self.cmd.split()[1:] if len(cmd) == 2: sftp.put(cmd[0],cmd[1]) print("上傳文件%s成功,並保存爲%s" %(cmd[0], cmd[1])) else: print("參數有誤") trans.close() #1.選擇要操做的主機組:mysql,web,ftp # 主機信息怎麼存?將不一樣的主機信息存放在不一樣的文件中 #2.根據選擇的主機組,顯示包含的主機IP/主機名 #3.讓用戶確認信息,選擇須要批量執行的命令 # -cmd shell命令 # -put 本地文件 遠程文件 # -get 遠程文件 本地文件 def main(): groups = [file.rstrip('.conf') for file in os.listdir('conf')] print('主機組顯示'.center(50,'*')) [print('\t',item) for item in groups] choiceGroup = input("請選擇批量操做的主機組(eg:web):") with open('conf/'+choiceGroup+'.conf') as f: info = f.readlines() print("批量執行腳本".center(50, '*')) while True: cmd = input(">>").strip() if cmd: if cmd =='exit': print("鏈接執行結束") break for item in info: item=item.strip() print(item.split(':')[0].center(50,'-')) hostname,port,username,passwd = item.split(':') ssh = SshRrmote(cmd,hostname,port,username,passwd) ssh.run() main()