编程

阻止 Laravel 应用的无效请求

7 2025-11-14 01:56:00

你的 Laravel 应用被各种无效请求轰炸。它们来自各种各样的机器人程序。大多数都是在探测攻击向量。常见的攻击目标包括 /wp-admin/login.php.env 文件。

大多数情况下,你的 Web 服务器只会返回 404 Not Found 错误码。但它仍然会处理请求。根据网站的受欢迎程度,你每秒可能会收到数十个甚至数百个这样的请求。

在过去的一个月里,我一直在努力优化 laravelshift.com 的加载时间。根据 80/20 规则,大部分加载时间都用于响应请求。当然,数据库查询或复杂计算等操作也需要时间。但与连接、处理和响应 Web 请求所需的总时间相比,这根本不算什么。

因此,我的目标是减少发送到 Web 服务器的请求。我将在以后的文章中介绍更多策略。本文中,我将通过阻止无效请求来减少请求数量。这释放了我的 Web 服务器来处理有效请求。如果我使用按请求计费的服务(例如 Nightwatch),减少 Web 服务器的流量也很重要。

这个想法实际上就是从这里来的。Michael Dyrynda 写了一篇关于保护 Laravel Cloud 端点的文章。他注意到日志中存在无效请求,这些请求正在耗尽他的请求配额。

他在 Cloudflare 中设置了一条安全规则来阻止对这些端点的请求。这让我想到:“如果可以阻止所有无效请求会怎么样?” 我记得我在计算机安全课上的一个观点——指定允许的内容比指定不允许的内容更好。允许的内容是一个已知的、有限的列表。不允许的内容是一个未知的、无限的列表。

即使没有 Laravel 应用,我们也知道允许哪些端点。我们可以通过运行 artisan route:list 来列出它们。将其转换为有效规则非常简单。任何带有参数的内容(例如模型绑定)都可以转换为通配符表达式。其他所有内容都是精确匹配。

例如以下路由:

Route::get('/', [HomeController::class, 'index'])->name('home');
Route::view('/faq', 'faq');
Route::get('shifts', [ShiftController::class, 'index'])->name('shifts');
Route::get('workbench/{task:slug}', [TaskController::class, 'show'])->name('task.show');

可以用以下表达式表示:

not (http.request.uri.path in {"/" "/faq" "/shifts"} or http.request.uri.path wildcard "/workbench/*")

我在 Cloudflare 为 laravelshift.com启用了这样的安全规则。现在我的应用只允许流量到达现有的端点。其他任何内容都将被 Cloudflare 阻止。在短短一周内,超过 5000 个无效请求被阻止。释放我的 web 服务器以处理有效请求。

与往常一样,这需要权衡。Cloudflare 免费计划只允许阻止操作。这将渲染一个 Cloudflare 错误页面,其中包含 403 Forbidden 响应。理想情况下,你可能会用一个简单的 404 Not Found 来回应。考虑到我堵塞的流量,我对此感到满意。但是,有拼写错误或链接中断的合法用户将收到此 Cloudflare 错误页面。通过确保对常见拼写错误或重命名路径进行重定向,可以缓解这种情况。