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

如何利用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实现一个ip防火墙”的全面内容,想了解更多关于 php入门 内容,请继续关注编程基础学习网。

本文标题为:如何利用php实现一个ip防火墙

基础教程推荐