python ssh paramiko_python使用paramiko实现ssh的功能详解

个人认为python的paramiko模块是运维人员必学模块之一,其ssh登录功能是旅行居家必备工具。

安装paramiko很简单,pip install paramiko就搞定了,其依赖库会被一并安装。

paramiko的官方站点在这里:http://www.paramiko.org/。有需要深入研究的可以阅读官方文档。

paramiko模块提供了ssh及sft进行远程登录服务器执行命令和上传下载文件的功能。

一、基于用户名和密码的 sshclient 方式登录

# 建立一个sshclient对象

ssh = paramiko.SSHClient()

# 允许将信任的主机自动加入到host_allow 列表,此方法必须放在connect方法的前面

ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# 调用connect方法连接服务器

ssh.connect(hostname='192.168.2.129', port=22, username='super', password='super')

# 执行命令

stdin, stdout, stderr = ssh.exec_command('df -hl')

# 结果放到stdout中,如果有错误将放到stderr中

print(stdout.read().decode())

# 关闭连接

ssh.close()

二、基于用户名和密码的 transport 方式登录

方法1是传统的连接服务器、执行命令、关闭的一个操作,有时候需要登录上服务器执行多个操作,比如执行命令、上传/下载文件,方法1则无法实现,可以通过如下方式来操作

# 实例化一个transport对象

trans = paramiko.Transport(('192.168.2.129', 22))

# 建立连接

trans.connect(username='super', password='super')

将sshclient的对象的transport指定为以上的trans

ssh = paramiko.SSHClient()

ssh._transport = trans

执行命令,和传统方法一样

stdin, stdout, stderr = ssh.exec_command('df -hl')

print(stdout.read().decode())

关闭连接

trans.close()

三、 基于公钥密钥的 SSHClient 方式登录

# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数

pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')

# 建立连接

ssh = paramiko.SSHClient()

ssh.connect(hostname='192.168.2.129',

port=22,

username='super',

pkey=pkey)

# 执行命令

stdin, stdout, stderr = ssh.exec_command('df -hl')

# 结果放到stdout中,如果有错误将放到stderr中

print(stdout.read().decode())

# 关闭连接

ssh.close()

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

四、 基于密钥的 Transport 方式登录

# 指定本地的RSA私钥文件,如果建立密钥对时设置的有密码,password为设定的密码,如无不用指定password参数

pkey = paramiko.RSAKey.from_private_key_file('/home/super/.ssh/id_rsa', password='12345')

# 建立连接

trans = paramiko.Transport(('192.168.2.129', 22))

trans.connect(username='super', pkey=pkey)

将sshclient的对象的transport指定为以上的trans

ssh = paramiko.SSHClient()

ssh._transport = trans

执行命令,和传统方法一样

stdin, stdout, stderr = ssh.exec_command('df -hl')

print(stdout.read().decode())

关闭连接

trans.close()

五、传文件 SFTP

# 实例化一个trans对象# 实例化一个transport对象

trans = paramiko.Transport(('192.168.2.129', 22))

# 建立连接

trans.connect(username='super', password='super')

实例化一个 sftp对象,指定连接的通道

sftp = paramiko.SFTPClient.from_transport(trans)

发送文件

sftp.put(localpath='/tmp/11.txt', remotepath='/tmp/22.txt')

下载文件

sftp.get(remotepath, localpath)

trans.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()

注意:在windows中,sys.stdin不是一个socket或者file-like对象,而是一个PseudoOutputFile对象,不能被select处理。所以上面的脚本不能在windows中运行,只能用于linux。

七、上例支持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()

八、 SSH服务端的实现

实现SSH服务端必须继承ServerInterface,并实现里面相应的方法。具体代码如下:

import socket

import sys

import threading

import paramiko

host_key = paramiko.RSAKey(filename='private_key.key')

class Server(paramiko.ServerInterface):

def init(self):

执行start_server()方法首先会触发Event,如果返回成功,is_active返回True

self.event = threading.Event()

当is_active返回True,进入到认证阶段

def check_auth_password(self, username, password):

if (username == 'root') and (password == '123456'):

return paramiko.AUTH_SUCCESSFUL

return paramiko.AUTH_FAILED

当认证成功,client会请求打开一个Channel

def check_channel_request(self, kind, chanid):

if kind == 'session':

return paramiko.OPEN_SUCCEEDED

命令行接收ip与port

server = sys.argv[1]

ssh_port = int(sys.argv[2])

建立socket

try:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP socket

sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

sock.bind((server, ssh_port))

sock.listen(100)

print '[+] Listening for connection ...'

client, addr = sock.accept()

except Exception, e:

print '[-] Listen failed: ' + str(e)

sys.exit(1)

print '[+] Got a connection!'

try:

用sock.accept()返回的socket实例化Transport

bhSession = paramiko.Transport(client)

添加一个RSA密钥加密会话

bhSession.add_server_key(host_key)

server = Server()

try:

启动SSH服务端

bhSession.start_server(server=server)

except paramiko.SSHException, x:

print '[-] SSH negotiation failed'

chan = bhSession.accept(20)

print '[+] Authenticated!'

print chan.recv(1024)

chan.send("Welcome to my ssh")

while True:

try:

command = raw_input("Enter command:").strip("\n")

if command != 'exit':

chan.send(command)

print chan.recv(1024) + '\n'

else:

chan.send('exit')

print 'exiting'

bhSession.close()

raise Exception('exit')

except KeyboardInterrupt:

bhSession.close()

except Exception, e:

print '[-] Caught exception: ' + str(e)

try:

bhSession.close()

except:

pass

sys.exit(1)

到此这篇关于python使用paramiko实现ssh的功能详解的文章就介绍到这了,更多相关python paramiko实现ssh内容请搜索菜鸟教程www.piaodoo.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持菜鸟教程www.piaodoo.com!

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ParamikoPython中用于SSH协议的一个库,可以用于远程登录、传输文件等操作。下面是Paramiko库的详解: 1. 安装 使用pip进行安装: ```python pip install paramiko ``` 2. 连接远程服务器 ```python import paramiko # 创建SSH客户端 ssh = paramiko.SSHClient() # 自动添加主机密钥 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接远程服务器 ssh.connect('hostname', port=22, username='username', password='password') # 执行命令 stdin, stdout, stderr = ssh.exec_command('ls') # 输出命令执行结果 print(stdout.read().decode()) # 关闭连接 ssh.close() ``` 3. 传输文件 ```python import paramiko # 创建SSH客户端 ssh = paramiko.SSHClient() # 自动添加主机密钥 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接远程服务器 ssh.connect('hostname', port=22, username='username', password='password') # 创建SFTP客户端 sftp = ssh.open_sftp() # 上传文件 sftp.put('local_path', 'remote_path') # 下载文件 sftp.get('remote_path', 'local_path') # 关闭连接 sftp.close() ssh.close() ``` 4. 高级用法 - 使用密钥登录 ```python import paramiko # 创建SSH客户端 ssh = paramiko.SSHClient() # 自动添加主机密钥 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 密钥文件路径 key_path = '/root/.ssh/id_rsa' # 密钥密码,如果没有设置则为None key_password = 'password' # 密钥对象 private_key = paramiko.RSAKey.from_private_key_file(key_path, password=key_password) # 连接远程服务器 ssh.connect('hostname', port=22, username='username', pkey=private_key) # 执行命令 stdin, stdout, stderr = ssh.exec_command('ls') # 输出命令执行结果 print(stdout.read().decode()) # 关闭连接 ssh.close() ``` - 自定义日志 ```python import paramiko import logging # 创建SSH客户端 ssh = paramiko.SSHClient() # 自动添加主机密钥 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 创建日志记录器 logger = logging.getLogger('paramiko') logger.setLevel(logging.DEBUG) # 创建日志处理器 handler = logging.StreamHandler() handler.setLevel(logging.DEBUG) # 创建日志格式化器 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) # 添加日志处理器 logger.addHandler(handler) # 连接远程服务器 ssh.connect('hostname', port=22, username='username', password='password') # 执行命令 stdin, stdout, stderr = ssh.exec_command('ls') # 输出命令执行结果 print(stdout.read().decode()) # 关闭连接 ssh.close() ``` 总之,Paramiko库是Python中一个非常强大的SSH协议库,其功能十分丰富,可以满足大部分远程操作的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值