如何保护 Web 应用程序免受 IPv6 机器人的攻击?

如何保护 Web 应用程序免受 IPv6 机器人的攻击?

我对此很感兴趣,因为它可以保护 Web 应用程序免受机器人攻击,但我猜它适用于机器人通过 IPv6 发起的所有类型的攻击。

在 Web 应用程序中,您需要保护某些页面免受机器人的攻击。

它可能是一个登录页面:您想避免数百万个尝试用户名/密码组合的请求。

这可能是一个注册页面。您不希望在您的网站上创建数千个机器人账户。

或者您可能不希望一次性下载数据库的全部内容。您认为匿名用户每天向您的数据库发出 100 或 200 个请求以获取一些信息是可以的,但您不能接受机器人以每分钟 1000 个请求的速度下载您提供的所有内容。

或者只是为了统计目的。您正在记录访客在网站上的活动,您不希望机器人完全歪曲您的数据,比如,人为地点击链接数千次,以便它链接到的文章成为您的新闻网站上的“最受欢迎的文章”。

我经常使用基于 IP 地址的限制/速率限制来处理这个问题,使用 Nginx 速率限制功能:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/m;    

server {
    location /sensitiveUrl {
        limit_req zone=mylimit;

        proxy_pass http://my_upstream;
    }
}

但对于 IPv6,我不确定这种方法有多有效。我的意思是,对于 IPv4,这种方法相对有效,因为攻击者创建和使用数千个 IP 地址的成本很高,但对于 IPv6,似乎任何人都可以创建数百万个 IP。如何处理这个问题?我应该对 IPv6 网络而不是地址应用限制吗?如果我这样做,在实践中效果如何?

答案1

IPv6 在寻址方面的灵活性非常好,但确实使这样的事情变得更加困难。我推荐一种算法:

  • 首先阻止单独的 IPv6 地址 (a /128)。它可能是网络上的单个用户,该网络有多个用户,并且您要避免阻止无辜用户(由于 NAT,IPv4 中经常发生这种情况,我们不再赘述)
  • x如果同一个 中有超过块/64,则假设整体/64已被污染并阻止所有块。您现在可以/128从黑名单中删除单个记录,因为它们现在已被 覆盖/64。这可以防止黑名单系统溢出内存/存储。
  • 攻击者可能拥有不止一个/64。默认大小为/48,但会出现/56和 偶数/60(对于 IPv6 来说太小了,但有些 ISP 永远不会知道)。我会按每 4 位进行扩展:如果/64来自同一个 的多个/60被阻止,则扩展以阻止整个/60。对于/60a 中的多个 等,情况相同/56
  • /64我还建议对不同的前缀长度使用不同的黑名单超时时间。单个用户意外阻止某个用户比某人“意外”阻止整个用户更容易/48。在我看来,较大的阻止时间应该在黑名单上保留更长时间。
  • 攻击者可能会滥用此算法,从一开始就将攻击扩展到整个系统/48,从而无法快速触发扩展算法。因此,您可能需要并行设置多个条件以快速扩展。

这种扩展机制的一个例子可能是:

+---------------+----------------------------------------+-----------+
|               |   Block when containing >= of these:   | Blacklist |
| Prefix length |  /128  |  /64  |  /60  |  /56  |  /52  |   time    |
+---------------+--------+-------+-------+-------+-------+-----------+
|     /128      |   N/A  |  N/A  |  N/A  |  N/A  |  N/A  |    5 min  |
|      /64      |     5  |  N/A  |  N/A  |  N/A  |  N/A  |   15 min  |
|      /60      |    15  |    2  |  N/A  |  N/A  |  N/A  |   30 min  |
|      /56      |    50  |    4  |    2  |  N/A  |  N/A  |   60 min  |
|      /52      |    75  |    8  |    4  |    2  |  N/A  |  120 min  |
|      /48      |   100  |   16  |    8  |    4  |    2  |  240 min  |
+---------------+--------+-------+-------+-------+-------+-----------+

答案2

你可以做一些非常原始的事情通过正则表达式进行 IP 子网划分。在这里,我传递 IPv4 地址,不做任何更改,但抓取 IPv6 地址的前半部分,这对应于地址的 /64 前缀。因此,nginx 将同时跟踪整个 /64 的速率限制。

map $binary_remote_addr $masked_ip_addr {
        # Extract the first half (the /64 prefix) of an ipv6 address
        "~^(?P<a>........)........$" "$a";
        # Extract the entire ipv4 address
        "~^(?P<a>....)$" "$a";
}

limit_req_zone $masked_ip_addr zone=myzone:10m rate=1r/s;

server {
        limit_req zone=myzone;
}

相关内容