paramiko 模块
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。
它是基于Python实现的 SSH2远程安全连接,支持认证及密钥方式。可以实现远程命令执行、文件传输、中间SSH代理等功能。
官网地址: http://www.paramiko.org
paramiko 安装
paramiko 会依赖第三方的 Crypto 、Ecdsa 包及Python 开发包 python-devel 的支持。
所以先安装依赖包,再安装 paramiko
# python3.x
yum install python-devel
pip3 install pycrypto
pip3 install ecdsa
pip3 install paramiko
验证安装
import paramiko
没有异常则证明安装成功
一般使用流程步骤示例,适用于首次建立 ssh 连接的情况
#/urs/bin/env python3
import paramiko
# 第一步 定义主机信息,用户信息
hostname = '192.168.56.129'
username = 'root'
import paramiko
# 第一步 定义主机信息,用户信息
hostname = '192.168.56.129'
username = 'root'
password = 'upsa'
# 第二步 (可选)
#发送paramiko日志到 sysloging.log 文件
paramiko.util.log_to_file('sysloging.log')
# 第三步 创建一个 ssh 客户端 client 对象
ssh = paramiko.SSHClient()
# 设置本机和远程主机第一次建立ssh连接是的策略
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 第四步 创建连接
ssh.connect(hostname=hostname,username=username,password=password)
# 第五步 执行命令( exec_command() )并获取结果
stdin,stdout,stderr = ssh.exec_command('free -m')
# 打印结果
#print(stdout.read())
print('=' * 30)
# 也可以使用 readlines()
print( stdout.readlines() )
# 第六步 关闭连接
ssh.close()
paramiko 核心组件
paramiko 包含了两个核心组件:
SSHClient 类 和 SFTPClient 类
SSHClient 类
SSHClient 类通常用于执行远程命令,有以下几个方法:
1. connect 方法
实现远程 SSH 连接并校验
使用方式:
connect(self, # 类的实例化对象本身
hostname, # str 类型,连接的目标主机地址,IP/FQDN;
port=22, # int 类型,连接的目标主机端口号,默认 22;
username=None, # str 类型, 校验的用户名,默认是当前本地用户名;
pasword=None, # str 类型, 校验的用户名密码,用于校验或解锁私钥;
pkey=None, # PKey 类型,本地私钥,用于使用私钥方式的身份验证;
key_filename=None, # str 或 list 类型,一个文件名或文件名的列表;
timeout=None, # float 类型,一个可选的超时时间(单位:秒)的TCP链接;
allow_agent=True, # bool 类型,设置为 False 时禁止连接到代理;
look_for_keys=True, # bool 类型,设置为 False 时禁止在 ~/.ssh 中搜索密钥文件;
compress=False # bool 类型,设置为 True 时打开压缩。
)
2. exec_command 方法
用于远程执行命令,该命令的输入与输出流水为:标准输入(stdin),标准输出(stdout),标准错误输出(stderr)的Python对象
方法定义:
exec_command(self,
command, # str 类型,执行的命令串;
bufsize=-1 # int 类型,文件缓冲区大小,默认为 -1 (不限制)。
)
3. load_system_host_keys
用于加载本地保存的公钥校验文件(这些公钥都是连接的目标主机的公钥,用于加密要发送给目标主机的信息),默认为 ~/.ssh/known_hosts,
非默认路径情况下,要手工指定,方法定义:
load_system_host_keys(self,
filename=None # str 类型,指定远程主机公钥的记录文件。
)
4. set_missing_host_key_policy
用于在首次建立 SSH 连接的情况下,设置对于收到远程主机的公钥的处理方式;目前支持三种处理方式:AutoAddPolicy,RejectPolicy(默认),
WarningPolicy,仅限于 SSHClient 类,方法定义:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(self,
paramiko.RejectPolicy # 自动拒绝未知的主机名和密钥,依赖 load_system_host_keys() 的配置;
paramiko.AutoAddPolicy # 自动添加一个未知的主机名和主机的公钥到本地 HostKeys 对象,并将其
保存,若默认的 ~/.ssh/known_hosts文件不存在则建立;
paramiko.WarningPolicy # 同 AutoAddPolicy ,只是会发出警告信息;
)
常用示例
基于公钥密钥连接:
import paramiko,os
print(os.system('id'))
# 指定自己的私钥文件
private_key = paramiko.RSAKey.from_private_key_file('/root/.ssh/id_rsa')
# 创建SSH对象
ssh = paramiko.SSHClient()
# 允许连接不在know_hosts文件中的主机
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 即使known_hosts 文件中没有彼此的公钥也没关系
# 连接服务器
ssh.connect(hostname='192.168.56.129', port=22, username='root', pkey=private_key)
# 执行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 获取命令结果
result = stdout.read()
print(result)
# 关闭连接
ssh.close()
SFTPClient 类
SFTPClient 用于和远程主机直接的文件上传、下载、创建目录、删除目录等功能,需要注意的是,put 和 get 方法需要指定文件名,不能省略。
有以下几个方法:
首先要创建一个通道对象
t = paramiko.Transport(('192.168.56.128',22))
再进行认证链接
t.connect(username='root',password='upsa')
这时候我们就创建了一个已通过认证的传说对象,接下来可以用这个对象使用以下方法了
1. from_transport 方法
用于创建一个已连通的 SFTP 客户端通道,方法定义:
from_transport(cls,
t, # 一个开放的已认证的传输对象
window_size=None, # 为sftpclient会话可选的窗口的大小,一般不设置,设置了会影响速度
max_packet_size=None # 为sftpclient会话可选的最大数据包大小。
)
返回的是一个新的stpfclient 对象,指的是用于传输的SFTP会话通道
用法:
t = paramiko.Transport(('192.168.56.128',22))
t.connect(username='root',password='upsa')
sftp = paramiko.SFTPClient.from_transport(t)
2. put 方法
用于上传本地文件到远程主机,方法定义:
put(self,
localpath, # str 类型,本地文件的路径,最好是绝对路径;
remotepath, # str 类型,在目标主机上的目标路径,应该包含文件名。仅指定目录可能报错;
callback=None, # 可选的回调函数,(用法:callback(func(int,int)))获取当前已经接收的字节和传输的总字节数
confirm=True # bool 类型,文件上传完毕后是否调用stat() 方法,以便确认文件的大小。
)
用法示例:
localpath='/home/access.log'
remotepath='/backup/log/access.log.back'
sftp.put(localpath,remotepath)
3. get 方法
get(self, remotepath, localpath, callback=None)
参数基本和 put 的参数意思一样,只是刚好相反,这里不再赘述。
用法也一样
4. 其他方法介绍
mkdir # 在远程主机上创建目录,如: sftp.mkdir('/home/testdir',0o0755) 后面的权限是 八进制的 int 类型
rmdir # 在远程主机上删除一个空目录, 如: sftp.rmdir('/home/testdir',)
remove # 在远程主机上移除指定路径下的文件,如: sftp.remove('/home/testdir/testfile')
rename # 在远程主机上重命名文件或目录,如: sftp.rename('/home/testdir','/home/userdir')
stat # 获取远程主机上指定文件信息,如: sftp.stat('/home/userdir/testfile.txt')
listdir # 获取远程主机上指定目录下的文件列表,返回的是Python的列表形式
SFTPClient 类的简单应用
import paramiko
username = 'root'
password = 'upsa'
hostname = '192.168.56.129'
port = 22
try:
t = paramiko.Transport((hostname,port))
t.connect(username=username,password=password)
sftp = paramiko.SFTPClient.from_transport(t)
sftp.put('/root/anaconda-ks.cfg','/home/anaconda-ks.cfg')
sftp.get('/home/anaconda-ks.cfg','/root/install.info')
sftp.mkdir('/home/testdir/',0o755)
# sftp.rmdir('/home/testdir')
print(sftp.listdir('/home'))
except Exception as ex:
print(ex)
封装SSHClient 和 SFTPClient
import paramiko
class SshHelper(object):
def __init__(self,host,port,username,pwd):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.transport = None
def connect(self):
transport = paramiko.Transport((self.host, self.port,))
transport.connect(username=self.username, password=self.pwd)
self.transport = transport
def upload(self,local,target):
sftp = paramiko.SFTPClient.from_transport(self.transport)
# 将location.py 上传至服务器 /tmp/test.py
sftp.put(local, target)
# 将remove_path 下载到本地 local_path
# sftp.get('remove_path', 'local_path')
def cmd(self,shell):
ssh = paramiko.SSHClient()
ssh._transport = self.transport
stdin, stdout, stderr = ssh.exec_command(shell)
stdout.read()
def close(self):
self.transport.close()
if __name__ == '__main__':
obj = SshHelper('...')
obj.connect()
obj.close()