以前笔者写过 一篇文章-SSH交互式通信总结:expect、plink、putty、sshpass、ALAB SSH 。最近在做python运维方面的东西,paramiko库是Python用于实现了SSHv2协议,对远程服务器进行操作,又多了一个方式来完成SSH通信。
在Windows平台下工具较少,paramiko库对于操作很多服务器来说是个很好的工具。
一、安装模块 paramiko
pip install paramiko
paramiko包含两个核心组件:SSHClient和SFTPClient。
二、SSHClient
SSHClient类是SSH服务会话的高级表示,该类封装了传输(transport)、通道(channel)及SFTPClient的校验、建立的方法,通常用于执行远程命令。
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命令的方法。
那么接下来测试一下。
1、密码连接
import paramiko
hostname='mywsl'
port=222
username='mycentos'
password='mycentos'
command='free -m'
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.RejectPolicy)
client.connect(hostname=hostname, port=port, username=username, password=password)
stdin, stdout, stderr = client.exec_command(command)
print(stdout.read().decode('utf-8'))
client.close()
笔者把.ssh下面的known_hosts删除,同时设置的连接策略是paramiko.RejectPolicy。运行上面的脚本出现错误:not found in known_hosts 。
更改为WarningPolicy后,可以运行成功,但是会出现告警: UserWarning: Unknown ssh-ed25519 host key 。
最后更改为AutoAddPolicy后,自动添加,运行成功。需要注意的是自动添加并不是添加到主机的.ssh下面的known_hosts里面。在cmd里面另外ssh时,同样会提示yes/no。
2、密钥连接
import paramiko
hostname='mywsl'
port=222
username='mycentos'
command='free -m'
private = paramiko.RSAKey.from_private_key_file('C:/Users/Administrator/.ssh/id_rsa')
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy)
client.connect(hostname=hostname, port=port, username=username, pkey=private)
stdin, stdout, stderr = client.exec_command(command)
print(stdout.read().decode('utf-8'))
client.close()
指定密钥地址,将connect中的password替换为pkey。但是前提是已经配置好免密的情况下,即对端有公钥存在才会执行成功。不指定private,如果密钥在默认的用户.ssh目录下,也可以连接成功。
三、SFTPClient
SFTPCLient作为一个sftp的客户端对象,根据ssh传输协议的sftp会话,实现远程文件操作,如上传、下载、权限、状态。
-from_transport(cls,t) 创建一个已连通的SFTP客户端通道
-put(localpath, remotepath, callback=None, confirm=True) 将本地文件上传到服务器
-get(remotepath, localpath, callback=None) 从服务器下载文件到本地
-mkdir() 在服务器上创建目录
-remove() 在服务器上删除目录
-rename() 在服务器上重命名目录
-stat() 查看服务器文件状态
-listdir() 列出服务器目录下的文件
import paramiko
hostname='mywsl'
port=222
username='mycentos'
password='mycentos'
tran = paramiko.Transport((hostname,port))
tran.connect(username=username, password=password)
#private = paramiko.RSAKey.from_private_key_file('C:/Users/Administrator/.ssh/id_rsa')
#tran.connect(username=username, pkey=private)
sftp = paramiko.SFTPClient.from_transport(tran)
localpath = "C:/Users/Administrator/Desktop/clear_buffcache.sh"
remotepath = "/home/mycentos/myshells/clear_buffcache.sh"
#sftp.put(localpath, remotepath)
sftp.get(remotepath, localpath)
tran.close()
put和get方法需要指定文件名,不能省略。和上面的类似,运行后密钥结果显示,只是目的目录有get到文件。
网友评论