apache - Fail2Ban 忽略本地重定向的 404
问题描述
假设一个不良行为者脚本访问 Apache 服务器以探测漏洞。使用 Fail2Ban 我们可以捕获一些 404 并禁止 IP。现在假设单个网页对 CSS、JS 或图像文件有错误的本地引用。同一合法网站访问者的重复点击将导致一定数量的 404,并可能导致 IP 禁令。
有没有一种好方法可以将这些本地请求与远程请求分开,这样我们就不会禁止有价值的访问者?
我知道所有请求都是远程的,因为页面被返回到浏览器并且页面的内容会触发更多的资产请求。问题是,我们如何知道这种页面加载模式和对同一资源的脚本查询之间的区别?
如果我们确实知道一个请求是基于我们刚刚生成的链接进来的,我们可以做一个 302 重定向而不是返回一个 404,从而避免禁止过程。
可以使用 HTTP Referer 标头。如果 Refer 与请求的页面同源,或者与本地站点 FQDN 相同,那么我们不应该禁止。但是该标题可以被欺骗。那么这是一个好用的工具吗?
我认为可以使用 cookie 或会话随机数,其中可能会从没有当前会话 cookie 的页面中请求资产。但我不知道这样的东西是否是内置功能。
最好的解决方案显然是确保站点上生成的所有页面都包含对该站点的有效引用,但我们都知道这是不可能的。一些 CMS 将版本信息添加到文件,或者他们调整图像路径以包含基于客户端设备/大小的图像大小。在我们找到并修复创建它们的代码之前,任何这些生成的标头都可能是错误的。在我们部署有问题的东西和修复它的时间之间,我担心使用 Fail2Ban(和其他工具)意外禁止合法访问者,这些工具不考虑请求的来源。
是否有其他解决方案来应对这一挑战?谢谢!
解决方案
我们如何知道这种页面加载模式之间的区别
在正常情况下你不会(至少没有一些白名单或黑名单)。但是您知道 URI 或路径段、文件扩展名等,它们绝不会成为此类攻击向量的目标,您可以忽略它们。
一些 CMS 将版本信息添加到文件中,或者他们调整图像路径以包含基于客户端设备/大小的图像大小。
但是您肯定知道正确的前缀,因此允许某些路径段的 RE 是可能的。比如这个:
# regex ignoring site and cms paths:
^<HOST> -[^"]*\"[A-Z]{3,}\s+/(?!site/|cms/)\S+ HTTP/[^"]+" 40\d\s\d+
将忽略这个:
192.0.2.1 - - [02/Mar/2021:18:01:06] "GET /site/style.css?ver=1.0 HTTP/1.1" 404 469
并匹配这个:
192.0.2.1 - - [02/Mar/2021:18:01:06] "GET /xampp/phpmyadmin/scripts/setup.php HTTP/1.1" 404 469
类似地,您可以编写一个带有负前瞻的正则表达式来忽略某些扩展,如.css
or.js
或参数,如?ver=1.0
.
另一种可能性是在特殊日志文件中创建一个特殊的后备位置记录完全更糟糕的请求(而不是访问或错误日志),就像在wiki :: Best practice中描述的那样,这样就可以考虑具有绝对错误 URI 的邪恶者没有匹配任何可以由 Web 服务器处理的正确位置。或者干脆在称为有效位置(路径、前缀、扩展名等)中禁用 404 日志记录。
为了确保或完全避免误报,您可以首先增加maxretry
或减少findtime
并稍微观察一下(因此,尝试次数过多的作恶者会被禁止,而合法用户的“中断”请求会导致 404 但数量不多但仍将被忽略) . 因此,您可以累积应用程序的“有效”404 请求的整个列表(以便编写更精确的正则表达式或在某些位置过滤它)。
推荐阅读
- clojure - Clojure:具有不同数量的递归匿名函数
- google-bigquery - BigQuery 动态查询 - 相当于 SQL Server sp_executesql
- c# - C# - 如何使用 try-catch 块处理此代码中的错误?
- postgresql - 在 PostgreSQL 中创建管理员用户
- python - postgres pg8000 创建数据库
- android - 在 LinearLayout 的横向模式下设置右侧视图
- symfony - 嵌入式管理模板
- c# - 执行Mysql查询时命令执行过程中遇到致命错误
- android - 被杀死时重启一个分离的进程服务,而不将其绑定到应用程序的主进程
- javascript - 移动设备中带箭头的水平菜单栏