加入收藏 | 设为首页 | 会员中心 | 我要投稿 莆田站长网 (https://www.0594zz.com.cn/)- 业务安全、应用安全、终端安全、数据分析、数据应用!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

IP门禁:保姆式教你用PHP实现一个IP防火墙

发布时间:2022-08-10 11:00:24 所属栏目:PHP教程 来源:互联网
导读:最近我遇到一个需求,我的一台服务器总是遭到端口扫描和恶意登录攻击,对此可以怎么办呢?似乎除了内网隔离、增强密码认证、证书登录、设置防火墙iptables,网上找不到什么别的方案,对了,还用堡垒机的方案。 这些方案实际上都无法解决我的问题。这是一台公
  最近我遇到一个需求,我的一台服务器总是遭到端口扫描和恶意登录攻击,对此可以怎么办呢?似乎除了内网隔离、增强密码认证、证书登录、设置防火墙iptables,网上找不到什么别的方案,对了,还用堡垒机的方案。
 
  这些方案实际上都无法解决我的问题。这是一台公网服务器,并没有什么复杂的网络结构,所以不能建立内网隔离。调整账号的密码策略,自然是一个方案,但是人工操作太麻烦,而且我一般经常换电脑使用,如果修改密码,公司的和家里的电脑都要更新,很麻烦。设置防火墙自然是运维的基本操作,但是iptables的配置太麻烦,ufw工具还好些,firewall-cmd就麻烦些,而且有一个巨大的痛点,众所周知,大家的出网IP都会经常变,好不容易在命令行里一个字母一个字母的配置好了,睡了一觉,白费了。堡垒机更不是一个主流的方案,有点大材小用,用了堡垒机,反而不能随意使用系统,更何况还没听说过那个免费的堡垒机呢。【推荐:PHP视频教程】
 
  那怎么办呢,作为一个资深的PHP开发者,服务器这块的应用还不是手到擒来,当初连内网穿透都能轻松实现,一个IP过滤系统,小意思。所以我打算自己开发这样一个项目,首先能够实现IP过滤,另外,可以轻松地将IP加入到白名单里,比如访问一个网页,就自动加入到白名单。
 
  整个项目不到几个小时就研发完了,起码满足了我自己的需求,并且实现了这样几个特性:
 
  多进程
  支持并发
  守护进程
  可以通过网页面板管理IP
  流量统计
  拦截记录
  现在我们来一步一步的实现这个系统。
 
  第一步,首先能够简简单单的过滤IP
  使用PHP监听端口并且转发数据的框架很多,对此我选择workerman,原因有3:
 
  运行简单稳定
  方法接口简单
  内置进程守护
  至于具体的安装方法,可以参考他的官方文档。
 
  0f7d3163d512f1d5ed4ba46e69929b1.jpg
 
  workerman的使用方法非常简单,只要10行代码,就实现了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();
 
  }
 
  正如上面代码所示,只有简单几行,便实现了IP监听和转发,其中IP白名单通过数据库查询,并且缓存。
 
  第二步,与ThinkPHP命令行整合在一起
  为了项目开发方便,我都会使用ThinkPHP框架进行开发,它够简单,功能也比较齐全。
 
  
  最终实现的命令行效果如下:
 
  
 
  运行命令
 
  php think door start
 
  php think door start --mode d  // 守护进程重启
 
  重启
 
  php think door restart
 
  停止
 
  php think door stop
 
  workerman的命令参数与thinkphp并不兼容,但是实现这样的效果并不难,实际上很简单,代码如下:
 
  
  <?php
 
   
 
  declare(strict_types=1);
 
   
 
  namespace appcommoncommand;
 
   
 
  use thinkconsoleCommand;
 
  use thinkconsoleInput;
 
  use thinkconsoleinputArgument;
 
  use thinkconsoleinputOption;
 
  use thinkconsoleOutput;
 
   
 
  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的代码
 
      }
 
  }

(编辑:莆田站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读