Paramiko
Paramiko
是SSHv2
协议的Python
实现,提供客户端和服务器功能
Paramiko
本身是一个围绕SSH
网络概念的纯Python
接口
利用paramiko
我们可以通过Python
方便的进行ssh
操作
paramiko
包含两个核心组件:SSHClient
和SFTPClient
SSHClient
SSHClient
的作用类似于Linux
的ssh
命令,是对SSH
会话的封装
该类封装了传输Transport
,通道Channel
及SFTPClient
建立的方法open_sftp
,通常用于执行远程命令
API
class paramiko.client.SSHClient
创建SSH
客户端实例
SSHClient.connect(hostname, port=22, username=None, password=None, pkey=None, key_filename=None, timeout=None, allow_agent=True, look_for_keys=True, compress=False..)
python
# 参数解释
- hostname:连接的目标主机
- port=SSH_PORT:指定端口
- username=None:验证的用户名
- password=None:验证的用户密码
- pkey=None:私钥方式用于身份验证
- key_filename=None:一个文件名或文件列表,指定私钥文件
- timeout=None:可选的tcp连接超时时间
- allow_agent=True:是否允许连接到ssh代理,默认为True 允许
- look_for_keys=True:是否在~/.ssh中搜索私钥文件,默认为True 允许
- compress=False:是否打开压缩
通过验证连接远程服务端
SSHClient.exec_command(command, bufsize=-1, timeout=None, get_pty=False, environment=None)
python
# 参数解释
- command:要执行的命令
- bufsize:与Python中文件对象的同名函数解释相同,缓冲区大小
- timeout:设置命令的超时相应事件
- get_pty:从服务器请求一个伪终端(默认为假)
- environment:一个当前shell环境的字典,远程命令的默认执行环境
command
参数为要执行的shell
命令,打开一个新通道并执行请求的命令
该函数的返回结果为一个元组,其中包含stdin
、stdout
和stderr
,也就是我们常见的标准输入,输出以及出错
一般来说,命令的结果我们将通过stdout
进行获取
SSHClient.close()
关闭
SSH
连接
SSHClient.invoke_shell(term='vt100', width=80, height=24, width_pixels=0, height_pixels=0, environment=None)
python
# 参数解释
- term:模拟终端类型
- width:终端长度
- height:终端宽度
- width_pixels:终端的像素宽度
- height_pixels:终端的像素高度
- environment:命令的shell环境
在ssh
服务器上启动交互式shell
会话
一个新的通道被打开并连接到,使用请求的终端类型和大小的伪终端,并作为返回值
换句通俗的话来讲,就是创建了一个实际的shell
窗口空间进行命令交互
SSHClient.set_missing_host_key_policy(policy)
设置连接到没有已知主机密钥的服务器时要使用的策略
常见使用策略为paramiko.client.AutoAddPolicy
,其意义为自动将主机名和新主机密钥添加到本地主机密钥对象并保存
实例代码
以下是一个简单的通过
SSHClient
建立的通道进行命令的传输与返回结果的获取的代码!
python
import paramiko
def connect(hostname,username,password):
client = paramiko.SSHClient()
# 初始化
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 设置密钥策略
client.connect(hostname,username=username,password=password)
# 连接主机
return client
def exec_cmd(client,cmd):
stdin,stdout,stderr = client.exec_command(cmd)
return stdout.read().decode(),stderr.read().decode()
def main():
hostname = '192.168.0.104'
username = 'pi'
password = '123456'
cmd = 'ps -aux'
client = connect(hostname,username,password)
res = exec_cmd(client, cmd)
if res[0]:
print(res[0])
if res[1]:
print('[E]:\n',res[1])
client.close()
if __name__ == '__main__':
main()
上面的代码通过默认建立好的连接对象进行命令的传输以及返回结果的获取
invoke_shell
- 接下来使用
invoke_shell
进行虚拟终端的连接,首先初始化SSH
通道
python
class SSHChannle:
def __init__(self, host, username, password, port=22):
'''
初始化SSH通道
'''
self.sh = paramiko.SSHClient()
self.sh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.sh.connect(host, username=username, password=password)
self.channle = self.sh.invoke_shell()
- 思路为开启两个线程,分别负责命令的接收与命令的发送
python
def get_ssh_recv(self):
'''
接收SSH通道中发来的消息
'''
while not self.channle.exit_status_ready():
# 如果远程进程已退出并返回退出状态,则返回true
time.sleep(0.1)
try:
buf = self.channle.recv(1024).decode('utf-8')
print(buf,end='')
sys.stdout.flush()
except Exception as ex:
print(ex)
python
def send_ssh_cmd(self):
'''
发送命令给SSH通道
'''
while not self.channle.exit_status_ready():
cmd = input()
try:
self.channle.send(cmd + '\r')
except Exception as ex:
print(ex)
sys.stdin.flush()
- 在实例中定义
run
函数用来开启两个线程并负责线程的资源回收以及SSH通道的关闭
python
def run(self):
ssh_recv_thread = threading.Thread(target=self.get_ssh_recv)
ssh_send_thread = threading.Thread(target=self.send_ssh_cmd)
ssh_recv_thread.start()
ssh_send_thread.start()
ssh_recv_thread.join()
ssh_send_thread.join()
self.sh.close() # 关闭通道
- 在
win
下的CMD
中查看效果,其中的乱码格式其实为连接后命令传输的特殊标记格式,可以在后面结合前端中类似xterm.js
等插件查看到实际花里胡哨的效果