Przeglądaj źródła

feat: dual stack node ip

M1Screw 1 rok temu
rodzic
commit
672b7b37d5

+ 0 - 2
README.md

@@ -40,8 +40,6 @@ SSPanel UIM is a multi-purpose proxy service sales management system designed fo
 - 深度集成大型语言模型(Large Language Model),支持工单智能回复,文档生成等功能
 - 一键对接 OpenAI,Gemini Pro,Hugging Face Hosted API 和 Cloudflare Workers AI 等人工智能服务
 
-
-
 - Integrate multiple payment systems such as Alipay F2F, PayPal, Stripe, etc.
 - Support multiple mail services, built-in mail queue function, no third-party components are required to use
 - Built-in tabler theme based on Bootstrap 5, template engine support

+ 28 - 21
composer.lock

@@ -4367,29 +4367,29 @@
         },
         {
             "name": "srmklive/paypal",
-            "version": "3.0.28",
+            "version": "3.0.30",
             "source": {
                 "type": "git",
                 "url": "https://github.com/srmklive/laravel-paypal.git",
-                "reference": "6bde2b232a38c413f730115743cc9dcc29d4228e"
+                "reference": "d511038ff01f466e7bfca475c7417b5a6c4d38a5"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/srmklive/laravel-paypal/zipball/6bde2b232a38c413f730115743cc9dcc29d4228e",
-                "reference": "6bde2b232a38c413f730115743cc9dcc29d4228e",
+                "url": "https://api.github.com/repos/srmklive/laravel-paypal/zipball/d511038ff01f466e7bfca475c7417b5a6c4d38a5",
+                "reference": "d511038ff01f466e7bfca475c7417b5a6c4d38a5",
                 "shasum": ""
             },
             "require": {
                 "ext-curl": "*",
                 "guzzlehttp/guzzle": "~7.0",
-                "illuminate/support": "~6.0|~7.0|~8.0|~9.0|^10.0",
-                "nesbot/carbon": "~2.0",
+                "illuminate/support": "~6.0|~7.0|~8.0|~9.0|^10.0|^11.0",
+                "nesbot/carbon": "~2.0|^3.0",
                 "php": ">=7.2|^8.0"
             },
             "require-dev": {
                 "phpstan/phpstan": "^1.10",
                 "phpunit/phpunit": "^8.0|^9.0|^10.0",
-                "symfony/var-dumper": "~5.0"
+                "symfony/var-dumper": "~5.0|^7.0"
             },
             "type": "library",
             "extra": {
@@ -4427,9 +4427,9 @@
             ],
             "support": {
                 "issues": "https://github.com/srmklive/laravel-paypal/issues",
-                "source": "https://github.com/srmklive/laravel-paypal/tree/3.0.28"
+                "source": "https://github.com/srmklive/laravel-paypal/tree/3.0.30"
             },
-            "time": "2023-12-20T18:57:16+00:00"
+            "time": "2024-03-03T15:33:56+00:00"
         },
         {
             "name": "starkbank/ecdsa",
@@ -7028,20 +7028,21 @@
         },
         {
             "name": "phar-io/manifest",
-            "version": "2.0.3",
+            "version": "2.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phar-io/manifest.git",
-                "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+                "reference": "54750ef60c58e43759730615a392c31c80e23176"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
-                "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+                "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+                "reference": "54750ef60c58e43759730615a392c31c80e23176",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
+                "ext-libxml": "*",
                 "ext-phar": "*",
                 "ext-xmlwriter": "*",
                 "phar-io/version": "^3.0.1",
@@ -7082,9 +7083,15 @@
             "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
             "support": {
                 "issues": "https://github.com/phar-io/manifest/issues",
-                "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+                "source": "https://github.com/phar-io/manifest/tree/2.0.4"
             },
-            "time": "2021-07-20T11:28:43+00:00"
+            "funding": [
+                {
+                    "url": "https://github.com/theseer",
+                    "type": "github"
+                }
+            ],
+            "time": "2024-03-03T12:33:53+00:00"
         },
         {
             "name": "phar-io/version",
@@ -9682,16 +9689,16 @@
         },
         {
             "name": "theseer/tokenizer",
-            "version": "1.2.2",
+            "version": "1.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/theseer/tokenizer.git",
-                "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
+                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
-                "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+                "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
                 "shasum": ""
             },
             "require": {
@@ -9720,7 +9727,7 @@
             "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
             "support": {
                 "issues": "https://github.com/theseer/tokenizer/issues",
-                "source": "https://github.com/theseer/tokenizer/tree/1.2.2"
+                "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
             },
             "funding": [
                 {
@@ -9728,7 +9735,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-11-20T00:12:19+00:00"
+            "time": "2024-03-03T12:36:25+00:00"
         }
     ],
     "aliases": [],

+ 2 - 1
db/migrations/2023020100-init.php

@@ -161,7 +161,8 @@ return new class() implements MigrationInterface {
                 `bandwidthlimit_resetday` tinyint(2) unsigned NOT NULL DEFAULT 0 COMMENT '流量重置日',
                 `node_heartbeat` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '节点心跳',
                 `online_user` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '节点在线用户',
-                `node_ip` varchar(255) NOT NULL DEFAULT '' COMMENT '节点IP',
+                `ipv4` INET4 NOT NULL DEFAULT '127.0.0.1' COMMENT 'IPv4地址',
+                `ipv6` INET6 NOT NULL DEFAULT '::1' COMMENT 'IPv6地址',
                 `node_group` smallint(5) unsigned NOT NULL DEFAULT 0 COMMENT '节点群组',
                 `online` tinyint(1) NOT NULL DEFAULT 1 COMMENT '在线状态',
                 `gfw_block` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '是否被GFW封锁',

+ 0 - 1
db/migrations/2023061800-update_new_shop_data_type.php

@@ -80,7 +80,6 @@ return new class() implements MigrationInterface {
         ALTER TABLE node MODIFY COLUMN `bandwidthlimit_resetday` tinyint(2) unsigned NOT NULL DEFAULT 0 COMMENT '流量重置日';
         ALTER TABLE node MODIFY COLUMN `node_heartbeat` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '节点心跳';
         ALTER TABLE node MODIFY COLUMN `online_user` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '节点在线用户';
-        ALTER TABLE node MODIFY COLUMN `node_ip` varchar(255) NOT NULL DEFAULT '' COMMENT '节点IP';
         ALTER TABLE node MODIFY COLUMN `node_group` smallint(5) unsigned NOT NULL DEFAULT 0 COMMENT '节点群组';
         ALTER TABLE node MODIFY COLUMN `online` tinyint(1) NOT NULL DEFAULT 1 COMMENT '在线状态';
         ALTER TABLE node MODIFY COLUMN `gfw_block` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '是否被GFW封锁';

+ 30 - 0
db/migrations/2024030300-update_node_ip.php

@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+use App\Interfaces\MigrationInterface;
+use App\Services\DB;
+
+return new class() implements MigrationInterface {
+    public function up(): int
+    {
+        DB::getPdo()->exec("
+            ALTER TABLE node ADD COLUMN IF NOT EXISTS `ipv4` INET4 NOT NULL DEFAULT '127.0.0.1' COMMENT 'IPv4地址';
+            ALTER TABLE node ADD COLUMN IF NOT EXISTS `ipv6` INET6 NOT NULL DEFAULT '::1' COMMENT 'IPv6地址';
+            ALTER TABLE node DROP COLUMN IF EXISTS `node_ip`;
+        ");
+
+        return 2024030300;
+    }
+
+    public function down(): int
+    {
+        DB::getPdo()->exec("
+            ALTER TABLE node ADD COLUMN IF NOT EXISTS `node_ip` varchar(255) NOT NULL DEFAULT '' COMMENT '节点IP';
+            ALTER TABLE node DROP COLUMN IF EXISTS `ipv4`;
+            ALTER TABLE node DROP COLUMN IF EXISTS `ipv6`;
+        ");
+
+        return 2024021900;
+    }
+};

+ 8 - 2
resources/views/tabler/admin/node/edit.tpl

@@ -48,9 +48,15 @@
                                 </div>
                             </div>
                             <div class="form-group mb-3 row">
-                                <label class="form-label col-3 col-form-label">服务器IP</label>
+                                <label class="form-label col-3 col-form-label">IPv4地址</label>
                                 <div class="col">
-                                    <input id="node_ip" type="text" class="form-control" value="{$node->node_ip}" disabled>
+                                    <input type="text" class="form-control" value="{$node->ipv4}" disabled>
+                                </div>
+                            </div>
+                            <div class="form-group mb-3 row">
+                                <label class="form-label col-3 col-form-label">IPv6地址</label>
+                                <div class="col">
+                                    <input type="text" class="form-control" value="{$node->ipv6}" disabled>
                                 </div>
                             </div>
                             <div class="form-group mb-3 row">

+ 3 - 1
src/Middleware/NodeToken.php

@@ -55,7 +55,9 @@ final class NodeToken implements MiddlewareInterface
         if ($_ENV['checkNodeIp']) {
             $ip = $request->getServerParam('REMOTE_ADDR');
 
-            if ($ip !== '127.0.0.1' && ! (new Node())->where('node_ip', $ip)->exists()) {
+            if ($ip !== '127.0.0.1' && $ip !== '::1' && $ip !== '0:0:0:0:0:0:0:1' &&
+                ! (new Node())->where('ipv4', $ip)->orWhere('ipv6', $ip)->exists()
+            ) {
                 return AppFactory::determineResponseFactory()->createResponse(401)->withJson([
                     'ret' => 0,
                     'msg' => 'Invalid request IP.',

+ 13 - 6
src/Models/Node.php

@@ -30,7 +30,8 @@ use const DNS_AAAA;
  * @property int    $bandwidthlimit_resetday 流量重置日
  * @property int    $node_heartbeat          节点心跳
  * @property int    $online_user             节点在线用户
- * @property string $node_ip                 节点IP
+ * @property string $ipv4                    IPv4地址
+ * @property string $ipv6                    IPv6地址
  * @property int    $node_group              节点群组
  * @property int    $online                  在线状态
  * @property int    $gfw_block               是否被GFW封锁
@@ -100,7 +101,7 @@ final class Node extends Model
     /**
      * 获取节点在线状态
      *
-     * @return int 0 = new node OR -1 = offline OR 1 = online
+     * @return int 0 = new node, -1 = offline, 1 = online
      */
     public function getNodeOnlineStatus(): int
     {
@@ -112,14 +113,20 @@ final class Node extends Model
      */
     public function updateNodeIp(): void
     {
-        if (Tools::isIPv4($this->server) || Tools::isIPv6($this->server)) {
-            $this->node_ip = $this->server;
+        if (Tools::isIPv4($this->server)) {
+            $this->ipv4 = $this->server;
+            $this->ipv6 = '::1';
+        } elseif (Tools::isIPv6($this->server)) {
+            $this->ipv4 = '127.0.0.1';
+            $this->ipv6 = $this->server;
         } else {
             try {
                 $result = dns_get_record($this->server, DNS_A + DNS_AAAA);
-                $this->node_ip = $result[0]['ip'] ?? $result[0]['ipv6'] ?? $this->server;
+                $this->ipv4 = $result[0]['ip'] ?? '127.0.0.1';
+                $this->ipv6 = $result[1]['ipv6'] ?? '::1';
             } catch (Exception $e) {
-                $this->node_ip = $this->server;
+                $this->ipv4 = '127.0.0.1';
+                $this->ipv6 = '::1';
             }
         }
     }

+ 3 - 3
src/Services/Auth/Cookie.php

@@ -54,10 +54,10 @@ final class Cookie extends Base
         }
 
         if ($_ENV['enable_login_bind_ip']) {
-            $remote_ip = $_SERVER['REMOTE_ADDR'];
-            $node = (new Node())->where('node_ip', $remote_ip)->first();
+            $ip = $_SERVER['REMOTE_ADDR'];
+            $node = (new Node())->where('ipv4', $ip)->orWhere('ipv6', $ip)->first();
 
-            if ($node === null && $ipHash !== Hash::ipHash($remote_ip, $uid, $expire_in)) {
+            if ($node === null && $ipHash !== Hash::ipHash($ip, $uid, $expire_in)) {
                 return $user;
             }
         }

+ 3 - 2
src/Services/Detect.php

@@ -29,12 +29,13 @@ final class Detect
      */
     public static function gfw(): void
     {
-        $nodes = (new Node())->where('type', 1)->where('node_ip', '!=', '')->where('online', 1)->get();
+        $nodes = (new Node())->where('type', 1)
+            ->where('ipv4', '!=', '127.0.0.1')->where('online', 1)->get();
 
         foreach ($nodes as $node) {
             $api_url = str_replace(
                 ['{ip}', '{port}'],
-                [$node->node_ip, $_ENV['detect_gfw_port']],
+                [$node->ipv4, $_ENV['detect_gfw_port']],
                 $_ENV['detect_gfw_url']
             );