防止 socket.io 垃圾邮件套接字

Prevent socket.io spamming sockets

我正在使用 socket.io 制作多人游戏。这是我的服务器代码的一部分。

io.on('connection', (socket) => {
    console.log("socket has connected!!")
    socket.on("go", (name) => {
       addPlayer(name);
    })
    
    socket.on("move", (angle) => {
     //do movement stuff
    })
})

现在人们通过创建垃圾邮件套接字使我的服务器崩溃。他们正在打开控制台并在客户端中输入此代码:

setInterval(() => {
var socket = io()
socket.emit("go", "haha ugothacked")
},10)

这每秒创建 100 个玩家并最终导致我的服务器崩溃。我该如何防止这种情况。我知道你必须使用某种速率限制。我不知道如何获取套接字的ip。

我正在使用 socket.io v4

我该怎么做?

查看https://socket.io/docs/v3/server-api/,可以使用socket.handshake.address获取连接客户端的IP。之后,您需要建立一个服务器端数组或 object 包含 ips 以及他们提出的请求数量,这样您就可以建立一个速率限制器并检查他们在最后一次提出的请求数量分钟,您也可以完全阻止来自同一连接的新请求或诸如创建新玩家之类的事情。

你也可以强制人们在玩你的游戏之前创建一个帐户并验证他们的电子邮件,但是使用 https://temp-mail.org/en/ 之类的东西可以在大约 10 秒内完成,所以虽然它可能是一个额外的层保护并减慢它们的速度,它不会阻止您的问题。

您还可以访问请求 object 中的请求 header,由此您可以对它们进行数字指纹识别。然而,更好的解决方案可能是将 uuid 值存储为 cookie/localStorage 并让客户端将其作为请求 header 传递,以免陷入 GDPR 或侵犯人们隐私的麻烦。在那种情况下,他们将无法只生成自己的 uuid,您可以非常有目的地将他们的 uuid 作为目标,以便在套接字事件上对他们进行 limit/block 评级。然而,这与首先使用他们的 IP 有点相似。

我看不出有什么方法可以在不使用一些唯一标识符(如 IP 或 uuid)并构建速率限制器服务器端的情况下实现你想要的。除此之外,您可以使用像 cloudflare 这样的安全服务来为您设置速率限制,https://blog.cloudflare.com/cloudflare-traffic/,您可以在其中对 auth 令牌进行速率限制等,但我认为如果您需要立即进行速率限制,它不会起作用即使在第二次调用时也会阻止事件(我不知道他们的规则是否允许该级别的配置)。