使用 Firewall 扩展包全面保护 Laravel 应用免受恶意攻击


功能简介

Firewall 扩展包是专门为 Laravel 应用打造的 Web 应用防火墙(WAF),该扩展包可用于保护 Laravel 应用免受不同类型的攻击,比如常见的 XSS(跨站脚本攻击)、SQLi(SQL 注入攻击)、RFI(远程文件包含攻击)、LFI(本地文件包含攻击)、User Agent(用户代理注入攻击)等,此外,它还能够屏蔽重复的攻击并且在攻击到来时发送邮件/Slack 通知。

下面我们来简单演示下如何在 Laravel 应用中安装并使用这个扩展包。

安装配置

首先,我们通过 Composer 安装这个扩展包:

composer require akaunting/firewall -vvv

安装完成后,如果你的 Laravel 版本低于 5.5 的话,需要在 config/app.php 中注册服务提供者:

'providers' => [
    ...
    Akaunting\Firewall\Provider::class,
]

如果你使用的 Laravel 版本大于等于 5.5 的话,会自动发现该扩展包,无需手动注册:

接下来,我们发布该扩展包的配置文件及数据库迁移文件到 Laravel 项目中:

php artisan vendor:publish --tag=firewall

这样,我们就可以运行数据库迁移命令创建对应的数据表了:

php artisan migrate

最后我们在 .env 环境文件中添加这一行配置,表示开启 Firewall:

FIREWALL_ENABLED=true

如果你还想对 Firewall 做更多自定义配置,比如通知邮件的配置,可以自行到 config/firewall.php 中去配置。

快速上手

我们通过 Firewall 提供的中间件完成安全防护:

firewall.all

firewall.agent
firewall.geo
firewall.ip
firewall.lfi
firewall.php
firewall.referrer
firewall.rfi
firewall.session
firewall.sqli
firewall.swear
firewall.url
firewall.whitelist
firewall.xss    

这些中间件对应的实现源码位于 vendor/akaunting/firewall/src/Middleware 目录下,你可以自行去查看源码看每个中间件的作用,如果在路由中应用 firewall.all 这个中间件代表会应用所有配置在 firewall.all_middlewares 中的中间件,另外,你还可以将自定义中间件放到这个配置项中。

我们可以按需自由将上述列表中的中间件应用到指定路由或路由分组中来使用它们:

// 应用所有 Firewall 中间件
Route::group(['middleware' => 'firewall.all'], function () {
    Route::get('/', 'HomeController@index');
});

// 应用指定 Firewall 中间件 firewall.whitelist,只允许在白名单中的 IP 访问该分组中的路由
Route::group(['middleware' => 'firewall.whitelist'], function () {
    Route::get('/admin', 'AdminController@index');
});

此外你还可以设置不在 whitelist (位于配置文件 firewall.php 中,用于配置 IP 白名单)中的用户访问指定路由时被阻止并发送通知:

Route::group(['middleware' => 'firewall.url'], function () {
    Route::get('/admin', 'AdminController@index');
});

然后将对应路由添加到 firewall.middleware.url.inspections 配置中即可。

使用示例

下面我们以 firewall.url 为例来演示下这个中间件的安全校验,首先在 firewall.php 中配置一个白名单 IP:

'whitelist' => ['127.0.0.1'],

然后在 middleware.url 配置项的 inspections 中配置检查路由 firewall

'url' => [
    'methods' => ['all'],

    'inspections' => ['firewall'], // i.e. 'admin'

    'auto_block' => [
        'attempts' => 5,
        'frequency' => 1 * 60, // 1 minute
        'period' => 30 * 60, // 30 minutes
    ],
],

并且在 notifications.email 配置项中配置收发邮箱地址(确保 .env 中已经配置过 MAIL_FROM_ADDRESS,Firewall 使用通知的方式发送邮件,所以 mail.to 应该对应系统用户表 users 中某个有效用户的邮箱地址):

'mail' => [
    'enabled' => true,
    'name' => 'Laravel Firewall',
    'from' => env('MAIL_FROM_ADDRESS'),
    'to' => ['yaojinbu@163.com'],
],

最后,我们在路由文件 routes/web.php 中注册这个测试路由:

Route::group(['middleware' => 'firewall.url'], function () {
    Route::get('/firewall', function() {
        return "访问成功";
    });
});

此时访问路由 /firewall,没有任何问题,因为本地 IP 地址是 127.0.0.1 会跳过 Firewall 中间件的检查:

接下来,我们修改下 firewall.whitelist 配置信息:

'whitelist' => ['192.168.10.11'],

再次访问该路由,访问失败:

并且在数据库 firewall_logs 中可以看到访问日志:

同时也会收到通知邮件:

当指定时间段内攻击次数超过 middleware.url.auto_block.attempts 限制后,会将这个发起攻击的 IP 保存到 firewall_ips 表中。

另外,你还可以在 config/firewall.phpmiddleware 中为每个中间件配置路由信息,然后在所有路由中应用这些中间件或者直接应用 firewall.all 中间件,这里就不演示了,感兴趣的同学可以自行去研究下。


点赞 取消点赞 收藏 取消收藏

<< 上一篇: Laravel 学院文本编辑器及 XSS 攻击防范 —— Markdown 编辑器篇

>> 下一篇: Laravel 5 高性能电子商务扩展包 —— Aimeos Laravel