如何使用Socket.io防止Node.js中的分布式拒绝服务攻击?

Vir*_*han 45 ddos node.js socket.io

我最近一直在学习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 ] });
    });
   });
 });
Run Code Online (Sandbox Code Playgroud)

例如,如果客户端使用chrome开发人员工具来执行流动的代码

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

它会杀死服务器.

Keo*_*ife 20

看看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:
    }
}());
Run Code Online (Sandbox Code Playgroud)

你可以看到发送速度超过5毫秒的每个请求都会返回false,否则处理程序会运行.

您可以简单地断开发送请求超过5毫秒(或2毫秒,或3毫秒,取决于您的网络和您的应用程序的重量......)的套接字.

您也可以在客户端站点上使用js事件限制来确保所有请求的发送速度都不超过速度限制!

这种技术不会提供绝对的保护,不会受到攻击,但它会阻止你的服务器在攻击者尝试Dos时崩溃......


Ani*_*mir 10

速率限制器灵活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
    });
});
Run Code Online (Sandbox Code Playgroud)

任何事件将被阻止,如果它每秒发生超过 5 次。

还可以选择使用 Redis 的分布式应用程序。一些灵活的设置,如保险和块策略,rate-limiter-flexible可实现高可用性和快速性。