【问题标题】:NodeJS Server-Server Secure CommunicationNodeJS 服务器-服务器安全通信
【发布时间】:2017-08-28 23:46:12
【问题描述】:

我在同一个域上有两台使用 NodeJS 的服务器。 (server1.example.com 和 server2.example.com)

我想以安全的方式从一台服务器向另一台服务器发送消息。

现在,我正在使用通过发送 HTTPS POST 来发送消息,例如 https://example.com{secret:XXXXX,message:1234}

有没有更清洁的方法来做到这一点?如果是这样,需要的确切步骤是什么? 注意:我在网站上有一个 SSL 证书。两台服务器都在同一个域上。

【问题讨论】:

  • 我认为发送请求时查询字符串不会被加密,因此您可以使用 POST 之类的方法在请求正文中发送它
  • @ExplosionPills 谢谢,我使用 POST 编辑了问题。
  • 从技术上讲,两台服务器都在不同的域上,它们只是共享一个父级
  • @RainingChain 您认为“干净”的 HTTPS 请求是什么?
  • @mscdex 我不太清楚。我曾希望有一种自动化的方式或库来做到这一点。我宁愿不必为每条消息都发送秘密,也不必真正手动管理秘密。

标签: node.js ssl https server


【解决方案1】:

只是为了添加到已经发布的其他解决方案,您可以只是在两端使用证书,这样您就可以在 TLS 层而不是应用程序层进行身份验证,如果这有帮助的话.

假设您在两台服务器上都使用节点,您可以这样实现:

  1. 创建一个自定义 CA,然后为每台服务器创建一个证书和一个私钥。
  2. 每个服务器可能有如下代码:

    const tls = require('tls');
    
    function onMessage(socket, msg) {
      // `msg` is a parsed message received from `socket`
    }
    
    // Receive incoming messages
    tls.createServer({
      rejectUnauthorized: true,
      requestCert: true,
      ca: MY_CUSTOM_CA,
      cert: THIS_SERVER_CERT,
      key: THIS_SERVER_PRIVATE_KEY
    }, (socket) => {
      if (!socket.authorized)
        return socket.end(); // Certificate did not check out
      console.log('Connection accepted');
    
      // example protocol: newline-delimited JSON
      var jsonBuffer = '';
      socket.setEncoding('utf8');
      socket.on('data', (chunk) => {
        var chunks = chunk.split('\n');
        var numComplete = chunks.length - 1;
        // Last line does not have trailing newline
        var incompleteChunk = chunks[numComplete];
        if (numComplete === 0) {
          jsonBuffer += incompleteChunk;
          return;
        }
        chunks[0] = jsonBuffer + chunks[0];
        for (var i = 0; i < numComplete; ++i) {
          try {
            onMessage(socket, JSON.parse(chunks[i]));
          } catch (ex) {}
        }
        jsonBuffer = incompleteChunk;
      });
    
      socket.on('end', () => {
        console.log('Connection ended');
      });
    }).listen(MY_PORT);
    
    // Send outgoing messages
    function sendMessages(host, port, msgs, cb) {
      if (!Array.isArray(msgs))
        msgs = [msgs];
    
      var req = tls.connect({
        host,
        port,
        rejectUnauthorized: true,
        ca: MY_CUSTOM_CA,
        cert: THIS_SERVER_CERT,
        key: THIS_SERVER_PRIVATE_KEY
      }, () => {
        if (!this.authorized)
          return this.end(); // Certificate did not check out
    
        for (var i = 0; i < msgs.length; ++i)
          this.write(JSON.stringify(msgs[i]) + '\n');
    
        this.end();
      }).once('error', onError).once('close', onClose);
    
      function onError(err) {
        req.removeListener('close', onClose);
        cb(err);
      }
    
      function onClose() {
        cb();
      }
    }
    
  3. onMessage() 中添加传入消息处理并使用sendMessages() 发送传出消息。

您也可以始终保持一个套接字打开,而不是为每组传出消息使用一个新连接,但这会涉及更多一些,因为您需要添加一个应用程序级别的保活机制等,但它肯定是可行的。

【讨论】:

    【解决方案2】:

    我可以想到一些选项,当然,这取决于您正在寻找的加密和安全性的数量,如果 HTTPS 不足以满足特定通信的要求。 (尽管如前所述,您确实有 HTTPS。)

    1. 您可以让发送服务器发出完整的 JWT 路由。使用 Token 发送信息并在另一端进行验证。确保令牌也有一个短的 TTL。 (如果你真的想在这里破产,你可以开始实现 OAuth2 框架,尽管这可能完全是矫枉过正。)

    2. 另外,您可以创建一个 Websocket HTTPS 服务器,并且只接受来自特定传入端口信息的信息。这将允许您使用 JWT 并通过端口访问进一步验证。您打开的端口将只被允许接受来自特定 IP 的数据包,即您的传出服务器。

    3. 您可以通过加密整个消息(通过其中一个 Node NPM 模块或通过 Crypto)来添加另一层,因此消息和秘密都经过哈希处理。

    4. 您还可以添加缓存层(Redis 或 Node-Cache 模块),所有解密都将在其中完成以加快处理速度。

    5. 另一个使用技巧是,尽管您必须制定实际的时间表,但您可以根据流程或不同的时间或您希望的任何时间表来混合您使用的各种散列例程。

    6. 最后,一个有时被忽视的选项是在接收计算机上安装防火墙,对接收内容和从何处接收具有非常具体的规则。 (虽然这不是 Node 进程,并且可能需要时间才能正确。)

    以上都没有链接到 Express 或中间件。我假设如果您采用上述任何一种方法,最终您将需要一些 NPM 模块。

    可能忘记了一些选项,但希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      您可以通过HOSTORIGIN 标头验证请求的主机来进一步加强安全性。

      查看:https://stackoverflow.com/questions/18498726/how-do-i-get-the-domain-originating-the-request-in-express-js

      基本上,您要确保带有加密密钥的请求实际上来自特定服务器,而不仅仅是任何服务器。

      【讨论】:

        猜你喜欢
        • 2016-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-01
        • 2016-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多