1、paramiko模块介绍

paramiko模块提供了基于ssh连接,进行远程登录服务器执行命令和上传下载文件的功能。这是一个第三方的软件包,使用之前需要安装。

2、paramiko的使用方法

(1)基于用户名和密码的sshclient方式登陆

#!/usr/bin/env python
#coding:utf8 import paramiko
#创建sshclient对象
ssh = paramiko.SSHClient()
#允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#调用connect方法连接服务器
ssh.connect(hostname='172.16.32.129',port=2323,username='root',password='123.com')
while True:
input_command = input('>>>:')
if input_command == 'quit':
break
#执行命令,输出结果在stdout中,如果是错误则放在stderr中
stdin,stdout,stderr = ssh.exec_command(input_command)
result = stdout.read() #read方法读取输出结果
if len(result) == 0: #判断如果输出结果长度等于0表示为错误输出
print(stderr.read())
else:
print(str(result,'utf-8'))
ssh.close()

封装方法,隐藏属性:

#config.ini文件
[ssh]
host=172.16.32.129
port=2323
user=root
pwd=123.com
timeout=1.1 #封装ssh类
#!/usr/bin/env python
#coding:utf8
import configparser,paramiko
class parmikoclient(object):
def __init__(self,ini_file):
self.config=configparser.ConfigParser()
self.config.read(ini_file)
self.host = self.config.get('ssh','host')
self.port = self.config.get('ssh', 'port')
self.user = self.config.get('ssh', 'user')
self.pwd = self.config.get('ssh', 'pwd')
self.timeout = self.config.get('ssh', 'timeout')
self.client=paramiko.SSHClient()
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.client.connect(hostname=self.host,port=self.port,username=self.user,password=self.pwd,timeout=float(self.timeout))
def run_ssh(self,cmd_command):
# 执行命令,输出结果在stdout中,如果是错误则放在stderr中
stdin,stdout,stderr = self.client.exec_command(cmd_command)
result = stdout.read() # read方法读取输出结果
if len(result) == 0: # 判断如果输出结果长度等于0表示为错误输出
print(stderr.read().decode())
else:
print(str(result, 'utf-8'))
def close(self):
self.client.close()
if __name__ == '__main__':
client_cmd = parmikoclient('config.ini')
while True:
cmd_input=input('>>>:')
client_cmd.run_ssh(cmd_input)
if cmd_input == 'quit':
client_cmd.close()

通过transport方式登录:

#!/usr/bin/env python
#coding:utf8
import paramiko
#实例化一个transport对象
transport = paramiko.Transport(('172.16.32.129',2323))
#建立连接
transport.connect(username='root',password='')
#建立ssh对象
ssh = paramiko.SSHClient()
#绑定transport到ssh对象
ssh._transport=transport
#执行命令
stdin,stdout,stderr=ssh.exec_command('df')
#打印输出
print(stdout.read().decode())
#关闭连接
transport.close()

(2)基于密钥的sshclient方式登陆

#!/usr/bin/env python
#coding:utf8
#必须先将公钥文件传输到服务器的~/.ssh/authorized_keys中
import paramiko
# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数
pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024') #建立连接
ssh = paramiko.SSHClient()
#允许将信任的主机自动加入到known_hosts列表
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='172.16.32.129',port=2323,username='root',pkey=pkey) #指定密钥连接
#执行命令
stdin,stdout,stderr=ssh.exec_command('free -m')
print(stdout.read().decode())
ssh.close()

以上需要确保被访问的服务器对应用户.ssh目录下有authorized_keys文件,也就是将服务器上生成的公钥文件保存为authorized_keys。并将私钥文件作为paramiko的登陆密钥

transport封装密钥登陆:

#!/usr/bin/env python
#coding:utf8
#必须先将公钥文件传输到服务器的~/.ssh/authorized_keys中
import paramiko
# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数
pkey = paramiko.RSAKey.from_private_key_file('id_rsa_1024') #创建transport对象绑定主机和端口,指定用户和密钥连接
transport = paramiko.Transport(('172.16.32.129',2323))
transport.connect(username='root',pkey=pkey)
ssh = paramiko.SSHClient()
ssh._transport = transport #类属性赋值
#允许将信任的主机自动加入到known_hosts列表
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #执行命令
stdin,stdout,stderr=ssh.exec_command('free -m')
print(stdout.read().decode())
ssh.close()

(3)SFTP文件传输

#!/usr/bin/env python
#coding:utf8 import paramiko
#实例化transport对象,并建立连接
transport = paramiko.Transport(('172.16.32.129',2323))
transport.connect(username='root',password='123.com')
#实例化sftp对象,指定连接对象
sftp = paramiko.SFTPClient.from_transport(transport)
#上传文件
sftp.put(localpath='id_rsa_1024',remotepath='/root/idrsa1024.txt')
#下载文件
sftp.get(remotepath='/root/idrsa1024.txt',localpath='idrsa1024_back.txt')
#关闭连接
transport.close()

实现一个类似xshell工具的功能,登录以后可以输入命令回车后就返回结果:

import paramiko
import os
import select
import sys # 建立一个socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 启动一个客户端
trans.start_client() # 如果使用rsa密钥登录的话
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用户名和密码登录
trans.auth_password(username='super', password='super')
# 打开一个通道
channel = trans.open_session()
# 获取终端
channel.get_pty()
# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样
channel.invoke_shell()
# 下面就可以执行你所有的操作,用select实现
# 对输入终端sys.stdin和 通道进行监控,
# 当用户在终端输入命令后,将命令交给channel通道,这个时候sys.stdin就发生变化,select就可以感知
# channel的发送命令、获取结果过程其实就是一个socket的发送和接受信息的过程
while True:
readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
# 如果是用户输入命令了,sys.stdin发生变化
if sys.stdin in readlist:
# 获取输入的内容
input_cmd = sys.stdin.read(1)
# 将命令发送给服务器
channel.sendall(input_cmd) # 服务器返回了结果,channel通道接受到结果,发生变化 select感知到
if channel in readlist:
# 获取结果
result = channel.recv(1024)
# 断开连接后退出
if len(result) == 0:
print("\r\n**** EOF **** \r\n")
break
# 输出到屏幕
sys.stdout.write(result.decode())
sys.stdout.flush() # 关闭通道
channel.close()
# 关闭链接
trans.close()

支持tab自动补全

import paramiko
import os
import select
import sys
import tty
import termios '''
实现一个xshell登录系统的效果,登录到系统就不断输入命令同时返回结果
支持自动补全,直接调用服务器终端 '''
# 建立一个socket
trans = paramiko.Transport(('192.168.2.129', 22))
# 启动一个客户端
trans.start_client() # 如果使用rsa密钥登录的话
'''
default_key_file = os.path.join(os.environ['HOME'], '.ssh', 'id_rsa')
prikey = paramiko.RSAKey.from_private_key_file(default_key_file)
trans.auth_publickey(username='super', key=prikey)
'''
# 如果使用用户名和密码登录
trans.auth_password(username='super', password='super')
# 打开一个通道
channel = trans.open_session()
# 获取终端
channel.get_pty()
# 激活终端,这样就可以登录到终端了,就和我们用类似于xshell登录系统一样
channel.invoke_shell() # 获取原操作终端属性
oldtty = termios.tcgetattr(sys.stdin)
try:
# 将现在的操作终端属性设置为服务器上的原生终端属性,可以支持tab了
tty.setraw(sys.stdin)
channel.settimeout(0) while True:
readlist, writelist, errlist = select.select([channel, sys.stdin,], [], [])
# 如果是用户输入命令了,sys.stdin发生变化
if sys.stdin in readlist:
# 获取输入的内容,输入一个字符发送1个字符
input_cmd = sys.stdin.read(1)
# 将命令发送给服务器
channel.sendall(input_cmd) # 服务器返回了结果,channel通道接受到结果,发生变化 select感知到
if channel in readlist:
# 获取结果
result = channel.recv(1024)
# 断开连接后退出
if len(result) == 0:
print("\r\n**** EOF **** \r\n")
break
# 输出到屏幕
sys.stdout.write(result.decode())
sys.stdout.flush()
finally:
# 执行完后将现在的终端属性恢复为原操作终端属性
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, oldtty) # 关闭通道
channel.close()
# 关闭链接
trans.close()
05-07 15:33