momo's Blog.

WebSSH功能简单实现

字数统计: 650阅读时长: 3 min
2020/09/13 Share

前言

前几天学习了django-channels如何基于ws建立聊天室, 针对于ws在运维方面实际用途还是很多的.
今天基于ws,做一个webssh的小案例
用到的新模块

使用WebSSH操控远程服务器

在学习之前,需要简单了解一下paramiko的基本使用

1
2
3
4
5
6
7
8
9
10
11
# 实例化SSHclient
self.ssh = paramiko.SSHClient()

#当远程服务器没有添加本地host秘钥时,将自动添加.无需使用yes or no
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)

# 连接远程服务器, 也可只用秘钥连接
self.ssh.connect(hostname="192.168.233.128", port=22, username="root", password="123456")

# 打开ssh channel。保持长连接,并设置终端大小
self.chan = self.ssh.invoke_shell(width=200, height=50)

建立channel以后,可以通过channel的send()方法向远程服务器发送数据.也可以通过recv()方法接受数据.

基本思路和实现步骤

我们需要在前端页面绘制出一个终端,并建立ws连接,后端建立连接前,使用paramiko 建立SSH channel

当建立SSH连接成功以后,启动一个线程来循环监听发送和接受数据发送到前后端。

后端实现

完整的consumer代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
from channels.generic.websocket import WebsocketConsumer
import paramiko
import threading


class WebSSH(threading.Thread):
def __init__(self, chan, consum):
super(WebSSH, self).__init__()
self.chan = chan
self.consum = consum

def run(self):
while not self.chan.exit_status_ready():
try:
data = self.chan.recv(1024)
self.consum.send(data.decode())
except Exception as ex:
print(str(ex))


class ChatConsumer(WebsocketConsumer):
def connect(self):
try:
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy)
self.ssh.connect(hostname="192.168.233.128", port=22, username="root", password="123456")
self.chan = self.ssh.invoke_shell(width=200, height=50)
except Exception:
self.close()
self.accept()
self.a = WebSSH(self.chan, self)
self.a.setDaemon(True)
self.a.start()

def disconnect(self, close_code):
self.ssh.close()

def receive(self, text_data):
self.chan.send(text_data)

前端实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<template>
<div>
<h1>webssh</h1>
<div ref="xtermContainer"></div>
</div>
</template>

<script>
import { Terminal } from 'xterm'
import { FitAddon } from 'xterm-addon-fit'
import { AttachAddon } from 'xterm-addon-attach'

export default {
name: 'WebSSH',
mounted () {
const terminal = new Terminal({
rows: 35,
cursorBlink: true,
disableStdin: false
})
const ws = new WebSocket('ws://127.0.0.1:8001/ws/webssh')
const fitAddon = new FitAddon()
const attachAddon = new AttachAddon(ws)
terminal.loadAddon(fitAddon)
// 参数为ws
terminal.loadAddon(attachAddon)
// 打开终端
terminal.open(this.$refs.xtermContainer)
// 获取焦点
terminal.focus()
// 重新设置 窗口大小
terminal.resize(200, 50)
// 将终端全屏显示
fitAddon.fit()
console.log(terminal.cols, terminal.rows)
}
}
</script>

<style scoped>
</style>

目前到此已经可以实现了WebSSH的基本功能了,是不是很简单呢?

资料

CATALOG
  1. 1. 前言
  2. 2. 使用WebSSH操控远程服务器
    1. 2.1. 基本思路和实现步骤
      1. 2.1.1. 后端实现
      2. 2.1.2. 前端实现
  3. 3. 资料