最近我遇到一个需求,我的一台服务器总是遭到端口扫描和恶意登录攻击,对此可以怎么办呢?似乎除了内网隔离、增强密码认证、证书登录、设置防火墙iptables,网上找不到什么别的方案,对了,还用堡垒机的方案 。
这些方案实际上都无法解决我的问题 。这是一台公网服务器,并没有什么复杂的网络结构,所以不能建立内网隔离 。调整账号的密码策略,自然是一个方案,但是人工操作太麻烦,而且我一般经常换电脑使用,如果修改密码,公司的和家里的电脑都要更新,很麻烦 。设置防火墙自然是运维的基本操作,但是iptables的配置太麻烦,ufw工具还好些,firewall-cmd就麻烦些,而且有一个巨大的痛点,众所周知,大家的出网IP都会经常变,好不容易在命令行里一个字母一个字母的配置好了,睡了一觉,白费了 。堡垒机更不是一个主流的方案,有点大材小用,用了堡垒机,反而不能随意使用系统,更何况还没听说过那个免费的堡垒机呢 。
那怎么办呢,作为一个资深的php开发者,服务器这块的应用还不是手到擒来,当初连内网穿透都能轻松实现,一个IP过滤系统,小意思 。所以我打算自己开发这样一个项目,首先能够实现IP过滤,另外,可以轻松地将IP加入到白名单里,比如访问一个网页,就自动加入到白名单 。
整个项目不到几个小时就研发完了,起码满足了我自己的需求,并且实现了这样几个特性:
- 多进程
- 支持并发
- 守护进程
- 可以通过网页面板管理IP
- 流量统计
- 拦截记录
第一步,首先能够简简单单的过滤IP使用PHP监听端口并且转发数据的框架很多,对此我选择workerman,原因有3:
- 运行简单稳定
- 方法接口简单
- 内置进程守护
文章插图
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();// 拦截IPif (!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框架进行开发,它够简单,功能也比较齐全 。
文章插图
最终实现的命令行效果如下:
【IP门禁:手把手教你用PHP实现一个IP防火墙】
运行命令php think door start php think door start --mode d// 守护进程重启重启php think door restart停止php think door stopworkerman的命令参数与thinkphp并不兼容,但是实现这样的效果并不难,实际上很简单,代码如下:<?phpdeclare(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的代码}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 固件更新处难寻?手把手教你用影驰魔盘更新SSD固件
- 教你如何取个好听的英文名字 怎么取英文名
- 微信设置更换修改气泡和主题教程 微信皮肤怎么设置
- 教师|宝丰县2022年招聘教师200名,8月2日起开始报名
- 教师资格证报名照片是教师资格证的照片吗 教师资格证报名照片要求是什么
- 大学教育技术学专业简析 教育技术学是什么专业
- nfc怎么复制门禁卡iQOO nfc怎么复制门禁卡
- 金宝贝和其他早教机构相比到底好在哪儿 金宝贝早教怎么样
- 教你制作电子相册,一分钟就能学会 如何制作电子相册
- 3种方法教你查看电脑真实配置 怎么查电脑配置
