我希望减少或减轻到达后端的恶意第 7 层流量(针对性攻击、一般恶意自动抓取)的影响,这些流量会使其变得非常缓慢甚至不可用。这涉及基于负载的攻击,如https://serverfault.com/a/531942/1816
假使,假设:
- 我使用的后端/CMS 速度不是很快(例如,每个动态生成的页面的 TTFB 时间约为 1500ms)。优化它是不可能的,或者说在工作量上非常昂贵。
- 我已经完全扩大了规模,即我使用了尽可能最快的硬件。
- 我无法扩展,即 CMS 不支持主到主复制,因此它仅由单个节点提供服务。
- 我在后端前面使用 CDN,它足够强大,可以处理任何流量,并且可以长时间缓存响应(例如 10 天)。缓存的响应(命中)速度很快,不会再次影响我的后端。未命中显然会到达我的后端。
- 攻击者/机器人不知道我的后端的 IP。
- 一些用例,例如 POST 请求或登录用户(占网站总使用量的一小部分),被设置为绕过 CDN 的缓存,因此它们最终总是会到达后端。
- 对 URL 进行任何更改以使其对 CDN 而言是新的/唯一的(例如,添加
&_foo=1247895239
)最终都会影响后端。 - 首先研究过系统的攻击者将很容易找到非常缓慢的用例(例如,分页到第 10,000 个结果),他们可以将这些用例与 #7 的随机参数一起滥用,使后端陷入瘫痪。
- 我无法预测特定时间内后端所有已知且有效的 URL 和合法参数,以便以某种方式将请求列入白名单或清理 CDN 上的 URL,以减少不必要的请求到达后端。例如,
/search?q=whatever
将/search?foo=bar&q=whatever
100% 产生相同的结果,因为foo=bar
这不是我的后端使用的东西,但我无法在 CDN 级别对其进行清理。 - 有些攻击来自单个 IP,有些攻击来自许多 IP(例如 2000 个或更多),这些 IP 无法猜测或通过 IP 范围轻易过滤掉。
- CDN 提供商和后端主机提供商都提供某种 DDoS 攻击功能,但可能导致我的后端瘫痪的攻击非常小(例如每秒只有 10 个请求),并且从未被视为来自这些提供商的 DDoS 攻击。
- 我确实有监控,当后端受到压力时会立即收到通知,但我不想手动禁止 IP,因为这是不可行的(我可能正在睡觉、做其他事情、度假或者攻击可能来自许多不同的 IP)。
- 我犹豫是否要在后端引入每秒每个 IP 的连接数限制,因为在某个时候,我最终会拒绝合法用户的访问。例如,想象一下在大学或大公司举行关于我的服务的演示/研讨会,数十或数百个浏览器几乎同时从单个 IP 地址使用该服务。如果这些浏览器已登录,则它们将始终到达我的后端,而不会由 CDN 提供服务。另一种情况是公共部门用户都从非常有限的 IP 地址(由政府提供)访问该服务。因此,这将拒绝合法用户的访问,并且对来自许多 IP 的攻击毫无帮助,每个 IP 只发出几个请求。
- 我不想永久地将某些国家的大型 IP 范围列入黑名单,这些国家有时是攻击的起源(例如中国、东欧),因为这是不公平的、错误的,将拒绝来自这些地区的合法用户的访问,并且来自其他地方的攻击不会受到影响。
那么,我该怎么做才能解决这种情况?有没有我假设中没有考虑到的解决方案可以提供帮助?
答案1
我生活在类似的环境中(我不直接管理它,但我与负责管理它的团队合作),我们找到了两种可以很好地协同工作的解决方案。在我们的案例中,我们自己托管应用程序,因此我们可以完全控制流量,但想法是一样的。
您的一些限制非常严格,而且我认为它们相互矛盾,但我认为可以解决。我不确定您的 CDN 是什么,但我推测它是一个您无法真正控制的黑匣子。
我建议在应用程序前面设置另一个(缓存)层来控制和修改流量,我们使用 Varnish 来实现它 - 主要用于缓存,但也用于缓解恶意流量。我可以很小,并且不需要像 CDN 那样长时间缓存,因为它应该只会看到很少的流量。
- 在预设到后端之前清理 URI。通常,您无法在 CDN 中执行此操作,但您可以使用自己的中间人服务器执行此操作。仅允许已知的 URI 和参数,其余的将被切断、输入节流系统或立即拒绝(404、500……)。
- 缓存未命中会导致限制或无服务。根据您的应用程序,即使每个客户端 IP 每秒一次缓存未命中(可能甚至少于一次)也可能指向恶意流量,特别是如果您只看到来自 CDN 的缓存未命中。这要求您对真实的最终用户 IP 有一些了解,并且您可能可以将其范围缩小到排除已登录的用户或已知的良好 IP 范围(可能有更宽松的限制规则或没有限制)。CloudFront 添加了 X-Forwarded-For 标头,也许您的 CDN 也有类似的东西。例如,每个客户端 IP 在 15 秒内有 5 次缓存未命中,拒绝 CDN 中未缓存的错误(可能是 429)持续 60 秒。更长时间内的更多未命中会导致更长的禁令。请参阅此处https://github.com/varnish/varnish-modules/blob/master/docs/vmod_vsthrottle.rst
答案2
我理解你的痛苦——但你面临的是一个不可能完成的任务。鱼与熊掌不可兼得。
通常我会建议使用 fail2ban 作为解决此问题的工具(如果 Web 服务器速率限制不是一种选项),但是您不仅明确表示您甚至无法支持临时禁令,而且由于您的流量来自 CDN,您还需要构建许多功能来报告地址并应用阻止。
我认为你只剩下 2 个行动方案了:
1)将网站扁平化为 html 文件并将其作为静态内容提供
2)在其他地方找工作