如何利用php实现一个ip防火墙

555 ℃

如何利用php实现一个ip防火墙,利用php监听端口并且转发数据的框架很多,我们今天讲的是用workerman来实现。

1、利用workerman方法实现了IP转发+白名单过滤:

$worker = new Worker('tcp:0.0.0.0:' . Config::get('door.port_in'));
// 监听一个端口
$worker->count = 2;
// 设置多进程
$worker->onConnect = function (TcpConnection $connection) {
  // 获取IP白名单
  $list_ip = AppIp::where('status', 0)->cache(3)->column('ip');
  $remote_ip = $connection->getRemoteIp();
  // 拦截IP
  if (!in_array($remote_ip, $list_ip)) {
    $connection->close();
  }
  // 放行连接,连接内部目标端口
  $to_connection = new AsyncTcpConnection('tcp:127.0.0.1:' . Config::get('door.port_to'));
  // 互相转发流量
  $connection->pipe($to_connection);
  $to_connection->pipe($connection);
  $to_connection->connect();
}

兼容

<?php
declare(strict_types=1);

namespace app\common\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;

class Door extends Command
{
  protected function configure()
  {
     // 指令配置
     $this->setName('door')
         // 设置think的命令参数
         ->addArgument('action', Argument::OPTIONAL, "start|stop|restart|reload|status|connections", 'start')
         ->addOption('mode', 'm', Option::VALUE_OPTIONAL, 'Run the workerman server in daemon mode.')
         ->setDescription('the door command');
  }
  protected function execute(Input $input, Output $output)
  {
     // 指令输出
     $output->writeln('door');
     $action = $input->getArgument('action');
     $mode = $input->getOption('mode');
     // 重新构造命令行参数,以便兼容workerman的命令
     global $argv;
     $argv = [];
     array_unshift($argv, 'think', $action);
     if ($mode == 'd') {
         $argv[] = '-d';
     } else if ($mode == 'g') {
         $argv[] = '-g';
     }
     // ...workerman的代码
  }
}
?>

2、流量统计

<?php
// 向TO发起连接
$to_connection = new AsyncTcpConnection('tcp://127.0.0.1:' . Config::get('door.port_to'));
$to_connection->onMessage = function ($source, $data) use ($connection, $remote_ip) {
    // 接收到来自TO的数据,返回的数据
    $connection->send($data);
    // 将流量统计存储到内存里
    Cache::inc(md5($remote_ip) . '-to', strlen($data));
};
// 流程和流量控制
$to_connection->onClose = function ($source) use ($connection) {
    $connection->close();
};
$connection->onBufferFull = function ($dest) use ($to_connection) {
    $to_connection->pauseRecv();
};
$connection->onBufferDrain = function ($dest) use ($to_connection) {
    $to_connection->resumeRecv();
};
$connection->onMessage = function ($source, $data) use ($to_connection, $remote_ip) {
    // 接收来自IN的数据,请求的数据
    $to_connection->send($data);
    // 将流量统计存储到内存里
    Cache::inc(md5($remote_ip) . '-in', strlen($data));
};
// 流程和流量控制
$connection->onClose = function ($source) use ($to_connection) {
    $to_connection->close();
};
$to_connection->onBufferFull = function ($dest) use ($connection) {
    $connection->pauseRecv();
};
$to_connection->onBufferDrain = function ($dest) use ($connection) {
    $connection->resumeRecv();
};
?>

3、拦截统计

<?php
$worker->onConnect = function (TcpConnection $connection) {
    $disable_cache_key = 'disable_ip_list';
    $list_ip = Cache::get($disable_cache_key);
    if (empty($list_ip)) {
        $connection->close();
    }
    $remote_ip = $connection->getRemoteIp();
    if (!in_array($remote_ip, $list_ip)) {
        AppIpReject::initRecord($remote_ip);
        $connection->close();
    }
};
?>

php利用微信小程序实现pdf文件的预览功能

php字符串长度不够前后自动补0

php字符串拼接方法介绍

php可以利用for循环来实现阶乘算法吗?

php简单介绍DI注入方法

标签: ip防火墙, php, workerman

上面是“如何利用php实现一个ip防火墙”的全面内容,想了解更多关于 php入门 内容,请继续关注web建站教程。

当前网址:https://m.ipkd.cn/webs_2298.html

声明:本站提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请发送到邮箱:admin@ipkd.cn,我们会在看到邮件的第一时间内为您处理!

推荐一款免费开源的Vue可拖拽组件——VueDraggablePlus
如何利用mysql语句来修改密码
Vue中如何在子组件中验证props
域名单解析会对SEO产生不好的影响吗?
mac笔记本电脑快捷键大全(新手宝典)