什么是webshell ?

shell是一个集成了一堆linux命令的控制台界面

安装xterm

1
cnpm install xterm@3.1.0 --save

导入css样式,main.js

1
import 'xterm/dist/xterm.css'

在页面里放入一个id对的上的div

1
2
3
<div id="terminal">
<!-- 黑窗口-->
</div>

添加插件

1
2
3
4
5
6
import { Terminal } from 'xterm'
import * as attach from 'xterm/lib/addons/attach/attach' // 安装插件适,可以使用attach去添加
import * as fit from 'xterm/lib/addons/fit/fit' // fit进行自适应大小的

Terminal.applyAddon(attach) // 添加插件
Terminal.applyAddon(fit) // 添加插件

mounted初始化div标签id为terminal对象,成为一个真正的黑窗口

1
2
3
4
5
6
// 获取到了div标签
let terminalContainer = document.getElementById('terminal')
// 初始化黑窗口对象
this.term = new Terminal(this.terminal)
// 打开这个对象
this.term.open(terminalContainer)

vue连接webshell ?

1
2
3
4
5
6
7
8
9
10
11
12
new WebSocket('ws://127.0.0.1:8000/webssh/')

this.terminalSocket = new WebSocket('ws://127.0.0.1:8000/webssh/')
this.terminalSocket.onopen = function(){ // 连接成功触发该方法
console.log('websocket is Connected...')
}
this.terminalSocket.onclose = function(){ // 连接关闭适触发的方法
console.log('websocket is Closed...')
}
this.terminalSocket.onerror = function(){ // 连接出错触发的方法
console.log('damn Websocket is broken!')
}

绑定黑窗口

1
this.term.attach(this.terminalSocket)

django接收websocket

下载dwebsocket

pip3 install dwebsocket

settings安装该模块,INSTALL_APPS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@accept_websocket
def webssh(request):
# 1. 获取到连接对象
ws = request.websocket
while 1: # 主线程: 只管发送
# 2. 阻塞ws接收发来的数据
cmd = ws.wait()
if cmd:
channel.send(cmd) # 发送到linux 去执行
else: # 如果连接断开,那么cmd将会发一个空包
break
recv_thread.join() # 回收子线程
ws.close() # 关闭ws连接

如何发送输入来的cmd给linux呢

黑窗口进入python输入

1
pip3 install paramiko

paramiko如何连接linux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def make_ssh(host, username, password, port=22):
"""
:host 主机地址
:username 用户名,一般是root
:password 密码
:port ssh协议的端口,22
"""
# 初始化一个ssh对象
sh = paramiko.SSHClient()
# 设置对象连接密钥规则
sh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接
sh.connect(host, username=username, password=password)
# 生成shell对象,把命令执行结果,模拟成一个终端的返回,带上花里胡哨的颜色
channle = sh.invoke_shell(term='xterm')
return channle

编写子线程方法,接收命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def recv_ssh_msg(channle, ws):
'''
channle: 建立好的SSH连接通道
这个函数会不停的接收ssh通道返回的命令
返回到前端的ws套接字里
'''
# 判断shell连接对象是否没有退出
while not channle.exit_status_ready():
# 接收过程可能会因为没有任何返回而报错
try:
buf = channle.recv(1024) # 接收命令的执行结果
ws.send(buf) # 向Websocket通道返回
# 接收不到会报错,但是报错没关系,继续重新尝试接受
except:
break