利用 Swoole 给应用写个防火墙
原理:
定时检测活跃连接数, 如果单个IP连接数超过20临时封禁, 超过100永久封禁(在TCP连接时候直接关闭)
<?php
$server = new swoole_http_server("0.0.0.0", 9502);
$server->_GLOBAL_SESSION = [];
$server->_GLOBAL_SESSION['ban'] = [];
$server->_GLOBAL_SESSION['ban_forever'] = [];
$server->_GLOBAL_SESSION['init_waf_u2'] = '/init_waf_KKDL_d'.mt_rand(100000, 9999999);
$server->on('connect', function ($server, $fd, $fi) {
# 永久封禁
# 为了能工作, dispatch_mode_mode不能设置为1或3
$connection_info = $server->connection_info($fd);
if( $this->_GLOBAL_SESSION['ban_forever'][$connection_info['remote_ip']] == 1 ){
$server->close($fd);
return;
}
});
$server->on('request', function ($req, $res) use ($server) {
# 永久封禁
if( $this->_GLOBAL_SESSION['ban_forever'][$req->server['remote_addr']] == 1 ){
return;
}
# 封禁十分钟
if( $this->_GLOBAL_SESSION['ban'][$time-$time%600][$req->server['remote_addr']] == 1 ){
$res->status(204); $res->end(); return;
}
$time = time();
if ($req->server['request_uri'] == $server->_GLOBAL_SESSION['init_waf_u2'] ){
$timer_id = $this->tick(500, function(){
if($this->connection_list(-1, 50) < 51) return 0;
$connection_list = $this->connection_list(-1, 20000);
$connection_data = []; // ip -> connection_count
foreach ($connection_list as $connection_id) {
$connection = $this->connection_info($connection_id);
if (!isset($connection_data[$connection['remote_ip']])) {
$connection_data[$connection['remote_ip']] = 0;
} else if ($connection_data[$connection['remote_ip']] > 20) {
$this->_GLOBAL_SESSION['ban'][$time-$time%600][$connection['remote_ip']] = 1;
} else if ($connection_data[$connection['remote_ip']] > 100) {
$this->_GLOBAL_SESSION['ban_forever'][$connection['remote_ip']] = 1;
}
$connection_data[$connection['remote_ip']] ++;
$str = "";
$str .= $connection['remote_ip'];
$str .= " => ";
$str .= $connection_data[$connection['remote_ip']];
$str .= "\n";
echo $connection['remote_ip'];
echo " => ";
echo $connection_data[$connection['remote_ip']];
echo "\n";
}
});
$res->end($timer_id);
return true;
}
});
echo "\n\nYou need to run following command to init waf:\n";
echo "curl -s http://127.0.0.1:9502".$server->_GLOBAL_SESSION['init_waf_u2'];
$server->start();
千里码博客
A.R.G.U.S.网络安全小组
推荐阅读
个人如何免费接入微信支付, 不用交300块钱
也不是没有办法, 微信现在推出了"服务商"模式, 也就是给线下小微商户开通微信收款的权限. 而微信为了方便服务商拓展业务, 给了服务商替商户发起支付的 API 接口, 支付完成再通知到服务商. 然后第二天, 到账的钱会...
ARGUS赞 3阅读 8k
php实现只需要一个QQ号就可以获得用户信息
{代码...} DEMO:[链接]此处输入你的QQ号
TANKING赞 27阅读 7.3k评论 5
初学后端,如何做好表结构设计?
这篇文章介绍了设计数据库表结构应该考虑的4个方面,还有优雅设计的6个原则,举了一个例子分享了我的设计思路,为了提高性能我们也要从多方面考虑缓存问题。
王中阳Go赞 4阅读 1.7k评论 2
一分钟搞明白!快速掌握 Go WebAssembly
最近因为各种奇怪的原因,更多的接触到了 WebAssembly。虽然之前很多博客也翻过写过各种文章,但总感觉欠些味道。于是今天梳理了一版,和大家一起展开学习。
煎鱼赞 4阅读 2.1k
面试官:请说一下如何优化结构体的性能?
使用内存对齐机制优化结构体性能,妙啊!前言之前分享过2篇结构体文章:10秒改struct性能直接提升15%,产品姐姐都夸我好棒 和 Go语言空结构体这3种妙用,你知道吗? 得到了大家的好评。这篇继续分享进阶内容:结...
王中阳Go赞 4阅读 3.8k评论 2
Laravel入门及实践,快速上手ThinkSNS+二次开发
【摘要】自从ThinkSNS+不使用ThinkPHP框架而使用Laravel框架之后,很多人都说技术门槛抬高了,其实你与TS+的距离仅仅只是学习一个新框架而已,所以,我们今天来说说Laravel的入门。
ThinkSNS赞 1阅读 2.4k
我让chatGPT用PHP写一个MVC框架,不仅写出来,还能跑!
没想到写出来的框架确实挺简单的,但是又没觉得哪里不对,于是我尝试把这个框架放到服务器试试能不能跑起来,最后还真的可以跑起来,为了让大家能够看到这个框架的演示,我直接爬一个热搜,然后便于展示数据。
TANKING赞 1阅读 1.7k
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。