NodeJS服务器 - 服务器安全通信

时间:2017-04-03 23:35:37

标签: node.js ssl https server

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

我希望以安全的方式将消息从一台服务器发送到另一台服务器。

现在,我通过发送https://example.com{secret:XXXXX,message:1234}之类的HTTPS POST来发送消息。

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

3 个答案:

答案 0 :(得分:3)

我可以考虑一些选项,当然,如果HTTPS不够强大,无法满足特定通信所需的要求,它取决于您要查找的加密和安全性的数量。 (尽管如上所述,你确实有HTTPS。)

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

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

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

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

  5. 另一个使用的技巧,虽然您必须计算出实际的时间表,但是要根据流程或不同的时间或您希望的任何时间表混合使用的各种哈希例程。

  6. 最后,一个有时被忽视的选项是在接收计算机上安装防火墙,其中包含有关接收内容和从哪里接收的非常具体的规则。 (这虽然不是Node过程,但可能需要时间才能正确。)

  7. 上述所有内容均未与Express或中间件相关联。我假设如果采用上述任何一种方法,最终结果将需要一些NPM模块。

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

答案 1 :(得分:2)

只是为了添加已经发布的其他解决方案,你可以在两端使用证书,这样你就可以在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()发送传出邮件。

  4. 你也可以只保持一个套接字一直打开,而不是每组传出消息使用一个新连接,但这会更复杂,因为你需要添加一个应用程序级别的keepalive机制等等。 ,但它肯定是可行的。

答案 2 :(得分:1)

您可以通过HOSTORIGIN标题验证请求的主机,从而加强您的安全性。

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

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