1

我有一个工作的 node.js 服务器,它使用 socket.io websocket 连接和 ssh2 连接打开一个 shell 并将其返回到使用 xterm-for-react 的浏览器中的反应客户端。我现在正在尝试通过相同的 ssh 连接来隧道端口,但遇到了一些困难。代码在下面,注释掉的部分是我一直在尝试进行端口转发的地方 - 相当于 ssh -L 2233:192.168.2.1:80 test@192.168.0.65

    const socketIO = require("socket.io");
    const sshClient = require("ssh2").Client;
    const utf8 = require("utf8");
    const fs = require("fs");
    
    class SocketServiceFwd {
      constructor() {
        this.socket = null;
        this.pty = null;
        this.devicesList = [
          {
            name: "Device 1",
            host: "192.168.0.65",
            port: "22",
            username: "test",
            password: "test12345",
          },
        ];

      attachServer(server) {
        if (!server) {
          throw new Error("Server not found...");
        }
    
        const io = socketIO(server, {cors: {origin: "*",},});
        console.log("Created socket server. Waiting for client connection.");
        // "connection" event happens when any client connects to this io instance.
        io.on("connection", (socket) => {
          console.log("Client connect to socket.", socket.id);
    
          this.socket = socket;
          const ssh = new sshClient();
    
          this.socket.on("devices", (cb) => {
            console.log("Get devices list from " + socket.id);
            return cb(null,this.devicesList.map((d) => ({ name: d.name }))
            );
          });
    
          this.socket.on("connectToDevice", (deviceName) => {
            console.log(socket.id + " connecting to device " + deviceName);
            const selectedDevice = this.devicesList.find(
              (d) => d.name === deviceName
            );
    
            if (selectedDevice) {
              ssh.on("ready", function () {
                console.log(socket.id + " successfully connected to " + deviceName);
                socket.emit("output", "\r\n*** SSH CONNECTION ESTABLISHED ***\r\n");
                // ssh.forwardOut("127.0.0.1", 2233, "192.168.2.1", 80, 
                //   (err, stream) => {
                //     console.log(
                //       "ssh forwardOut '127.0.0.1:2233' '192.168.2.1:80'"
                //     );
                //     if (err)
                //       return socket.emit(
                //         "output",
                //         "\r\n*** SSH FORWARDOUT ERROR: " + err.message + " ***\r\n"
                //       );
                //   }
                // );
                ssh.shell(function (err, stream) {
                  if (err)
                    return socket.emit(
                      "output",
                      "\r\n*** SSH SHELL ERROR: " + err.message + " ***\r\n"
                    );
    
                  socket.on("input", function (data) {
                    stream.write(data);
                  });
    
                  stream.on("data", function (d) {
                    socket.emit("output", utf8.decode(d.toString("binary")));
                  });
                  stream.on("close", function () {
                    console.log(socket.id + " terminal stream close");
                    ssh.end();
                  });
                });
              });
              ssh.on("close", function () {
                console.log(socket.id + " ssh connection closed to " + deviceName);
                socket.emit("output", "\r\n*** SSH CONNECTION CLOSED ***\r\n");
                socket.removeListener("input", () => {});
              });
              ssh.on("error", function (err) {
                console.log(err);
                socket.emit("output","\r\n*** SSH CONNECTION ERROR: " + err.message + " ***\r\n");
              });
              ssh.connect(selectedDevice);
            }
          });
    
          this.socket.on("disconnectFromDevice", () => {
            console.log(socket.id + " disconnecting from device");
            ssh.destroy();
          });
        });
      }
    }
    
    module.exports = SocketServiceFwd;

***** 已编辑 ***** 如果有人能提供一些建议,那就太好了 :-) 我一直在努力,但仍然需要一些帮助......我使用 npm “隧道”取得了更多的成功-ssh”模块。隧道确实打开了足够长的时间让我查看网站,但不久之后,隧道停止工作。打开隧道后我还有什么事情要做吗?

下面的代码位于上面注释掉的部分。我试图按照我在网上看到的例子进行操作——谁能告诉我我做错了什么?

我在我的 npm start 中运行 DEBUG=* 并看到以下内容:

  tunnel-ssh sshConnection:ready +3s
  tunnel-ssh sshConnection:ready +1ms
  tunnel-ssh sshStream:create +19ms
  tunnel-ssh sshStream:create +0ms
TCP :: ERROR: read ECONNRESET
TCP :: ERROR: read ECONNRESET

所以很明显隧道启动但随后发生错误。通常连接会恢复,我可以继续通过隧道浏览网站,但最终会出现不可恢复的错误。所以隧道是不稳定的。如果我使用 openssh 运行隧道,它是稳定的。因此,我的问题现在归结为请求协助确定不稳定的原因。我是否没有正确处理我的代码或配置中的某些内容?请帮忙!另请注意,尽管如此,我的 shell 会话仍然可以正常工作。

const tunnel = require("tunnel-ssh");
const tnl = tunnel({host: '192.168.0.65', username: 'test', password: 'test12345', 
        dstHost: '192.168.2.1', dstPort: 80, localHost: '127.0.0.1',
        localPort: 2233}, (er, stream) => {
    if(er) {
        console.log("something went wrong " + er.message);
        stream.close();
    }
    stream.on("data", (data) => {
        console.log("TCP :: DATA: " + data);
    });
    stream.on("error", (error) => {
        console.log("TCP :: ERROR: " + error.message);
    }); 
});
4

0 回答 0