资讯专栏INFORMATION COLUMN

利用 Swoole 给应用写个防火墙

Freelander / 3497人阅读

摘要:原理定时检测活跃连接数如果单个连接数超过临时封禁超过永久封禁在连接时候直接关闭永久封禁为了能工作,不能设置为或永久封禁封禁十分钟

原理:

定时检测活跃连接数, 如果单个IP连接数超过20临时封禁, 超过100永久封禁(在TCP连接时候直接关闭)

_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 .= "
";

                echo $connection["remote_ip"];
                echo " => ";
                echo $connection_data[$connection["remote_ip"]];
                echo "
";
            }
        });
        $res->end($timer_id);
        return true;
    }
});

echo "

You need to run following command to init waf:
";
echo "curl -s http://127.0.0.1:9502".$server->_GLOBAL_SESSION["init_waf_u2"];
$server->start();

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30410.html

相关文章

  • 基于 Swoole 的微信扫码登录

    摘要:随着微信的普及,扫码登录方式越来越被现在的应用所使用。这里基于微信公众平台的带参数临时二维码,并且结合的服务实现扫码登录。对于用户扫临时的二维码,微信会触发相应的回调事件,我们需要在该回调事件中处理用户的扫码行为。 随着微信的普及,扫码登录方式越来越被现在的应用所使用。它因为不用去记住密码,只要有微信号即可方便快捷登录。微信的开放平台原生就有支持扫码登录的功能,不过大部分人还是在用公众...

    Half 评论0 收藏0
  • Websocket解析及实现

    摘要:早期的轮询是通过不断自动刷新页面而实现的。长轮询的另一个问题是缺乏标准实现。服务器端接到这个请求后作出回应并不断更新连接状态以保证客户端和服务器端的连接不过期。协议解析协议包含两部分一部分是握手,一部分是数据传输。 Websocket是什么? Websocket是一个因为应用场景越来越复杂而提出的,针对浏览器和web服务器之间双向持续通信而设计,而且优雅地兼容HTTP的协议(我猜想:同...

    XboxYan 评论0 收藏0
  • 学习swoole的心得(一)

    摘要:假如我们要发布封邮件,用一个循环,循环遍执行发邮件操作。我采取的是第二种方式噢。安装完成,需要更改的配置,将放在这个配置中,然后重启。向服务器端发送一个字符串,服务器会返回一个字符串。以上是简单的安装和连同。 什么是swooleswoole是PHP的异步、并行、高性能网络通信引擎,使用纯C语言编写,提供了PHP语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步R...

    huashiou 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<