web-dev-qa-db-ja.com

Socket.ioを使用してNode.jsの分散型サービス拒否攻撃から保護する方法

私は最近node.jsとsocket.ioを学んでいます。私の質問は、クライアント側の攻撃からサーバーを保護するにはどうすればよいですか?

これは私のサーバーコードです

io.sockets.on('connection', function (socket) { 
//users.Push(socket);       
socket.on('message', function (data) {      

    socket.on('disconnect', function () { });           

    socket.on('bcast', function (data) {        
        socket.emit('news', { 'data': data });
        socket.broadcast.emit('news', { 'data': data });     
    });

    socket.on('login', function(data){
      socket.emit('login', {'data': [ socket.id, data ] });
    });
   });
 });

たとえば、クライアントがchrome開発者ツールを使用してフローコードを実行する場合

 for(var i = 0; i<99999999999; i++)
 {
        socket.emit('bcast', {data: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'});
 }

サーバーを強制終了します。

45
Virushan

JSイベントの調整とデバウンスを確認してください!

これらのテクニックは、特定のポイントへの攻撃を防止および検出するのに役立ちます(私の意見では、これは小さなマルチプレイヤーソケットゲームには十分です)...

編集:

このjsfiddleで: http://jsfiddle.net/y4tq9/9/

var sIO = {};

sIO.on = (function(){
    var messages = {};
    var speedLimit = 5; //5ms
    return function(message, handler) {
        messages[message] = messages[message] || {};
        if(messages[message].timestamp && new Date().getTime() - messages[message].timestamp < speedLimit) return false;
        else messages[message].timestamp = new Date().getTime();

        handler();
        return true;
        //execute code, Ex:
    }
}());

5msよりも速く送信されたすべてのリクエストがfalseを返すことがわかります。それ以外の場合、ハンドラーが実行されます。

5ms(または、ネットワークとアプリケーションの重みに応じて2ms、または3ms)より高速でリクエストを送信するソケットを簡単に切断します。

クライアントサイトでjsイベント調整を使用して、すべてのリクエストが速度制限よりも速く送信されないようにすることもできます。

この手法は、悪用からの絶対的な保護を提供するものではありませんが、攻撃者がDosしようとしたときにサーバーがクラッシュするのを防ぎます...

20
Keo Strife

rate-limiter-flexible Node.jsパッケージは、DDoS攻撃に対して使用できます。

const { RateLimiterMemory } = require('rate-limiter-flexible');

const rateLimiter = new RateLimiterMemory({
  points: 5, // 5 points
  duration: 1 // per second
});

socket.on('bcast', data => {
  rateLimiter.consume(uniqueSocketId) // consume 1 point per event
    .then(() => {
      socket.emit('news', { 'data': data });
      socket.broadcast.emit('news', { 'data': data });
    })
    .catch(rejRes => {
      // no available points to consume
      // emit error or another workaround
    });
});

1秒間に5回以上発生すると、イベントはブロックされます。

Redisを使用した分散アプリケーション用のオプションもあります。保険やブロック戦略などの柔軟な設定により、rate-limiter-flexible高可用性と高速。

4
Animir

Httpサーバーでこれを行うことは常に良い考えではありません。この回答を確認してください: node.jsで記述されたhttpサーバーでDOS攻撃を防ぐ方法?

3
Luca Steeb

ノードがフレームワーク自体内でこのようなDDoS条件を処理するのに「最良」ではないことを考えると、cloudflareやblacklotusなどの第3部のDDoS緩和策を検討します。使用規模が非常に大きい場合は高価な製品ですが、Nodeまたは実際にあらゆるフレームワークをサービス拒否攻撃から保護します。

https://www.cloudflare.com

http://www.blacklotus.net/

別のオプションとして、aiProtectのようなソフトウェアベースのファイアウォールソリューションを使用する方法があります。これは、cloudflareとblacklotusの無料の階層を超えてスケ​​ーリングする場合、もう少し費用効率が高くなります。

http://aiscaler.com/home/protect

他にもたくさんありますが、これにはたまたまAWSパートナーシップがあるため、aiProtect VMを簡単にスピンアップできます。

1
Matt617