2017-04-03 57 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機制等等,但它肯定是可行的。