【webssh】網頁上的SSH終端

【webssh】css

  ——記兩天來比較痛苦的歷程html

  廣義上來講,webssh泛指一種技術能夠在網頁上實現一個SSH終端。從而無需Xshell之類的模擬終端工具進行SSH鏈接,將SSH這一比較低層的操做也從C/S架構扭成了B/S架構。前端

  能實現webssh的組件有好幾種,但歸根結底都是創建在客戶端和服務端的即時通訊上,有一些webssh只停留在這一層,代表客戶端接入的ssh界面只是服務端自己的後臺;另外一種稍微高級一點的,將webssh作成一個通用的服務,網頁上的ssh界面其實就和XShell同樣,能夠鏈接任何服務器能夠連通的機器。因爲通常服務器都會安裝有ssh客戶端軟件,因此二者之間硬要說有很明顯的區別其實也沒有。python

  下面來講一說個人需求吧,我作的一個資源管理系統中重要的一部分就是服務器。同時系統中也維護了各個服務器的用戶和密碼,那麼若是在頁面上按一個鍵,就能打開一個webssh,而且 自動登陸 ,這樣就能很方便地管理各個服務器了。jquery

  基於這樣一種需求的想法,我出發去找了一些項目,下面來講說幾個找到的可能有用的:git

■  GateOnegithub

  項目地址: https://github.com/liftoff/GateOneweb

  詳細的安裝教程能夠參考這篇:http://www.laozuo.org/10703.htmlshell

  這個東西被不少人稱讚,使用了下也發現確實很牛。它是一個基於HTML5的webssh工程,不須要任何瀏覽器的任何插件就能無障礙運行。我感受gateone最厲害的地方在於其強大的webssh界面。不只僅是一塊黑屏,它還支持多終端建立和切換,支持在終端中顯示圖片等內容,支持操做回放,日誌審計等等功能。簡直能夠說比putty,XShell之類的桌面軟件都要強大不少。可是その分,這個工程很大,須要的依賴不少。npm

  gateone的開發框架是tornado,恰好是python的,因此我看了它很長時間。。在保證有了tornado,paramiko等一系列依賴以後,下載來項目,能夠考慮用python setup.py install來將gateone做爲一個軟件安裝在服務器上,我採用的方法是python gateone.py這樣的比較low的辦法啓動服務的。默認端口等等配置能夠在gateone.py同目錄下的server.conf中修改。哦對了,gateone默認使用了https協議,因此在訪問的時候記得不要搞錯了。

  部署完成以後,訪問相關地址,能夠看到gateone的界面。簡單用了一下,界面的邊上還有一連串工具欄,沒有仔細研究,不過確實能夠說是和桌面級軟件通常的好用。

  不過gateone有個很大的缺點不符合個人需求,就是沒法作到自動登陸。gateone實際上是做爲一個通用的ssh客戶端服務放在服務器上的,我沒法在打開它的時候向其傳遞一些信息從而實現自動的ssh到某臺服務器。爲了自動登陸,我甚至用jquery找到光標的DOM而後在它前面插入信息等方法,均告失敗。粗粗看了下源碼,以爲水平不足以改源碼來實現。。因而放棄找其餘辦法

■  shellinabox

  這個項目也是一個很好的webssh,不過沒有細看,由於它彷佛只支持對於部署本地的訪問,固然若是要訪問出去也是能夠,這樣仍是略顯麻煩一點。並且自動登陸的問題依然沒有解決,我依然沒有找到辦法向webssh界面傳遞信息實現自動登陸。

  在github上看彷佛最新版本已經集合了不少其餘插件好比IDE插件和其餘一些美化界面的東西進去,看起來仍是很漂亮的。

■  xterm.js

  晚上問了一下公司裏有相似功能的項目是如何實現webssh的,結果被告知是使用了xterm.js,而且作這塊的同事已經離職了。。只好本身研究了下xterm.js這個庫。

  項目地址:https://github.com/xtermjs/xterm.js

  xterm.js是一個前端庫,要實現一個完整的webssh還須要後端的支持。xterm的話能夠認爲它就是能夠在前端畫一個功能較爲齊全的終端屏幕。

  哦對了,在跟着它的readme安裝的時候還猜了很多坑,npm這個東西至今仍是不太會用。前端的玩法有必要系統學一下。總之最後總算是搞出了xterm.js和xterm.css兩個文件放到頁面裏實驗了一下。確實畫出了黑屏,不過沒有交互啊。交互的話確定要用websocket(其餘雙工交互方式確定是效率不高的,簡單用用能夠,webssh傳輸強度比較大的東西仍是算了),flask也就算了,django裏的websocket基本不會。。無奈再回網上找找。

■  webssh

  項目地址: https://github.com/huashengdun/webssh

  最終找到了webssh(狹義)這個東西。其實同名的webssh以前我已經在github上找到一個,以前開運維技術大會時,聽到別人的做品中也是用了那個組件。可是那裏簡介一看在一年前就已經不維護了,下來一試發現bug多得是,因此很快就放棄了。不過此次找到的webssh彷佛和以前那個沒啥關係,是同名的另外一個項目。下來一試發現好得很,不只可以實現基本的ssh界面,並且代碼也很少,要本身改的話學習成本也不是很大。

  技術上,這個項目前端用的也是xterm.js,後端用的也是tornado,並且後端的目錄結構至關簡單易懂。部署上去以後訪問進去一開始仍然是須要輸入IP,端口,帳號密碼這些內容的界面。可是它明確寫出了那個界面裏用了哪些JS,因而我想到了能夠在鏈接里加入GET參數,而後自建一個JS來把這些參數填入input中,而後再自動按一下submit,就能夠實現自動登陸了。

  這裏不得不指出的是,webssh用的是http協議,安全方面上可能有一些不足。可是已經顧不得這麼多了。。並且我把webssh部署在和我本身項目同一臺服務器上,頁面上採用了iframe訪問webssh服務,因此相對好一點。 若是想要將webssh項目部署成https也簡單,只要修改下webssh的tornado框架用到的一些源碼就能夠了。

  在main.py中,原先服務進程的監聽啓動是經過app.listen這樣的方式來作的。如今只要將這部分註釋掉而後從新創建一個http_server對象來監聽:

import tornado
# ...略
http_server = tornado.httpserver.HTTPServer(app, ssl_options={
  'certfile': 'your/path/to/certificate.crt',
  'keyfile': 'your/path/to/key.key'
})
http_server.listen(options.port,options.address)
# ...略

 

  這樣就能夠經過https來訪問webssh界面了。

  至此個人需求基本實現了,不過還有點不足,就是我不想把webssh默認的那個帶有表單的界面展現出來,因而用了layer組件,在頁面加載開始時就調出了一個加載界面而且指定shade爲true,使得看不到後面的內容。請求成功後關掉layer,若是請求失敗,就以layer.msg的方式將錯誤信息展示。按照webssh的main.js中默認的提示錯誤的方式,是將錯誤信息寫在一個#status的div中,記得把status.text(xxx)之類的內容換成layer.msg便可。還有一個歪打正着的,默認狀況輸入exit退出ssh以後會回到表單界面,加上layer以後退出來不顯示錶單而是變成一塊黑屏,很好。

  其他一些定製就是很簡單了。好比把錯誤提示信息換成中文等等。

  這個過程當中還遇到過兩個小問題。第一個是當個人ssh區域做爲一個iframe出如今頁面上時,若是區域高度太小,好比小於400px時,ssh界面會錨定在最頂部。當輸出比較多的命令被執行以後你就看不到光標了,除非盲打一個clear命令。。第二個是彷佛webssh不支持很大量的數據交互。我嘗試着cat了一個5M多的文件時,崩潰了。。不過我原本就是拿這個東西來作一個簡單的ssh的,不必繼續增強性能。

   * 關於第一個問題還有一些小補充。webssh模擬終端的界面的大小是個很微妙的東西,上面說了高度的問題,另外還有一個寬度的問題。通常狀況下,爲了可以動態適配窗口的大小,咱們能夠實時獲取window.height和window.width,而後經過計算得到到webssh終端合適的高和寬。對於width,webssh利用的前端組件xterm.js有一個問題就是最多每行只能顯示80個字符。或許你能夠嘗試修改Terminal對象生成時傳入方法的參數cols(其默認值是80),可是隻要其值設置爲大於80的時候就會發生超出80字符寬度部分的字符串不會自動換行,而是到本行開頭去覆蓋本行。

  google了挺久沒有找到合適的解決方案,github上官方給出的解釋是由於被鏈接服務器自己的tty終端字符寬度就是80,而xterm.js必須和這個寬度同樣才能夠正常工做。。爲了webssh終端可以正常地自動換行同時也要儘可能避免webssh終端區域大片屏幕都被浪費,一個曲線救國的辦法就是把終端窗口寬度恰好調節成80個字符再寬一點點的樣子,好比780px左右(根據屏幕大小不一樣可能不一樣)。

  以上。兩天終於找到了一個好一點的解決辦法。。

相關文章
相關標籤/搜索