闲着没事让ChatGPT写了一个基于nodejs的TCP端口复用脚本

众所周知,某些容器管理服务只让放一个端口,还有某些免费的NAT VPS也只给你放一个空闲端口,这个就直接导致了我现在SSH VNC 还有一个 Terraria 服务端根本就不够开… 好了前面都是废话,代码又不是我写的,直接贴:

// safe-app.js - 完全透明首包缓存代理
const net = require('net');

const LISTEN_PORT = 5911;

const ROUTES = [
  {
    name: 'SSH',
    port: 22,
    detect: buf => buf.toString().startsWith('SSH-'),
  },
  {
    name: 'VNC',
    port: 5912,
    detect: buf => false,
  },
  {
    name: 'Terraria',
    port: 7777,
    detect: buf => true,
  }
];

const server = net.createServer(clientSocket => {
  console.log(`[+] 新连接来自 ${clientSocket.remoteAddress}`);

  let resolved = false;
  let buffer = Buffer.alloc(0);

  const timer = setTimeout(() => {
    if (!resolved) {
      console.log('[~] 未收到数据,默认转发 VNC');
      forward(ROUTES[1].port);
    }
  }, 1000);

  clientSocket.on('data', chunk => {
    if (resolved) return;

    buffer = Buffer.concat([buffer, chunk]);

    for (const route of ROUTES) {
      if (route.detect(buffer)) {
        clearTimeout(timer);
        forward(route.port);
        return;
      }
    }

    // 超出长度仍未判断成功,转默认
    if (buffer.length > 12) {
      clearTimeout(timer);
      forward(ROUTES[2].port); // Terraria fallback
    }
  });

  function forward(targetPort) {
    resolved = true;
    console.log(`[→] 正在转发到端口 ${targetPort}`);

    const target = net.connect(targetPort, '127.0.0.1', () => {
      if (buffer.length > 0) target.write(buffer);
      clientSocket.pipe(target);
      target.pipe(clientSocket);
    });

    target.on('error', err => {
      console.error(`[×] 转发端口 ${targetPort} 出错: ${err.message}`);
      clientSocket.destroy();
    });

    clientSocket.on('error', () => {
      target.destroy();
    });
  }
});

server.listen(LISTEN_PORT, () => {
  console.log(`[✔] 多协议智能代理监听于端口 ${LISTEN_PORT}`);
});

因为我是Docker容器去映射端口到主机,所以地址都指定了127.0.0.1。这里我的情况是客户端没响应发给VNC,然后SSH自己报名的就发给SSH。如果VNC给超时了或者客户端发的也不是SSH的就全部转给Terraria,就这些功能,水一篇帖子。如果有人有成熟的项目的话欢迎推荐!