Python基础之paramiko模块

本文详细介绍Python的Paramiko模块,涵盖安装、核心组件、SSH连接、远程服务器操作、文件上传下载及封装技巧。适用于Python开发者掌握SSH协议下的远程操作。

一:paramiko介绍

paramiko是基于Python实现的SSH2远程安全连接,支持认证及密钥方式。可以实现远程命令执行、文件传输、中间SSH代理等功能,相对于Pexpect,封装的层次更高,更贴近SSH协议的功能

官网地址:
http://www.paramiko.org/installing.html
http://docs.paramiko.org/en/2.4/
https://pypi.org/project/paramiko/

本次实验环境python版本为:3.7.4

1.1 paramiko安装

pip install paramiko

1.2 paramiko包括两个核心的组件

SSHClient:它的作用类似于Linux的SSH命令,是对SSH会话的一个类的封装,这个类封装了传输(Transport),通道(Channel)及SFTPClient建立的方法(open_sftp),通过用于执行远程命令。

SFTPClient:它的作用类似Linux的SFTP命令,是对SFTP客户端的一个类的封装。主要是实现对远程文件的操作,上传,下载,修改文件权限等操作。

1.3 paramiko有几个基础的名词

Transport:是一种加密的会话,使用时会同步创建一个加密的Tunnels(通道),这个Tunnels叫Channel
Channel:是一种类的Socket,一种安全的SSH通道
Session:是client和server保持连接的对象。实现方式是connect —> start_client —> start_server 开始会话。

二:SSH连接步骤

paramiko模块基于SSH协议,所以服务器上必须开户SSH协议

  1. ssh server建立server public key,对应文件/etc/ssh/ssh_host_*文件
  2. ssh client发出请求连接
  3. ssh server发送server public key给ssh client
  4. ssh client比较server public key,同时计算自己的client public/private key
  5. ssh client发送client public key到ssh server
  6. 开始连接,双向加解密

三:paramiko连接远程服务器

3.1 SSHClicent常用方法

connect()方法:
实现远程服务器的连接认证,对于该方法自由一个hostname是必须传的参数
常用参数:
hostname:连接的目标主机
port:目标主机的端口
username:验证的用户可以为None
password:验证的密码可以为None
pkey:私钥的验证方式可以为None
key_filename:一个文件名或者一个文件列表,指定私钥文件
timeout:TCP连接的超时时间,可以为None
allow_agent:是否允许连接到ssh代理,默认为True
look_for_keys:是否在~/.ssh中搜索秘钥文件,默认为True
compress:是否打开压缩,默认False

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对象
通过这个对象可以实现上传下载的功能

3.2 使用密码连接

import paramiko
client = paramiko.SSHClient()
# 自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不在本地 know_hosts文件中记录的主机将无法连接
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
client.connect(hostname = '172.17.2.222', port = 22, username = 'root', password = 'root', timeout = 2)
stdin, stdout, stderr = client.exec_command('cat /proc/meminfo')
print(stdout.read().decode())
client.close()

3.3 从配置文件读取参数

同目录下新建config.ini配置文件,内容如下:

[ssh]
host = 172.17.2.222
port = 22
username = root
password = root
timeout = 2
from configparser import ConfigParser
import paramiko

config = ConfigParser()
config.read('config.ini')
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
try:
    client.connect(
        hostname = config.get('ssh', 'host'),
        port = config.get('ssh', 'port'),
        username = config.get('ssh', 'username'),
        password = config.get('ssh', 'password'),
        timeout = config.getfloat('ssh', 'timeout')
    )
except Exception as e:
    print(e)
    client.close()
else:
    stdin, stdout, stderr = client.exec_command('cat /proc/meminfo')
    print(stdout.read().decode())
    client.close()

Configparser模块是用来解析ini配置文件的解析器,关于ini配置文件的结构可以看python官方文档中的介绍:ini文件结构

3.4 使用秘钥连接

import paramiko
# 配置私人密钥文件位置
private = paramiko.RSAKey.from_private_key_file('/Users/xxx/.ssh/id_rsa')
#实例化SSHClient
client = paramiko.SSHClient()
#自动添加策略,保存服务器的主机名和密钥信息,如果不添加,那么不再本地know_hosts文件中记录的主机将无法连接
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#连接SSH服务端,以用户名和密码进行认证
client.connect(hostname='192.168.163.129',port=22,username='root',pkey=private)
# 打开一个Channel并执行命令
stdin, stdout, stderr = client.exec_command('df -h ')
# stdout 为正确输出,stderr为错误输出,同时是有1个变量有值
# 打印执行结果
print(stdout.read().decode('utf-8'))
# 关闭SSHClient
client.close()

四:paramiko上传下载

SFTPClient常用方法:

SFTPCLient作为一个sftp的客户端对象,根据ssh传输协议的sftp会话,实现远程文件操作,如上传、下载、权限、状态
  
from_transport(cls,t) 创建一个已连通的SFTP客户端通道
put(localpath, remotepath, callback=None, confirm=True) 将本地文件上传到服务器 参数confirm:是否调用stat()方法检查文件状态,返回ls -l的结果
get(remotepath, localpath, callback=None) 从服务器下载文件到本地
mkdir() 在服务器上创建目录
remove() 在服务器上删除目录
rename() 在服务器上重命名目录
stat() 查看服务器文件状态
listdir() 列出服务器目录下的文件
import paramiko
# 获取Transport实例
tran = paramiko.Transport(('172.17.2.222', 22))
# 连接SSH服务端,使用password
tran.connect(username="root", password='root')
# 或使用密钥
# private = paramiko.RSAKey.from_private_key_file('/Users/xxx/.ssh/id_rsa')
# 连接SSH服务端,使用pkey指定私钥
tran.connect(username="root", pkey=private)
# 获取SFTP实例
sftp = paramiko.SFTPClient.from_transport(tran)
# 设置上传的本地/远程文件路径
localpath = "/Users/xxx/Downloads/1.txt"
remotepath = "/tmp/1.txt"
# 执行上传动作
sftp.put(localpath, remotepath)
# 执行下载操作
# sftp.get(remotepath, localpath)
# 关闭连接
tran.close()

五:paramiko进行封装

import paramiko

class ParamikoClient(object):
    def __init__(self, host_info):
        self.hostname = host_info.get('hostname')
        self.port = host_info.get('port')
        self.username = host_info.get('username')
        self.password = host_info.get('password')
        self.transport = paramiko.Transport((self.hostname, self.port))
        self.transport.connect(username = self.username, password = self.password)
        self.client = paramiko.SSHClient()
        self.client._transport = self.transport
        self.sftp = self.client.open_sftp()

    def run_cmd(self, cmd):
        stdin, stdout, stderr = self.client.exec_command(cmd)
        return stdout.read().decode()

    def get(self, remote_file, local_file):
        self.sftp.get(remote_file, local_file)

    def put(self, local_file, remote_file):
        self.sftp.put(local_file, remote_file)

    def __del__(self):
        self.transport.close()
        self.sftp.close()

if __name__ == '__main__':
    host_info = dict(
        hostname = '172.17.2.222',
        port = 22,
        username = 'root',
        password = 'root'
    )
    client = ParamikoClient(host_info)
    result = client.run_cmd('df -h')
    print(result)

    local_file = '/root/tools/test.txt'
    remote_file = '/tmp/test.txt'

    # client.put(local_file, remote_file)
    client.get(remote_file, local_file)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值