2016-08-01 210 views
6

我一直在尋找網絡的面部來回答我曾認爲很簡單的問題。我的目標很簡單。我想用Node.js模塊構建一個簡單的基於Web的SSH客戶端。如果我想連接到節點服務器本身,我發現了幾個選項,但似乎找不到連接到REMOTE服務器的任何示例。連接到遠程SSH服務器(通過Node.js/html5控制檯)

基本上我正在尋找的結果是這樣的工作流程:連接到網絡服務器 - >在服務器的點擊列表中的服務器名稱 - >輸入SSH會話我的

唯一點擊服務器我發現,這甚至遠遠接近我正在尋找的是guacamole。然而,我不想使用鱷梨醬,因爲我希望這個應用程序獨立於操作系統。目前,我正在將其構建在Windows 10平臺上,並在完成後將其移植到Fedora。

我發現本教程的creating an SSH terminal。但是,所有這些都會創建(或嘗試創建)到本地系統的SSH連接。

看起來非常棒的另一種選擇是tty.js。唉,底線與上面的教程相同。該模塊僅允許您連接到node.js服務器,而不允許連接到遠程服務器。

任何人都有關於實現此目標的可能路徑的信息?

回答

18

這可以通過模塊ssh2xtermsocket.io輕鬆實現。

下面是一個例子:

  1. npm install ssh2 xterm socket.io
  2. 創建index.html
<html> 
    <head> 
    <title>SSH Terminal</title> 
    <link rel="stylesheet" href="/src/xterm.css" /> 
    <script src="/src/xterm.js"></script> 
    <script src="/addons/fit/fit.js"></script> 
    <script src="/socket.io/socket.io.js"></script> 
    <script> 
     window.addEventListener('load', function() { 
     var terminalContainer = document.getElementById('terminal-container'); 
     var term = new Terminal({ cursorBlink: true }); 
     term.open(terminalContainer); 
     term.fit(); 

     var socket = io.connect(); 
     socket.on('connect', function() { 
      term.write('\r\n*** Connected to backend***\r\n'); 

      // Browser -> Backend 
      term.on('data', function(data) { 
      socket.emit('data', data); 
      }); 

      // Backend -> Browser 
      socket.on('data', function(data) { 
      term.write(data); 
      }); 

      socket.on('disconnect', function() { 
      term.write('\r\n*** Disconnected from backend***\r\n'); 
      }); 
     }); 
     }, false); 
    </script> 
    <style> 
     body { 
     font-family: helvetica, sans-serif, arial; 
     font-size: 1em; 
     color: #111; 
     } 
     h1 { 
     text-align: center; 
     } 
     #terminal-container { 
     width: 960px; 
     height: 600px; 
     margin: 0 auto; 
     padding: 2px; 
     } 
     #terminal-container .terminal { 
     background-color: #111; 
     color: #fafafa; 
     padding: 2px; 
     } 
     #terminal-container .terminal:focus .terminal-cursor { 
     background-color: #fafafa; 
     } 
    </style> 
    </head> 
    <body> 
    <div id="terminal-container"></div> 
    </body> 
</html> 
  • 創建server.js
  • var fs = require('fs'); 
    var path = require('path'); 
    var server = require('http').createServer(onRequest); 
    
    var io = require('socket.io')(server); 
    var SSHClient = require('ssh2').Client; 
    
    // Load static files into memory 
    var staticFiles = {}; 
    var basePath = path.join(require.resolve('xterm'), '..'); 
    [ 'addons/fit/fit.js', 
        'src/xterm.css', 
        'src/xterm.js' 
    ].forEach(function(f) { 
        staticFiles['/' + f] = fs.readFileSync(path.join(basePath, f)); 
    }); 
    staticFiles['/'] = fs.readFileSync('index.html'); 
    
    // Handle static file serving 
    function onRequest(req, res) { 
        var file; 
        if (req.method === 'GET' && (file = staticFiles[req.url])) { 
        res.writeHead(200, { 
         'Content-Type': 'text/' 
             + (/css$/.test(req.url) 
             ? 'css' 
             : (/js$/.test(req.url) ? 'javascript' : 'html')) 
        }); 
        return res.end(file); 
        } 
        res.writeHead(404); 
        res.end(); 
    } 
    
    io.on('connection', function(socket) { 
        var conn = new SSHClient(); 
        conn.on('ready', function() { 
        socket.emit('data', '\r\n*** SSH CONNECTION ESTABLISHED ***\r\n'); 
        conn.shell(function(err, stream) { 
         if (err) 
         return socket.emit('data', '\r\n*** SSH SHELL ERROR: ' + err.message + ' ***\r\n'); 
         socket.on('data', function(data) { 
         stream.write(data); 
         }); 
         stream.on('data', function(d) { 
         socket.emit('data', d.toString('binary')); 
         }).on('close', function() { 
         conn.end(); 
         }); 
        }); 
        }).on('close', function() { 
        socket.emit('data', '\r\n*** SSH CONNECTION CLOSED ***\r\n'); 
        }).on('error', function(err) { 
        socket.emit('data', '\r\n*** SSH CONNECTION ERROR: ' + err.message + ' ***\r\n'); 
        }).connect({ 
        host: '192.168.100.105', 
        username: 'foo', 
        password: 'barbaz' 
        }); 
    }); 
    
    server.listen(8000); 
    
  • 編輯在瀏覽器傳遞給.connect()server.js
  • node server.js
  • 訪問http://localhost:8000 SSH服務器配置
  • +1

    老兄,你絕對搖滾! :) – Ethan

    +1

    不要碰巧有類似的RDP和VNC嗎? :) – Ethan

    +0

    vnc的快速搜索顯示[this](http://blog.mgechev.com/2013/08/30/vnc-javascript-nodejs/)。這有點舊,可以稍微優化一下,但它可能仍然有效。就RDP而言,我還沒有看到RDP實現/綁定節點。 – mscdex

    0

    也嘗試noVnc。 然而,xterm.js內頁一點點掏揭示其他解決方案,如

    WebSSH2

    相關問題