metalinked/laravel-defender
GitHub: metalinked/laravel-defender
Laravel Defender 是一个模块化的 Laravel 安全工具包,提供 IP 日志、暴力破解防护、蜜罐反垃圾、动态黑名单、多渠道告警和安全审计等综合防护能力。
Stars: 4 | Forks: 0
# Laravel Defender
[](https://github.com/metalinked/laravel-defender/actions/workflows/tests.yml)
[](https://github.com/metalinked/laravel-defender/actions/workflows/phpstan.yml)
[](https://github.com/metalinked/laravel-defender/releases)
[](https://packagist.org/packages/metalinked/laravel-defender)
[](https://github.com/metalinked/laravel-defender/blob/main/LICENSE.md)
一个用于 Laravel 的模块化安全包,提供暴力破解防护、动态 IP 黑名单、国家/地区访问控制、蜜罐垃圾信息防护、实时告警以及 Laravel Pulse 仪表板卡片——所有功能均可配置且注重隐私。
## 环境要求
| Laravel | PHP |
|---------|-------|
| 11.x | ^8.2 |
| 12.x | ^8.2 |
## 功能
- 🛡️ 表单的**蜜罐垃圾信息防护**
- 👁️ 针对可疑活动的**请求日志**和告警系统
- 🚨 **高级风险检测** —— 恶意 user-agent、常见攻击路由、使用常见用户名的登录尝试、路径遍历以及模糊测试模式
- 🔒 **暴力破解防护** —— 在出现过多可疑请求后封禁 IP
- 🌍 **国家/地区访问控制** —— 根据国家代码允许或拒绝访问,支持 IP 白名单绕过
- 🚫 **动态 IP 黑名单** —— 运行时通过 Artisan 封禁/解封 IP;无需更改配置
- 🤖 **自动封禁** —— 自动封禁在可配置时间窗口内触发重复事件的 IP
- 🎯 **Laravel 事件** —— `SuspiciousRequestDetected` 和 `IpBlocked`,提供完全的可扩展性
- 🔔 **多渠道告警** —— log、database、mail、Slack、webhook
- 📊 **Laravel Pulse 卡片** —— 实时安全仪表板(可选,需要 `laravel/pulse`)
- 🔍 **安全审计命令** —— 检测常见的 Laravel 配置错误和缺失的安全标头
- 📝 **Artisan 命令** —— 直接从控制台查看、导出和清理日志
## 安装
**1. 通过 Composer 安装:**
```
composer require metalinked/laravel-defender
```
**2. 发布配置文件:**
```
php artisan vendor:publish --tag=defender-config
```
**3. 发布并运行迁移:**
```
php artisan vendor:publish --tag=defender-migrations
php artisan migrate
```
这将创建两个表:
- `defender_ip_logs` —— 存储访问日志和安全告警
- `defender_blocked_ips` —— 存储动态封禁的 IP
## 全局保护(推荐)
全局注册 Defender 的中间件以保护所有请求——包括那些针对不存在路由(如 `/wp-admin`、`/phpmyadmin` 和 `/xmlrpc.php`)的请求。
**Laravel 11 和 12** (`bootstrap/app.php`):
```
->withMiddleware(function (Middleware $middleware) {
$middleware->append(\Metalinked\LaravelDefender\Http\Middleware\BlockedIpMiddleware::class);
$middleware->append(\Metalinked\LaravelDefender\Http\Middleware\AdvancedDetectionMiddleware::class);
$middleware->append(\Metalinked\LaravelDefender\Http\Middleware\BruteForceMiddleware::class);
$middleware->append(\Metalinked\LaravelDefender\Http\Middleware\CountryAccessMiddleware::class);
})
```
**Laravel 10** (`app/Http/Kernel.php`):
```
protected $middleware = [
// ...
\Metalinked\LaravelDefender\Http\Middleware\BlockedIpMiddleware::class,
\Metalinked\LaravelDefender\Http\Middleware\AdvancedDetectionMiddleware::class,
\Metalinked\LaravelDefender\Http\Middleware\BruteForceMiddleware::class,
\Metalinked\LaravelDefender\Http\Middleware\CountryAccessMiddleware::class,
];
```
| 中间件 | 描述 |
|---|---|
| `BlockedIpMiddleware` | 立即封禁动态黑名单中的 IP(返回 403)。首先运行此项。 |
| `AdvancedDetectionMiddleware` | 检测恶意 user-agent、攻击路由和常见用户名。 |
| `BruteForceMiddleware` | 在配置的窗口期内出现过多可疑请求后封禁 IP。 |
| `CountryAccessMiddleware` | 根据国家代码允许或拒绝访问。 |
## 配置
发布后,所有选项均位于 `config/defender.php` 中。
### IP 日志与暴力破解
```
'ip_logging' => [
'enabled' => true,
'log_all' => false, // Log every request, not just suspicious ones. Only for debugging.
],
'brute_force' => [
'max_attempts' => 5,
'decay_minutes' => 10,
],
```
### 高级检测与国家/地区访问
```
'advanced_detection' => [
'enabled' => true,
'geo_provider' => 'ip-api', // 'ip-api', 'ipinfo', 'ipgeolocation'
'geo_cache_minutes' => 10,
'ipinfo_token' => env('IPINFO_TOKEN'),
'ipgeolocation_key' => env('IPGEOLOCATION_KEY'),
'suspicious_user_agents' => ['curl', 'python', 'sqlmap', 'nmap', 'nikto', 'fuzzer', 'scanner'],
'suspicious_routes' => ['/wp-admin', '/wp-login', '/phpmyadmin', '/admin.php', '/xmlrpc.php'],
'common_usernames' => ['admin', 'administrator', 'root', 'test', 'user'],
'country_access' => [
'mode' => 'allow', // 'allow' = only listed countries; 'deny' = block listed countries
'countries' => ['ES'],
'whitelist_ips' => ['1.2.3.4'], // Always allowed, regardless of country
],
],
```
**Geo 提供商:**
- [ip-api.com](https://ip-api.com/) —— 免费层级,无需注册(默认)
- [ipinfo.io](https://ipinfo.io/) —— 需要 `IPINFO_TOKEN`
- [ipgeolocation.io](https://ipgeolocation.io/) —— 需要 `IPGEOLOCATION_KEY`
### 动态 IP 黑名单与自动封禁
```
'blocklist' => [
'enabled' => true,
'cache_ttl' => 300, // Seconds to cache each IP's blocked status
'auto_block_after' => null, // IpBlocked events before auto-blocking (null = disabled)
'auto_block_hours' => null, // Duration of auto-block in hours (null = permanent)
'auto_block_window_hours' => 24, // Sliding window in hours for counting events
],
```
### 告警
```
'alerts' => [
'channels' => ['log', 'database'], // Also: 'mail', 'slack', 'webhook'
'mail' => ['to' => env('DEFENDER_ALERT_MAIL_TO')],
'slack' => ['webhook_url' => env('DEFENDER_SLACK_WEBHOOK')],
'webhook' => ['url' => env('DEFENDER_ALERT_WEBHOOK')],
],
```
### 环境变量
| 变量 | 描述 |
|---|---|
| `DEFENDER_GEO_PROVIDER` | Geo 提供商:`ip-api`、`ipinfo` 或 `ipgeolocation` |
| `IPINFO_TOKEN` | ipinfo.io 的 API token |
| `IPGEOLOCATION_KEY` | ipgeolocation.io 的 API key |
| `DEFENDER_ALERT_MAIL_TO` | 接收告警通知的电子邮件地址 |
| `DEFENDER_SLACK_WEBHOOK` | Slack 的传入 webhook URL |
| `DEFENDER_ALERT_WEBHOOK` | 用于告警通知的自定义 webhook URL |
## 动态 IP 黑名单
在运行时封禁和解封 IP,无需修改配置文件或重新部署:
```
# 永久 Block
php artisan defender:block-ip 1.2.3.4 --reason="Persistent attacker"
# Block 24 小时
php artisan defender:block-ip 1.2.3.4 --reason="Brute force" --hours=24
# Unblock
php artisan defender:unblock-ip 1.2.3.4
# 列出所有当前被 Block 的 IP
php artisan defender:block-list
```
被封禁的 IP 存储在 `defender_blocked_ips` 中并被缓存(默认每个 IP 缓存 5 分钟),以便在每次请求时快速查找。
## 自动封禁
Defender 可以自动封禁在时间窗口内触发重复 `IpBlocked` 事件的 IP —— 这对于在无需人工干预的情况下捕捉顽固的攻击者非常有用。
在 `config/defender.php` 中启用它:
```
'blocklist' => [
'auto_block_after' => 5, // Block after 5 triggered events
'auto_block_hours' => 24, // Block for 24 hours (null = permanent)
'auto_block_window_hours' => 24, // Count events within a 24-hour sliding window
],
```
使用此配置,任何在 24 小时内导致 5 次封禁请求的 IP 都将被自动添加到黑名单中并封禁 24 小时。计数器在封禁后重置。
自动封禁**默认禁用**(`auto_block_after: null`)。
## 事件与可扩展性
Defender 会触发标准的 Laravel 事件,您可以在应用程序中监听这些事件:
```
use Metalinked\LaravelDefender\Events\SuspiciousRequestDetected;
use Metalinked\LaravelDefender\Events\IpBlocked;
// In your EventServiceProvider or AppServiceProvider boot():
Event::listen(SuspiciousRequestDetected::class, function ($event) {
// $event->ip, $event->reason, $event->request
// Fired when a threat is detected, even if the request is not blocked
});
Event::listen(IpBlocked::class, function ($event) {
// $event->ip, $event->reason, $event->request
// Fired when a middleware actually blocks a request (returns 429 or 403)
});
```
使用这些事件可以与您自己的通知系统、SIEM、审计跟踪或任何自定义逻辑进行集成——而无需修改该软件包。
## 蜜罐垃圾信息防护
使用隐藏字段和基于时间的检查来保护表单免受机器人侵害。
**1. 将蜜罐字段添加到您的 Blade 表单中:**
```
@defenderHoneypot
```
**2. 启用自动保护或按路由使用中间件:**
```
// config/defender.php
'honeypot' => [
'auto_protect_forms' => true,
],
```
或者手动应用它:
```
Route::post('/contact', ...)->middleware('defender.honeypot');
```
**发布视图(可选):**
```
php artisan vendor:publish --tag=defender-views
```
## 告警系统
Defender 支持多个用于实时通知的告警渠道。
| 渠道 | 描述 | 默认 |
|---------|-------------|---------|
| `log` | 写入 Laravel 的应用程序日志 | 开启 |
| `database` | 将告警保存到 `defender_ip_logs` | 开启 |
| `mail` | 向 `DEFENDER_ALERT_MAIL_TO` 发送电子邮件 | 关闭 |
| `slack` | 向 Slack webhook 发送消息 | 关闭 |
| `webhook` | 向任何 URL 发起 POST 请求 | 关闭 |
## Laravel Pulse 卡片
如果安装了 [Laravel Pulse](https://pulse.laravel.com/),Defender 会自动注册一个带有实时安全活动的仪表板卡片。
将该卡片添加到您的 Pulse 仪表板视图中:
```
```
该卡片显示:
- 过去一小时检测到的威胁
- 记录的威胁总数
- 前 5 个攻击 IP
- 最新的 8 个检测事件(每 10 秒自动刷新一次)
无需额外配置。当检测到 Pulse 和 Livewire 时,该卡片会自动注册。
## Artisan 命令
### 查看日志
```
php artisan defender:ip-logs # Latest 50 logs
php artisan defender:ip-logs --suspicious # Only suspicious logs
php artisan defender:ip-logs --ip=1.2.3.4 # Filter by IP
php artisan defender:ip-logs --limit=100 # Limit results
```
### 导出日志
```
php artisan defender:export-logs --format=csv
php artisan defender:export-logs --suspicious --format=json --output=suspicious.json
php artisan defender:export-logs --ip=1.2.3.4 --from=2024-06-01 --to=2024-06-30 --format=csv
```
### 清理旧日志
```
php artisan defender:prune-logs --days=90 # Delete logs older than 90 days
php artisan defender:prune-logs --days=30 --laravel # Also remove old Laravel log files
```
**计划清理** —— 添加到您的调度程序中:
对于 Laravel 11+ (`bootstrap/routes/console.php`):
```
Schedule::command('defender:prune-logs --days=90')->daily();
```
对于 Laravel 10 (`app/Console/Kernel.php`):
```
$schedule->command('defender:prune-logs --days=90')->daily();
```
## 安全审计
对您的 Laravel 应用程序的安全配置运行本地审计:
```
php artisan defender:audit
```
检查内容包括:
- 可公开访问的 `.env` 文件
- 在生产环境中启用了 `APP_DEBUG`
- 过于宽松的 CORS 配置(`allowed_origins = "*"`)
- 不安全的 session cookie(缺少 `secure` 或 `http_only` 标志)
- `APP_KEY` 过弱或缺失
- 缺失 HTTP 安全标头(`X-Frame-Options`、`X-Content-Type-Options`、`Referrer-Policy`、`Strict-Transport-Security`)
每个问题都包含具体的修复提示。
## 测试
```
composer test
```
## 安全
如需报告安全漏洞,请发送电子邮件至 [security@metalinked.net](mailto:security@metalinked.net)。所有报告都将得到负责任和保密的处理。
## 贡献
请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 了解贡献指南。
## 许可证
MIT © [Metalinked](https://metalinked.net)
💬 [有问题、建议或反馈?发起讨论。](https://github.com/metalinked/laravel-defender/discussions)
标签:CISA项目, ffuf, Laravel, OpenVAS, PHP, Syscall, Web开发, 安全防护, 应用防火墙, 日志告警, 服务器监控, 蜜罐, 证书利用