Paramiko 是 Python 实现 SSHv2 协议的模块,它支持口令认证和公钥认证两种方式。我们能够基于Paramiko模块编写Python代码,实现SSH相关功能。
它可以实现安全的远程命令执行、文件传输等功能。
组件架构(架构概述)
Paramiko 组件如下图所示,最常用的两个类为 SSHClient 类和 SFTPClient 类,分别提供 SSH 和 SFTP 功能。
我们将主要学习四个类的相关方法:Transport类,Key handling类,SSHClient类,SFTPClient类;
常用协议类
Channel:该类用于创建在 SSH Transport 上的安全通道。Channel类包含执行命令,请求X11会话,发送数据,打开交互式会话等方法。通常这些来自Channel类的常用方法已包装在 SSHClient 中。
Message:SSH Message是字节流,该类包含向流中写入字节,提取字节等方法。该类对字符串、整数、bools、无限精度整数(Python中称为long)的某些组合进行编码。
Packetizer:数据包处理类。Packetizer类包含检查握手,获取channel ID等方法。
Transport:该类用于在现有套接字或类套接字对象上创建一个Transport会话对象。Transport类包含公钥认证,打开channel通道等方法。
SFTPClient:该类通过一个打开的SSH Transport会话创建SFTP会话通道并执行远程文件操作。SSHClient类包含建立连接,打开交互式会话等方法。
SSHClient:SSHClient类是与SSH服务器会话的高级表示。该类集成了Transport,Channel和SFTPClient类。SFTPClient类包含文件上传,文件下载等方法。
密钥相关类
SSH Agent类:该类用于SSH代理。
Host keys类:该类与OpenSSH known_hosts文件相关,用于创建一个host keys对象。
Key handling类:该类用于创建对应密钥类型的实例,如RSA密钥,DSS(DSA)密钥。
Transport 及其方法介绍
一个SSH Transport连接到一个流(通常为套接字),协商加密会话,进行认证。后续可在加密会话上创建通道。多个通道可以在单个会话连接中多路复用(事实上经常如此,如端口转发)。
如下为方法示例:
tran = paramiko.Transport(('192.168.56.100',22)) tran.connect(username=‘client’,password=‘test’) # Transport(sock):建立Transport对象,实例化SSH会话通道。 # connect(username="",password=None,pkey=None):建立SSH会话连接,并使用密码或私钥进行身份认证。 # close():关闭会话。 # 为了便于使用,可以传入地址(作为元组)或主机字符串作为sock参数。 # 主机字符串是具有可选端口(以“:”分隔)的主机名,该端口将转换为(主机名,端口)的元组。
Key handling 及其方法介绍
Key handling:用于创建对应密钥类型的实例,如RSA密钥,DSS(DSA)密钥。这个类包含了密钥的读取,写入等相关方法。
如下为方法示例:
key=paramiko.RSAKey.from_private_key_file(r'C:\Users\exampleuser\.ssh\id_rsa') # RSAKey.from_private_key_file(filename):从文件读取RSA私钥来创建密钥对象。 # DSSKey.from_private_key_file(filename):从文件读取DSS私钥来创建密钥对象。
SFTPClient 及其方法介绍
SFTPClient类通过一个打开的SSH Transport会话通道创建SFTP会话连接并执行远程文件操作。
如下为典型用例:
key=paramiko.RSAKey.from_private_key_file(r'C:\Users\exampleuser\.ssh\id_rsa') tran = paramiko.Transport(('192.168.56.100',22)) tran.connect(username=‘client’, pkey=key) sftp = paramiko.SFTPClient.from_transport(tran) local_path=r'C:\Users\exampleuser\.ssh\vrptest.cfg' remote_path= '/vrpcfg.cfg' sftp.get(remote_path, local_path) # from_transport() 从打开的Transport创建一个SFTP会话连接。 # get() 下载指定文件。 # put() 上传指定文件。
from_transport()
from_transport():从开启的Transport通道创建一个SFTP客户端通道。
如下为方法示例:
T = paramiko.Transport((‘192.168.56.100’,22)) sftp = paramiko.SFTPClient.from_transport(T,window_size=None, max_packet_size=None) # T 一个认证过的开启的Transport会话。 # window_size 可选参数,SFTP会话窗口大小。 # max_packet_size 可选参数,SFTP会话最大数据包大小。
get()
将远程文件(remotepath)从SFTP服务器复制到本地主机的指定路径中(localpath),操作引发的任何异常都将被传递。
如下为方法示例:
local_path=r'C:\Users\exampleuser\.ssh\vrptest.cfg' remote_path= '/vrpcfg.cfg' sftp.get(remote_path, local_path) # remotepath 远程文件。 # localpath 本地主机的目的路径,该路径应包含文件名,仅指定目录可能会导致错误。
put()
将本地文件(localpath)从本地主机复制到SFTP服务器的指定路径中(remotepath),操作引发的任何异常都将被传递。
如下为方法示例:
local_path=r'C:\Users\exampleuser\.ssh\vrptest.cfg' remote_path= '/vrpcfg.cfg' sftp.put(localpath, remotepath) # localpath 本地文件。 # remotepath SFTP服务器上的目的路径,该路径应包含文件名,仅指定目录可能会导致错误。
SSHClient 及其方法介绍
SSHClient类是与SSH服务器会话的高级表示。这个类已经包装 Transport类、Channel类、SFTPClient类来进行会话通道的建立和鉴权认证。
如下为一个典型用例:
client=paramiko.client.SSHClient() client.connect(hostname=‘192.168.56.100’,port=22,username=‘client’,password=‘123456’) stdin,stdout,stderr=client.exec_command(‘ls –l’)
connect()
实现远程服务器的连接与认证。
client.connect(hostname='192.168.56.100',port=22,username=‘client',key_filename='id_rsa') client.connect(hostname='192.168.56.100',port=22,username=‘client',password=‘123456') hostname 连接的目标主机,只有该参数为必选参数。 port 指定端口,默认为22。 username 进行认证的用户名,默认为空。 password 进行认证的用户密码,默认为空。 key_filename 一个文件名或文件列表,指定私钥文件,默认为空。 pkey 用于身份验证的私钥。
set_missing_host_key_policy()
设置连接到没有已知主机密钥的服务器时使用的策略。
client.set_missing_host_key_policy(paramiko.client.AutoAddPolicy()) AutoAddPolicy 自动添加主机名及主机密钥到本地HostKeys对象,不依赖load_system_host_key的配置。即新建立ssh连接时不需要再输入yes或no进行确认。 WarningPolicy 用于记录一个未知的主机密钥的python警告并接受,功能上和AutoAddPolicy类似,但是会提示是新连接。 RejectPolicy 自动拒绝未知的主机名和密钥,依赖load_system_host_key的配置,此为默认选项。
load_system_host_keys()
从系统文件加载主机密钥,如果没有参数,那么就尝试从用户本地的“known hosts”文件中读取密钥信息。
如下为方法示例:
client.load_system_host_keys() # filename 文件名,默认为空。
exec_command()
在远程服务器执行Linux命令。
exec_command():在远程服务器执行Linux命令的方法。
如下为方法示例:
stdin,stdout,stderr=client.exec_command(‘ls –l’)
invoke_shell()
在远程服务器上启动交互式shell会话。
cli = client.invoke_shell()
open_sftp()
在一个会话连接中创建SFTP通道。
sftp=client.open_sftp()
close()
关闭连接。
使用流程图
以 Paramiko SFTP 为例:
补充说明:
1)事实上,由于SSHClient类集成 Transport、Channel、SFTPClient 类,上述方法都可由 SSHClient 这个类实现,SSH 会话更是如此。
参考文献
Welcome to Paramiko! — Paramiko documentation
docs.paramiko.org/en/latest/index.html