暂无图片
暂无图片
暂无图片
暂无图片
1
暂无图片

Xterm+Websocket+Jsch实现Web端SSH

IT那活儿 2020-12-24
7083
前 言

   最近由于项目需要,要在web端实现类似secureCRT的功能。首先想到在Github上看下有没有现成的轮子,找了一圈没看到合适的。于是结合着开源的资料,实现了一套适合本地项目的基于Springboot和Vue前后端分离版本的网页端SSH。

技术选型

 项目中前端使用vue,由于vue无法直接发起SSH通信,所以还需要一个后端来接受并发起SSH请求,后端自然就选择开发效率很高的Springboot框架了。

我们来分析一下需求。首先需要有个交互界面,模拟terminal终端;其次还需要前后端通讯,需要支持前端发命令到后端以及后端将请求结果发送回前端;最后在后端还需要能处理SSH命令的逻辑。基于以上三点需求,最终的技术选型就是Xterm.js+ Websocket + Jsch组合。

Xterm.js

Xterm是一个使用TypeScript编写的前端终端组件,可以直接在浏览器中实现一个命令行终端应用。

Websocket

WebSocket是一种在单个TCP连接上进行全双工通信的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

Jsch

Jsch即JavaSecureChannel,Jsch是SSH2的一个纯Java实现。它允许你连接到一个sshd服务器,使用端口转发,X11转发,文件传输等等。

前端实现

  前端主要功能如下:页面的实现、连接WebSocket并完成数据的接收以及回写、数据的发送。

 部分源码如下:

1、 首先引入以下依赖

Xterm.js

npm install --save xterm

xterm-addon-fit

xterm.js的插件,使终端的尺寸适合包含元素。

npm install --save xterm-addon-fit

2、 创建一个command界面组件terminal.vue

主要包括xterm的初始化和websocket发送接收消息的实现

<template>  <div id="xterm" class="xterm"/></template><script>import 'xterm/css/xterm.css'import {Terminal} from 'xterm'import {FitAddon} from 'xterm-addon-fit'export default {  name: "terminal",  props: {    // 终端信息    hostInfo: {type: Object},  },  mounted() {    this.initTerm();  },  beforeDestroy() {    this.socket.close();    this.term.dispose();  },  data() {    return {      term: null,      socket: null,    }  },  methods: {    //初始化Xterm    initTerm() {      const term = new Terminal({        cursorBlink: true, 光标闪烁        cursorStyle: "block", 光标样式  null | 'block' | 'underline' | 'bar'        scrollback: 800, 回滚        tabStopWidth: 8, 制表宽度        screenKeys: true,      });      const fitAddon = new FitAddon();      term.loadAddon(fitAddon);      term.open(document.getElementById('xterm'));      fitAddon.fit();      term.focus();      this.term = term;      this.initSocket();    },    //初始化websocket    initSocket() {      let endpoint = `${location.protocol === 'https' ? 'wss' : 'ws'}://${location.host}/ogg_server/webssh`;      if (window.WebSocket) {        this.socket = new WebSocket(endpoint);//如果支持websocket      } else {        this.term.write('Error: WebSocket Not Supported\r\n');//否则报错        return;      }      this.socketOnOpen();      this.socketOnMessage();      this.socketOnClose();      this.socketOnError();    },    socketOnOpen() {      this.socket.onopen = () => {        this.term.write('Connecting...\r\n');        this.socket.send(JSON.stringify({          operate: 'connect',          host: this.hostInfo.host,//IP          port: this.hostInfo.port,//端口号          username: this.hostInfo.username,//用户名          password: this.hostInfo.password//密码        }));        this.term.onData((data) => {          //发送指令          this.socket.send(JSON.stringify({"operate": "command", "command": data}));        });      }    },    socketOnMessage() {      let _this = this;      this.socket.onmessage = (evt) => {        let data = evt.data.toString();        _this.term.write(data);      }    },    socketOnClose() {      this.socket.onclose = () => {        // console.log('close socket')      }    },    socketOnError() {      let _this = this;      this.socket.onerror = (error) => {        //连接失败回调        _this.term.write('Error: ' + error + '\r\n');      }    },    sendMessege(messege) {      //发送指令      this.socket.send(JSON.stringify({"operate": "command", "command": messege}));    }  }}</script>

3、 使用时引用terminal.vue组件,传入主机信息即可

<template>  <div>    <terminal :host-info="hostInfo"></terminal>  </div></template><script>import terminal from './terminal'export default {  name: "test",  components: {terminal},  data() {    return {      hostInfo: {        host: '192.168.3.50',//IP        port: '22',//端口号        username: 'root',//用户名        password: '123456'//密码      }    }  }}</script>

此时访问页面已经能看到终端屏幕,接下来继续实现后端逻辑。

后端实现


   后端功能主要包括服务器交互和请求转发两块,我们通过Jsch和Websocket来实现。服务器交互主要包括以下方法:初始化SSH连接、处理客户端发送的命令、读取命令执行结果、关闭连接等。前后端交互主要为对WebSocket生命周期中事件的处理,主要是连接WebSocket并完成数据的接收并回写。

部分源码如下:

1、Websocket配置,开启Websocket并配置处理器和拦截器。

2、Websocket处理器,实现Websocket生命周期事件,在接收到执行命令请求后调用执行逻辑。

3、WebSSH的业务逻辑,主要包括以下接口方法,重点看下处理客户端数据的实现,将请求数据分为连接请求和命令请求分别处理。

效果展示

   现在,我们已经成功实现了文章开始提出的Web端SSH需求。运行项目看下效果,可以看到已能实现类似SecureCRT的功能:

连接主机

ls命令

vim命令

top命令


End






文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

ZZ
暂无图片
2年前
评论
暂无图片 0
这样会有一个问题啊 很快就会和设备断开连接 提示因为channel已经关闭
2年前
暂无图片 点赞
评论