【webssh】網頁上的SSH終端
【webssh】
——記兩天來比較痛苦的歷程
廣義上來說,webssh泛指一種技術可以在網頁上實現一個SSH終端。從而無需Xshell之類的模擬終端工具進行SSH連接,將SSH這一比較低層的操作也從C/S架構扭成了B/S架構。
能實現webssh的組件有好幾種,但歸根結底都是建立在客戶端和服務端的即時通信上,有一些webssh只停留在這一層,表明客戶端接入的ssh界面只是服務端本身的後臺;另一種稍微高級一點的,將webssh做成一個通用的服務,網頁上的ssh界面其實就和XShell一樣,可以連接任何服務器可以連通的機器。由於一般服務器都會安裝有ssh客戶端軟件,所以兩者之間硬要說有很明顯的區別其實也沒有。
下面來說一說我的需求吧,我做的一個資源管理系統中重要的一部分就是服務器。同時系統中也維護了各個服務器的用戶和密碼,那麽如果在頁面上按一個鍵,就能打開一個webssh,並且 自動登錄 ,這樣就能很方便地管理各個服務器了。
基於這樣一種需求的想法,我出發去找了一些項目,下面來說說幾個找到的可能有用的:
■ GateOne
項目地址: https://github.com/liftoff/GateOne
詳細的安裝教程可以參考這篇:http://www.laozuo.org/10703.html
這個東西被很多人稱贊,使用了下也發現確實很牛。它是一個基於HTML5的webssh工程,不需要任何瀏覽器的任何插件就能無障礙運行。我感覺gateone最厲害的地方在於其強大的webssh界面。不僅僅是一塊黑屏,它還支持多終端創建和切換,支持在終端中顯示圖片等內容,支持操作回放,日誌審計等等功能。簡直可以說比putty,XShell之類的桌面軟件都要強大很多。但是その分,這個工程很大,需要的依賴很多。
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默認的那個帶有表單的界面展示出來,於是用了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】網頁上的SSH終端