Laravel 12 实现防火墙管理系统
在 Laravel 12 中实现防火墙功能可以帮助你保护应用免受恶意请求和攻击。以下是几种实现防火墙管理的方法:
1. 使用中间件实现基础防火墙
创建防火墙中间件
php artisan make:middleware Firewall
实现中间件逻辑
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Cache;
class Firewall
{
// 黑名单IP列表
protected $blacklist = [
'192.168.1.100',
'10.0.0.5',
];
// 白名单IP列表
protected $whitelist = [
'192.168.1.1',
];
// 请求速率限制(每分钟最大请求数)
protected $rateLimit = 60;
public function handle($request, Closure $next)
{
$ip = $request->ip();
// 检查白名单
if (in_array($ip, $this->whitelist)) {
return $next($request);
}
// 检查黑名单
if (in_array($ip, $this->blacklist)) {
abort(403, 'Access denied');
}
// 速率限制检查
$key = 'firewall:rate_limit:' . $ip;
$requests = Cache::get($key, 0);
if ($requests >= $this->rateLimit) {
abort(429, 'Too many requests');
}
Cache::put($key, $requests + 1, now()->addMinutes(1));
return $next($request);
}
}
注册中间件
在 app/Http/Kernel.php
中:
protected $middleware = [
// ...
\App\Http\Middleware\Firewall::class,
];
2. 使用 Laravel 内置功能
动态IP黑名单/白名单
创建数据库迁移:
php artisan make:migration create_ip_filters_table
Schema::create('ip_filters', function (Blueprint $table) {
$table->id();
$table->string('ip_address');
$table->enum('type', ['blacklist', 'whitelist']);
$table->text('reason')->nullable();
$table->timestamps();
});
更新中间件使用数据库
public function handle($request, Closure $next)
{
$ip = $request->ip();
// 检查白名单
if (IpFilter::where('ip_address', $ip)
->where('type', 'whitelist')
->exists()) {
return $next($request);
}
// 检查黑名单
if (IpFilter::where('ip_address', $ip)
->where('type', 'blacklist')
->exists()) {
abort(403, 'Access denied');
}
// 其余逻辑...
}
3. 使用专业包 - Laravel Firewall
安装 spatie/laravel-ip
composer require spatie/laravel-ip
发布配置文件
php artisan vendor:publish --provider="Spatie\Ip\IpServiceProvider"
配置防火墙规则
在 config/ip.php
中:
return [
'whitelist' => [
'192.168.1.0/24',
],
'blacklist' => [
'10.0.0.5',
],
];
使用中间件
Route::middleware(['spatie.ip'])->group(function () {
// 受保护的路由
});
4. 高级防火墙功能实现
1. 地理封锁
public function handle($request, Closure $next)
{
$country = geoip($request->ip())->getCountry();
// 封锁特定国家
if (in_array($country, ['CN', 'RU', 'IR'])) {
abort(403, 'Access from your country is restricted');
}
return $next($request);
}
2. User-Agent 过滤
public function handle($request, Closure $next)
{
$badBots = [
'AhrefsBot',
'SemrushBot',
'MJ12bot',
];
$userAgent = $request->header('User-Agent');
foreach ($badBots as $bot) {
if (stripos($userAgent, $bot) !== false) {
abort(403, 'Bot access not allowed');
}
}
return $next($request);
}
3. 可疑请求检测
public function handle($request, Closure $next)
{
// 检测SQL注入尝试
$sqlKeywords = ['select', 'insert', 'update', 'delete', 'drop', 'union'];
foreach ($request->all() as $input) {
if (is_string($input)) {
foreach ($sqlKeywords as $keyword) {
if (stripos($input, $keyword) !== false) {
Log::warning('SQL injection attempt from IP: ' . $request->ip());
abort(403, 'Invalid request');
}
}
}
}
return $next($request);
}
5. 管理界面实现
创建防火墙管理控制器
php artisan make:controller Admin/FirewallController --resource
基本实现
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\IpFilter;
use Illuminate\Http\Request;
class FirewallController extends Controller
{
public function index()
{
$filters = IpFilter::latest()->paginate(20);
return view('admin.firewall.index', compact('filters'));
}
public function store(Request $request)
{
$request->validate([
'ip_address' => 'required|ip',
'type' => 'required|in:blacklist,whitelist',
'reason' => 'nullable|string|max:255'
]);
IpFilter::create($request->only(['ip_address', 'type', 'reason']));
return back()->with('success', 'IP filter added');
}
public function destroy(IpFilter $filter)
{
$filter->delete();
return back()->with('success', 'IP filter removed');
}
}
路由定义
Route::prefix('admin')->middleware(['auth', 'admin'])->group(function () {
Route::resource('firewall', \App\Http\Controllers\Admin\FirewallController::class)
->except(['show', 'edit', 'update']);
});
6. 实时监控和日志
创建访问日志模型
php artisan make:model AccessLog -m
迁移文件
Schema::create('access_logs', function (Blueprint $table) {
$table->id();
$table->string('ip_address');
$table->string('user_agent')->nullable();
$table->string('url');
$table->string('method');
$table->integer('status_code');
$table->text('request_data')->nullable();
$table->string('country')->nullable();
$table->boolean('is_blocked')->default(false);
$table->string('block_reason')->nullable();
$table->timestamps();
});
日志记录中间件
public function handle($request, Closure $next)
{
$response = $next($request);
// 记录访问日志
AccessLog::create([
'ip_address' => $request->ip(),
'user_agent' => $request->header('User-Agent'),
'url' => $request->fullUrl(),
'method' => $request->method(),
'status_code' => $response->getStatusCode(),
'country' => geoip($request->ip())->getCountry(),
'request_data' => json_encode($request->except(['password', '_token'])),
]);
return $response;
}
最佳实践建议
- 分层防御:结合多种防护措施(IP过滤、速率限制、请求检测等)
- 动态更新:允许管理员动态添加/移除黑名单和白名单
- 监控报警:设置异常访问的报警机制
- 定期审计:定期检查防火墙日志和规则
- 性能考虑:对于高流量站点,考虑使用Redis缓存IP过滤规则
- 备份规则:定期备份防火墙配置
通过以上方法,你可以在Laravel 12中构建一个功能完善的防火墙系统,有效保护你的应用免受各种网络威胁。