2017-04-03 91 views
1

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

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

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

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

+2

我不认为查询字符串在发送请求时会被加密,因此您可以使用类似于POST的方法将其发送到请求正文中。POST –

+0

@ExplosionPills谢谢,我使用POST编辑了问题。 – RainingChain

+0

从技术上讲,两台服务器都在不同的域中,他们只是共享一个父项 – bitstrider

回答

1

有几个选项我可以想到,虽然当然,它取决于您要查找的加密和安全的数量,如果HTTPS不足以满足特定通信的要求。 (虽然如上所述,您确实有HTTPS。)

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

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

  3. 您可以通过加密整个消息(通过其中一个节点NPM模块或Crypto)来添加另一个图层,因此消息和秘密都被散列。

  4. 您还可以添加缓存层(Redis或节点缓存模块),其中将执行所有解密操作以加速进程。

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

  6. 最后,一个有时被忽视的选择是在接收计算机上安装防火墙,并在接收计算机上以及从哪里接收特定规则。 (这虽然不是一个节点的过程,需要一段时间才能得到正确的。)

以上都不是被链接到虽然快速,或中间件。我假设如果你采用上述任何一种,你最终的结果将需要几个NPM模块。

大概忘了一些选择,但希望这有助于。

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()发送传出的消息。

你也可以只保留一个套接字打开所有的时间,而不是使用每组传出消息的新的连接,但是这将是一个涉及多一点,因为你需要添加一个应用级keepalive机制等等,但它肯定是可行的。