一、简介
paramiko是一个基于SSH协议,用于连接远程服务器并执行相关操作的模块,主要用到SSHClient类和SFTPClinet类,一个用于远程执行命令,一个用于文件操作,使用该模块可以对远程服务器进行命令或文件操作。
值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来实现的。
二、使用
1. 下载安装
由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto
pip install pycrypto
pip install paramiko
若直接安装失败,可参考https://www.cnblogs.com/zlw-xyz/p/12889212.html进行安装。
2. SSHClient使用:远程连接并执行命令
2.1 SSHClient常用方法
connect():实现远程服务器的连接与认证,对于该方法只有hostname是必传参数。
set_missing_host_key_policy():设置远程服务器没有在know_hosts文件中记录时的应对策略。目前支持三种策略:
AutoAddPolicy 自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认
WarningPolicy 用于记录一个未知的主机密钥的python警告。并接受,功能上和AutoAddPolicy类似,但是会提示是新连接
RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置。此为默认选项
exec_command():在远程服务器执行Linux命令的方法。
open_sftp():在当前ssh会话的基础上创建一个sftp会话。该方法会返回一个SFTPClient对象。
2.2 SSHClient远程连接方式分为两种:
(1)基于用户名密码连接 (2)基于密钥对连接
(1)基于用户名密码连接
1 import paramiko 2 3 # 创建SSH客户端对象 4 ssh = paramiko.SSHClient() 5 # 允许连接不在know_hosts文件中的主机 6 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 7 # 连接服务器 8 ssh.connect(HOST, PORT, USERNAME, PASSWORD) 9 # 执行命令 10 stdin, stdout, stderr = ssh.exec_command('df') 11 # 获取命令结果,readlines()可以得到列表形式 12 result = stdout.read().decode() 13 print(result) 14 # 错误结果,如命令不存在 15 # print(stderr.read().decode()) 16 # 关闭连接 17 ssh.close()
(2)基于密钥对连接
1 import paramiko 2 3 # 密钥路径 4 private_key_path = '/root/.ssh/id_rsa' 5 # 生成密钥对象 6 private_key = paramiko.RSAKey.from_private_key_file(private_key_path) 7 ssh = paramiko.SSHClient() 8 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 9 ssh.connect(HOST, PORT, USERNAME, pkey=private_key) 10 # 执行命令 11 stdin, stdout, stderr = ssh.exec_command('df') 12 # 获取命令结果,readlines()可以得到列表形式 13 result = stdout.read().decode() 14 print(result) 15 # 错误结果,如命令不存在 16 # print(stderr.read().decode()) 17 # 关闭连接 18 ssh.close()
(3)除了直接连接外,也可以通过封装一个Transport对象连接,并为ssh客户端指定该对象
1 import paramiko 2 3 transport = paramiko.Transport((HOST, PORT)) 4 transport.connect(username=USERNAME, password=PASSWORD) 5 ssh = paramiko.SSHClient() 6 ssh._transport = transport
3. SFTPClient使用:远程连接并操作文件
3.1 SFTPClient常用方法
from_transport()创建一个已连通的SFTP客户端通道
put()将本地文件上传到服务器
get()从服务器下载文件到本地
3.2 需要先创建Transport对象,远程连接方式也分为两种:
(1)基于用户名密码连接 (2)基于密钥对连接
(1)基于用户名密码连接
1 import paramiko 2 3 # 创建Transport对象 4 transport = paramiko.Transport(HOST, PORT) 5 # 连接服务器 6 transport.connect(username=USERNAME, password=PASSWORD) 7 # 创建FTP客户端对象 8 sftp = paramiko.SFTPClient.from_transport(transport) 9 # 上传文件 10 sftp.put('cmds.txt', 'cmds.txt') 11 # 下载文件 12 sftp.get('zzz.txt', 'zzz.txt') 13 # 关闭连接 14 transport.close()
(2)基于密钥对连接
1 import paramiko 2 3 # 密钥路径 4 private_key_path = '/root/.ssh/id_rsa' 5 # 生成密钥对象 6 private_key = paramiko.RSAKey.from_private_key_file(private_key_path) 7 transport = paramiko.Transport(HOST, PORT) 8 transport.connect(username=USERNAME, pkey=private_key) 9 sftp = paramiko.SFTPClient.from_transport(transport) 10 # 上传文件 11 sftp.put('cmds.txt', 'cmds.txt') 12 # 下载文件 13 sftp.get('zzz.txt', 'zzz.txt') 14 # 关闭连接 15 transport.close()
4. paramiko常用功能封装在一个类里,方便调用
包括远程连接,执行命令,文件操作,交互式连接等
1 import sys 2 import paramiko 3 import interactive 4 5 HOST = '192.168.1.10' 6 PORT = 22 7 USERNAME = 'root' 8 PASSWORD = 'root1234' 9 10 11 # 可以将各功能封装在一个类里,方便调用 12 class SSHConnection(object): 13 ''' 14 SSH连接类,封装paramiko常用功能 15 基于用户名密码连接 16 ''' 17 18 def __init__(self, host, port, username, password): 19 self.host = host 20 self.port = port 21 self.username = username 22 self.password = password 23 24 self.ssh = None 25 self.sftp = None 26 self.transport = None 27 28 def connect(self): 29 ''' 30 连接远程主机 31 ''' 32 try: 33 print("正在连接%s......" % (self.host)) 34 transport = paramiko.Transport((self.host, self.port)) 35 transport.connect(username=self.username, password=self.password) 36 except Exception as e: 37 print("连接失败:", e) 38 sys.exit() 39 else: 40 self.transport = transport 41 self.ssh = paramiko.SSHClient() 42 self.ssh._transport = transport 43 self.sftp = paramiko.SFTPClient.from_transport(transport) 44 45 def cmd(self, command): 46 ''' 47 执行操作命令 48 ''' 49 stdin, stdout, stderr = self.ssh.exec_command(command) 50 result = stdout.read().decode() 51 print(result) 52 result = stderr.read().decode() 53 print(result) 54 55 def upload(self, local_path, target_path): 56 ''' 57 上传文件 58 ''' 59 try: 60 self.sftp.put(local_path, target_path) 61 except Exception as e: 62 print("上传失败:", e) 63 64 def download(self, target_path, local_path): 65 ''' 66 下载文件 67 ''' 68 try: 69 self.sftp.get(target_path, local_path) 70 except Exception as e: 71 print("下载失败:", e) 72 73 def get_shell(self): 74 ''' 75 交互式连接 76 ''' 77 channel = self.ssh.invoke_shell() 78 interactive.interactive_shell(channel) 79 80 def close(self): 81 ''' 82 关闭连接 83 ''' 84 self.transport.close() 85 print('已关闭连接%s' % (self.host)) 86 87 88 SSHobj = SSHConnection(HOST, PORT, USERNAME, PASSWORD) 89 SSHobj.connect() 90 SSHobj.get_shell() 91 # SSHobj.cmd('df') 92 # SSHobj.upload('test1.txt', 'test2.txt') 93 # SSHobj.download('test3.txt', 'test4.txt') 94 SSHobj.close()
说明:交互式连接用到interactive.py模块,该模块可直接在paramiko源码安装包的demos目录里找到,直接复制你的python安装目录的site-packages文件夹中即可直接导入使用import interactive。
另外,对Windows下交互部分做了一点优化修改,即函数windows_shell部分,添加输入exit判断,使交互更加方便,修改如下图所示。