Python进阶之-paramiko详解
✨简介:
ssh是一个协议,OpenSSH是其中一个开源实现,paramiko是Python的一个库,实现了SSHv2协议(底层使用cryptography)。
有了Paramiko以后,我们就可以在Python代码中直接使用SSH协议对远程服务器执行操作,而不是通过ssh命令对远程服务器进行操作。
🌟安装Paramiko
首先,需要确保安装了Paramiko。可以使用pip来安装:
pip install paramiko
🌟Paramiko的主要类
SSHClient: 最常用的类,表示一个SSH客户端连接。
SFTPClient: 用于SFTP传输操作。
Transport: 低级别的模块,可用来实现SSH2协议。
SSHClient主要方法
connect(hostname, port=22, username=None, password=None, pkey=None): 用于连接到远程服务器。可以选择使用用户名和密码或密钥进行认证。
exec_command(command): 在远程服务器上执行指令。
open_sftp(): 返回一个SFTPClient对象,可用于文件的上传与下载。
SFTPClient主要方法
get(remotepath, localpath, callback=None): 下载远程文件。
put(localpath, remotepath, callback=None, confirm=True): 上传本地文件。
listdir(path=“.”): 列出远程目录的内容。
✨示例
🌟SSH连接并执行命令
import paramiko
# 创建SSH客户端
client = paramiko.SSHClient()
# 自动添加未知的服务器密钥及策略
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接SSH服务端
client.connect('hostname', port=22, username='username', password='password')
# 执行命令
stdin, stdout, stderr = client.exec_command('ls -l')
# 获取命令执行结果
result = stdout.read()
print(result.decode())
# 关闭连接
client.close()
🌟通过SFTP上传和下载文件
import paramiko
# 创建SSH客户端
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('hostname', port=22, username='username', password='password')
# 创建SFTP会话
sftp = client.open_sftp()
# 上传文件
sftp.put('localfile.txt', '/remote/path/remote.txt')
# 下载文件
sftp.get('/remote/path/remote.txt', 'localfile.txt')
# 关闭SFTP会话和SSH连接
sftp.close()
client.close()
⚠️注意事项
在使用connect方法时务必考虑安全性,例如使用密钥认证而非明文密码。
对于错误处理,应当尝试捕获paramiko.ssh_exception.SSHException异常。
当不再需要SSH或SFTP客户端时,应当调用close()方法关闭连接。
🌟SSH方法的封装
下面提供一个比较简单的对SSH连接的封装的例子,实现了代理和不需要代理的方式连接服务器,以及发送命令,希望对大家有用。
#!/usr/bin/env python
# coding=utf-8
"""
# @Time : 2024/5/9
# @Author : Summer
# @File : SSH
# @describe:
"""
import paramiko
class SSHClient:
def __init__(self, hostname, port=22, username=None, password=None, pkey=None, use_proxy=False, proxy_hostname=None,
proxy_port=None, proxy_username=None, proxy_password=None, timeout=5):
"""
初始化SSH客户端。
:param hostname: 主机名或IP地址
:param port: 端口号,默认是22
:param username: 用户名
:param password: 密码
:param pkey: 私钥文件对象,用于密钥认证
:param use_proxy: 是否使用代理标志
:param proxy_hostname: 代理的主机名称
:param proxy_port: 代理的端口号
:param proxy_username: 代理的用户名
:param proxy_password: 代理的密码
"""
self.hostname = hostname
self.port = port
self.username = username
self.password = password
self.pkey = pkey
self.use_proxy = use_proxy
self.proxy_hostname = proxy_hostname
self.proxy_port = proxy_port
self.proxy_username = proxy_username
self.proxy_password = proxy_password
self.client = None
self.timeout = timeout
def _setup_proxy(self):
"""
配置代理。
"""
if self.use_proxy:
proxy_ssh = paramiko.SSHClient()
proxy_ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
proxy_ssh.connect(hostname=self.proxy_hostname, port=self.proxy_port, username=self.proxy_username,
password=self.proxy_password, timeout=self.timeout)
vm_transport = proxy_ssh.get_transport()
remote_address = (self.hostname, self.port)
local_address = (self.proxy_hostname, self.proxy_port)
vm_channel = vm_transport.open_channel("direct-tcpip", remote_address, local_address)
return vm_channel
else:
return None
def _connect(self):
"""
创建SSH连接。
"""
self.client = paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
proxy = self._setup_proxy()
self.client.connect(self.hostname, port=self.port, username=self.username, password=self.password,
pkey=self.pkey, sock=proxy, timeout=self.timeout)
def exec_command(self, command):
"""
在远程服务器上执行命令。
:param command: 要执行的命令字符串
:return: 命令输出结果的标准输出和标准错误
"""
if self.client is None:
self._connect()
stdin, stdout, stderr = self.client.exec_command(command)
return stdout.read().decode(), stderr.read().decode()
def close(self):
"""
关闭SSH连接。
"""
if self.client:
self.client.close()
self.client = None
# 使用示例
if __name__ == "__main__":
# 直接连接
ssh = SSHClient(hostname='hostname', port=22, username='username', password='password')
stdout, stderr = ssh.exec_command('ls -l')
print(stdout)
ssh.close()
# 通过代理连接
ssh_with_proxy = SSHClient(hostname='hostname', port=22, username='username', password='password', use_proxy=True,
proxy_hostname='proxy_hostname', proxy_port=22, proxy_username='proxy_username',
proxy_password='proxy_password')
stdout, stderr = ssh_with_proxy.exec_command('ls -l')
print(stdout)
ssh_with_proxy.close()
✨paramiko和pexpect对比
Paramiko和pexpect都是Python库,用于与外部进程、系统和设备进行交互,但它们的设计目的和使用场景存在明显的区别。
🌟Paramiko
Paramiko是一个纯Python实现的SSHv2协议库,它提供了客户端和服务器的SSH功能。Paramiko使得用户可以很容易地使用Python进行安全的远程连接、文件传输(SFTP)以及端口转发。
主要特点
提供了SSH客户端和服务器端编程接口。
支持密钥认证和密码认证。
支持SFTP客户端和服务器功能。
可以用于创建SSH隧道。
提供了底层的通信传输接口(Transport)和高层的功能封装(SSHClient)。
🌟pexpect
pexpect是一个用于控制和自动化命令行应用程序的Python库。它能够启动子程序,并通过预设的期望模式与其交互,从而模拟用户的输入。这类似于在Unix和Linux系统中的脚本工具expect。
主要特点
通过预期模式匹配来交互,类似于Unix中的expect命令。
广泛用于自动构造与许多命令行应用程序的交互会话,不局限于SSH连接。
可以等待特定的字符串出现在输出中,然后发送字符串给进程。
通常用于执行自动化测试,如自动与命令行工具交互输入、输出。
🌟对比与优势
使用场景
Paramiko专注于SSH连接,适用于需要通过SSH执行命令、传输文件等脚本化的自动化任务。pexpect更为通用,可以用于自动化控制任何命令行交互,不仅限于SSH。
安全性
Paramiko直接支持SSH协议的加密和认证机制,非常适合执行需要加密和认证的远程操作任务。而pexpect本身并不处理加密或认证,但可以通过pexpect去调用使用SSH的命令,比如ssh。
复杂性
Paramiko为SSH操作提供了丰富的API,对于复杂的SSH交互和文件操作有着更好的支持。pexpect则在模拟用户和程序间简单交互上的使用更为直观。
平台兼容性
Paramiko是纯Python实现,无需依赖系统命令,因此跨平台支持较好。而pexpect原本设计用于Unix-like系统,虽然有为Windows平台提供的类似库(如winpexpect),但并非原生。
性能
Paramiko可能比pexpect在处理大量文件传输时更高效,因为它直接处理SSH协议。相比之下,pexpect在某些情况下可能因为依赖终端输出的文本匹配而效率较低。
根据具体使用场景来选择适合的工具是关键。如果任务主要涉及SSH连接,文件传输然后执行远程命令,Paramiko是更好的选择。如果目标是广泛的自动化控制各种命令行交互,而不仅仅是通过SSH,那么pexpect是更合适的选择。
更多推荐
所有评论(0)