浏览代码

feat: uc singbox

M1Screw 2 年之前
父节点
当前提交
9773b4ce43

+ 45 - 45
composer.lock

@@ -123,16 +123,16 @@
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.281.3",
+            "version": "3.281.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "a3cfb20dbfb11117b7174b2594fc597745252e0c"
+                "reference": "53cb798ca9b0b817dd2584f9406ee84d0214e6fc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a3cfb20dbfb11117b7174b2594fc597745252e0c",
-                "reference": "a3cfb20dbfb11117b7174b2594fc597745252e0c",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/53cb798ca9b0b817dd2584f9406ee84d0214e6fc",
+                "reference": "53cb798ca9b0b817dd2584f9406ee84d0214e6fc",
                 "shasum": ""
             },
             "require": {
@@ -212,9 +212,9 @@
             "support": {
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.281.3"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.281.5"
             },
-            "time": "2023-09-08T18:06:26+00:00"
+            "time": "2023-09-12T18:13:00+00:00"
         },
         {
             "name": "bacon/bacon-qr-code",
@@ -1237,16 +1237,16 @@
         },
         {
             "name": "illuminate/collections",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/collections.git",
-                "reference": "f494398dbaaead9e5ff16a18002d11634e8358e6"
+                "reference": "72c3cc6d44416db499d2ad11b8b27ae22e60a661"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/collections/zipball/f494398dbaaead9e5ff16a18002d11634e8358e6",
-                "reference": "f494398dbaaead9e5ff16a18002d11634e8358e6",
+                "url": "https://api.github.com/repos/illuminate/collections/zipball/72c3cc6d44416db499d2ad11b8b27ae22e60a661",
+                "reference": "72c3cc6d44416db499d2ad11b8b27ae22e60a661",
                 "shasum": ""
             },
             "require": {
@@ -1288,11 +1288,11 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2023-08-11T14:48:51+00:00"
+            "time": "2023-09-07T14:13:46+00:00"
         },
         {
             "name": "illuminate/conditionable",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/conditionable.git",
@@ -1338,7 +1338,7 @@
         },
         {
             "name": "illuminate/container",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/container.git",
@@ -1389,16 +1389,16 @@
         },
         {
             "name": "illuminate/contracts",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/contracts.git",
-                "reference": "eb1a7e72e159136a832f2c0467de5570bdc208ae"
+                "reference": "6c39fba7b2311e28f5c6ac7d729e3d49a2a98406"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/contracts/zipball/eb1a7e72e159136a832f2c0467de5570bdc208ae",
-                "reference": "eb1a7e72e159136a832f2c0467de5570bdc208ae",
+                "url": "https://api.github.com/repos/illuminate/contracts/zipball/6c39fba7b2311e28f5c6ac7d729e3d49a2a98406",
+                "reference": "6c39fba7b2311e28f5c6ac7d729e3d49a2a98406",
                 "shasum": ""
             },
             "require": {
@@ -1433,11 +1433,11 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2023-07-26T21:27:34+00:00"
+            "time": "2023-09-05T19:07:46+00:00"
         },
         {
             "name": "illuminate/database",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/database.git",
@@ -1506,7 +1506,7 @@
         },
         {
             "name": "illuminate/macroable",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/macroable.git",
@@ -1552,7 +1552,7 @@
         },
         {
             "name": "illuminate/pagination",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/pagination.git",
@@ -1602,16 +1602,16 @@
         },
         {
             "name": "illuminate/support",
-            "version": "v10.22.0",
+            "version": "v10.23.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/support.git",
-                "reference": "7ff0d0d70a7b8275816398a88870e062a01ebb8b"
+                "reference": "2dbee8db3beaf6c1ffa07a1c6ca2b4d375d0d6b4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/support/zipball/7ff0d0d70a7b8275816398a88870e062a01ebb8b",
-                "reference": "7ff0d0d70a7b8275816398a88870e062a01ebb8b",
+                "url": "https://api.github.com/repos/illuminate/support/zipball/2dbee8db3beaf6c1ffa07a1c6ca2b4d375d0d6b4",
+                "reference": "2dbee8db3beaf6c1ffa07a1c6ca2b4d375d0d6b4",
                 "shasum": ""
             },
             "require": {
@@ -1669,7 +1669,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2023-09-04T15:58:19+00:00"
+            "time": "2023-09-11T14:03:23+00:00"
         },
         {
             "name": "irazasyed/telegram-bot-sdk",
@@ -4789,16 +4789,16 @@
         },
         {
             "name": "srmklive/paypal",
-            "version": "3.0.24",
+            "version": "3.0.25",
             "source": {
                 "type": "git",
                 "url": "https://github.com/srmklive/laravel-paypal.git",
-                "reference": "f9b3e6162f4b7ded0f53737101af5cf1ea9a02a2"
+                "reference": "3e151690f6d5e80f1d3ca6bb7957e2b0222f5768"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/srmklive/laravel-paypal/zipball/f9b3e6162f4b7ded0f53737101af5cf1ea9a02a2",
-                "reference": "f9b3e6162f4b7ded0f53737101af5cf1ea9a02a2",
+                "url": "https://api.github.com/repos/srmklive/laravel-paypal/zipball/3e151690f6d5e80f1d3ca6bb7957e2b0222f5768",
+                "reference": "3e151690f6d5e80f1d3ca6bb7957e2b0222f5768",
                 "shasum": ""
             },
             "require": {
@@ -4849,9 +4849,9 @@
             ],
             "support": {
                 "issues": "https://github.com/srmklive/laravel-paypal/issues",
-                "source": "https://github.com/srmklive/laravel-paypal/tree/3.0.24"
+                "source": "https://github.com/srmklive/laravel-paypal/tree/3.0.25"
             },
-            "time": "2023-09-06T22:26:06+00:00"
+            "time": "2023-09-12T21:52:40+00:00"
         },
         {
             "name": "starkbank/ecdsa",
@@ -7802,16 +7802,16 @@
         },
         {
             "name": "phpunit/php-code-coverage",
-            "version": "10.1.4",
+            "version": "10.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
-                "reference": "cd59bb34756a16ca8253ce9b2909039c227fff71"
+                "reference": "1df504e42a88044c27a90136910f0b3fe9e91939"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cd59bb34756a16ca8253ce9b2909039c227fff71",
-                "reference": "cd59bb34756a16ca8253ce9b2909039c227fff71",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1df504e42a88044c27a90136910f0b3fe9e91939",
+                "reference": "1df504e42a88044c27a90136910f0b3fe9e91939",
                 "shasum": ""
             },
             "require": {
@@ -7868,7 +7868,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
                 "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
-                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.4"
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.5"
             },
             "funding": [
                 {
@@ -7876,7 +7876,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-08-31T14:04:38+00:00"
+            "time": "2023-09-12T14:37:22+00:00"
         },
         {
             "name": "phpunit/php-file-iterator",
@@ -8123,16 +8123,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "10.3.3",
+            "version": "10.3.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "241ed4dd0db1c096984e62d414c4e1ac8d5dbff4"
+                "reference": "b8d59476f19115c9774b3b447f78131781c6c32b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/241ed4dd0db1c096984e62d414c4e1ac8d5dbff4",
-                "reference": "241ed4dd0db1c096984e62d414c4e1ac8d5dbff4",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b8d59476f19115c9774b3b447f78131781c6c32b",
+                "reference": "b8d59476f19115c9774b3b447f78131781c6c32b",
                 "shasum": ""
             },
             "require": {
@@ -8146,7 +8146,7 @@
                 "phar-io/manifest": "^2.0.3",
                 "phar-io/version": "^3.0.2",
                 "php": ">=8.1",
-                "phpunit/php-code-coverage": "^10.1.1",
+                "phpunit/php-code-coverage": "^10.1.5",
                 "phpunit/php-file-iterator": "^4.0",
                 "phpunit/php-invoker": "^4.0",
                 "phpunit/php-text-template": "^3.0",
@@ -8204,7 +8204,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.3"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.4"
             },
             "funding": [
                 {
@@ -8220,7 +8220,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-09-05T04:34:51+00:00"
+            "time": "2023-09-12T14:42:28+00:00"
         },
         {
             "name": "psr/cache",

+ 146 - 0
config/appprofile.example.php

@@ -2,6 +2,152 @@
 
 declare(strict_types=1);
 
+$_ENV['SingBox_Config'] = [
+    'log' => [
+        'level' => 'error',
+    ],
+    'dns' => [
+        'servers' => [
+            [
+                'tag' => 'cloudflare',
+                'address' => '1.1.1.1',
+            ],
+            [
+                'tag' => 'dnspod',
+                'address' => '119.29.29.29',
+                'detour' => 'direct',
+            ],
+        ],
+        'rules' => [
+            [
+                'outbound' => 'any',
+                'server' => 'dnspod',
+            ],
+            [
+                'clash_mode' => 'Direct',
+                'server' => 'dnspod',
+            ],
+            [
+                'clash_mode' => 'Global',
+                'server' => 'cloudflare',
+            ],
+            [
+                'type' => 'logical',
+                'mode' => 'and',
+                'rules' => [
+                    [
+                        'geosite' => 'google@cn',
+                        'invert' => true,
+                    ],
+                    [
+                        'geosite' => [
+                            'cn',
+                        ],
+                    ],
+                ],
+                'server' => 'dnspod',
+            ],
+        ],
+        'strategy' => 'prefer_ipv4',
+    ],
+    'inbounds' => [
+        [
+            "type" => "tun",
+            "inet4_address" => "172.19.0.1/30",
+            "auto_route" => true,
+            "strict_route" => true,
+            "endpoint_independent_nat" => true,
+            "udp_timeout" => 60,
+            "platform" => [
+                "http_proxy" => [
+                    "enabled" => true,
+                    "server" => "127.0.0.1",
+                    "server_port" => 8100,
+                ],
+            ],
+            "sniff" => true,
+        ],
+        [
+            'type' => 'mixed',
+            'listen' => '127.0.0.1',
+            'listen_port' => 8100,
+            'sniff' => true,
+            'domain_strategy' => 'prefer_ipv4',
+        ],
+    ],
+    'outbounds' => [
+        [
+            'type' => 'selector',
+            'tag' => 'default',
+            'outbounds' => [],
+        ],
+        [
+            'type' => 'direct',
+            'tag' => 'direct',
+        ],
+        [
+            'type' => 'block',
+            'tag' => 'block',
+        ],
+        [
+            'type' => 'dns',
+            'tag' => 'dns',
+        ],
+    ],
+    'route' => [
+        'rules' => [
+            [
+                'protocol' => 'dns',
+                'outbound' => 'dns',
+            ],
+            [
+                'network' => 'udp',
+                'port' => 53,
+                'outbound' => 'dns',
+            ],
+            [
+                'clash_mode' => 'Direct',
+                'outbound' => 'direct',
+            ],
+            [
+                'clash_mode' => 'Global',
+                'outbound' => 'default',
+            ],
+            [
+                'protocol' => 'stun',
+                'outbound' => 'block',
+            ],
+            [
+                'type' => 'logical',
+                'mode' => 'and',
+                'rules' => [
+                    [
+                        'geosite' => 'google@cn',
+                        'invert' => true,
+                    ],
+                    [
+                        'geosite' => [
+                            'cn',
+                        ],
+                        'geoip' => [
+                            'cn',
+                            'private',
+                        ],
+                    ],
+                ],
+                'outbound' => 'direct',
+            ],
+        ],
+        'auto_detect_interface' => true,
+    ],
+    'experimental' => [
+        'clash_api' => [
+            'store_mode' => true,
+            'cache_id' => '',
+        ],
+    ],
+];
+
 $_ENV['Clash_Config'] = [
     'port' => 7890,
     'socks-port' => 7891,

+ 7 - 0
resources/views/tabler/user/index.tpl

@@ -187,6 +187,9 @@
                                         <p>
                                             通用订阅(clash):<code>{$UniversalSub}/clash</code>
                                         </p>
+                                        <p>
+                                            通用订阅(sing-box):<code>{$UniversalSub}/singbox</code>
+                                        </p>
                                         {if $public_setting['enable_ss_sub']}
                                             <p>
                                                 通用订阅(sip008):<code>{$UniversalSub}/sip008</code>
@@ -201,6 +204,10 @@
                                                class="copy btn btn-primary">
                                                 复制通用订阅(clash)
                                             </a>
+                                            <a data-clipboard-text="{$UniversalSub}/singbox"
+                                               class="copy btn btn-primary">
+                                                复制通用订阅(sing-box)
+                                            </a>
                                             {if $public_setting['enable_ss_sub']}
                                                 <a data-clipboard-text="{$UniversalSub}/sip008"
                                                    class="copy btn btn-primary">

+ 1 - 1
src/Controllers/SubController.php

@@ -27,7 +27,7 @@ final class SubController extends BaseController
         $err_msg = '订阅链接无效';
 
         $subtype = $args['subtype'];
-        $subtype_list = ['json', 'clash', 'sip008'];
+        $subtype_list = ['json', 'clash', 'sip008', 'singbox'];
 
         if (! $_ENV['Subscribe'] ||
             ! in_array($subtype, $subtype_list) ||

+ 1 - 1
src/Models/Node.php

@@ -49,7 +49,7 @@ final class Node extends Model
     {
         return match ($this->sort) {
             0 => 'Shadowsocks',
-            1 => 'WireGuard',
+            1 => 'Shadowsocks2022',
             2 => 'TUIC',
             11 => 'V2Ray',
             14 => 'Trojan',

+ 0 - 12
src/Services/Config.php

@@ -61,13 +61,6 @@ final class Config
     public static function getSupportParam($type): array
     {
         return match ($type) {
-            'ss_aead_method' => [
-                'aes-128-gcm',
-                'aes-192-gcm',
-                'aes-256-gcm',
-                'chacha20-ietf-poly1305',
-                'xchacha20-ietf-poly1305',
-            ],
             'ss_obfs' => [
                 'simple_obfs_http',
                 'simple_obfs_http_compatible',
@@ -85,11 +78,6 @@ final class Config
                 'aes-256-gcm',
                 'chacha20-ietf-poly1305',
                 'xchacha20-ietf-poly1305',
-                'none',
-                'plain',
-                '2022-blake3-aes-128-gcm',
-                '2022-blake3-aes-256-gcm',
-                '2022-blake3-chacha20-poly1305',
             ],
         };
     }

+ 3 - 1
src/Services/Subscribe.php

@@ -6,6 +6,7 @@ namespace App\Services;
 
 use App\Services\Subscribe\Clash;
 use App\Services\Subscribe\Json;
+use App\Services\Subscribe\SingBox;
 use App\Services\Subscribe\SIP002;
 use App\Services\Subscribe\SIP008;
 use App\Services\Subscribe\SS;
@@ -14,7 +15,7 @@ use App\Services\Subscribe\V2Ray;
 
 final class Subscribe
 {
-    public static function getClient($type): SIP002|SIP008|Clash|SS|Trojan|Json|V2ray
+    public static function getClient($type): Json|SS|SIP002|V2Ray|Trojan|Clash|SIP008|SingBox
     {
         return match ($type) {
             'ss' => new SS(),
@@ -23,6 +24,7 @@ final class Subscribe
             'trojan' => new Trojan(),
             'clash' => new Clash(),
             'sip008' => new SIP008(),
+            'singbox' => new SingBox(),
             default => new Json(),
         };
     }

+ 140 - 0
src/Services/Subscribe/SingBox.php

@@ -0,0 +1,140 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Services\Subscribe;
+
+use App\Utils\Tools;
+use function array_filter;
+use function array_key_exists;
+use function array_merge;
+use function json_decode;
+use function json_encode;
+
+final class SingBox extends Base
+{
+    public function getContent($user): string
+    {
+        $nodes = [];
+        $singbox_config = $_ENV['SingBox_Config'];
+        $nodes_raw = Tools::getSubNodes($user);
+
+        foreach ($nodes_raw as $node_raw) {
+            $node_custom_config = json_decode($node_raw->custom_config, true);
+            //檢查是否配置“前端/订阅中下发的服务器地址”
+            if (! array_key_exists('server_user', $node_custom_config)) {
+                $server = $node_raw->server;
+            } else {
+                $server = $node_custom_config['server_user'];
+            }
+
+            switch ((int) $node_raw->sort) {
+                case 0:
+                    $plugin = $node_custom_config['plugin'] ?? '';
+                    $plugin_option = $node_custom_config['plugin_option'] ?? '';
+                    $network = ($node_custom_config['udp'] ?? '') === true ? '' : 'tcp';
+
+                    $node = [
+                        'type' => 'shadowsocks',
+                        'tag' => $node_raw->name,
+                        'server' => $server,
+                        'server_port' => (int) $user->port,
+                        'method' => $user->method,
+                        'password' => $user->passwd,
+                        'plugin' => $plugin,
+                        'plugin_opts' => $plugin_option,
+                        'network' => $network,
+                    ];
+
+                    break;
+                case 11:
+                    $v2_port = $node_custom_config['v2_port'] ?? ($node_custom_config['offset_port_user']
+                        ?? ($node_custom_config['offset_port_node'] ?? 443));
+                    $alter_id = $node_custom_config['alter_id'] ?? '0';
+                    $security = $node_custom_config['security'] ?? 'auto';
+                    $network = ($node_custom_config['udp'] ?? '') === true ? '' : 'tcp';
+                    $transport = $node_custom_config['network'] ?? '';
+                    $host = [];
+                    $host[] = $node_custom_config['header']['request']['headers']['Host'][0] ??
+                        $node_custom_config['host'] ?? '';
+                    $path = $node_custom_config['header']['request']['path'][0] ?? $node_custom_config['path'] ?? '';
+                    $headers = $node_custom_config['header']['request']['headers'] ?? [];
+                    $service_name = $node_custom_config['servicename'] ?? '';
+
+                    $node = [
+                        'type' => 'vmess',
+                        'tag' => $node_raw->name,
+                        'server' => $server,
+                        'server_port' => (int) $v2_port,
+                        'uuid' => $user->uuid,
+                        'security' => $security,
+                        'alter_id' => (int) $alter_id,
+                        'network' => $network,
+                        'transport' => [
+                            'type' => $transport,
+                            'host' => $host,
+                            'path' => $path,
+                            'headers' => $headers,
+                            'service_name' => $service_name,
+                        ],
+                    ];
+
+                    $node['transport'] = array_filter($node['transport']);
+
+                    break;
+                case 14:
+                    $trojan_port = $node_custom_config['trojan_port'] ?? ($node_custom_config['offset_port_user']
+                        ?? ($node_custom_config['offset_port_node'] ?? 443));
+                    $network = ($node_custom_config['udp'] ?? '') === true ? '' : 'tcp';
+                    $host = $node_custom_config['host'] ?? '';
+                    $insecure = $node_custom_config['allow_insecure'] ?? false;
+                    $transport = $node_custom_config['network']
+                        ?? (array_key_exists('grpc', $node_custom_config)
+                        && $node_custom_config['grpc'] === '1' ? 'grpc' : '');
+                    $path = $node_custom_config['header']['request']['path'][0] ?? $node_custom_config['path'] ?? '';
+                    $headers = $node_custom_config['header']['request']['headers'] ?? [];
+                    $service_name = $node_custom_config['servicename'] ?? '';
+
+                    $node = [
+                        'type' => 'trojan',
+                        'tag' => $node_raw->name,
+                        'server' => $server,
+                        'server_port' => (int) $trojan_port,
+                        'password' => $user->uuid,
+                        'network' => $network,
+                        'tls' => [
+                            'enabled' => true,
+                            'server_name' => $host,
+                            'insecure' => $insecure,
+                        ],
+                        'transport' => [
+                            'type' => $transport,
+                            'path' => $path,
+                            'headers' => $headers,
+                            'service_name' => $service_name,
+                        ],
+                    ];
+
+                    $node['tls'] = array_filter($node['tls']);
+                    $node['transport'] = array_filter($node['transport']);
+
+                    break;
+                default:
+                    $node = [];
+                    break;
+            }
+
+            if ($node === []) {
+                continue;
+            }
+
+            $nodes[] = $node;
+            $singbox_config['outbounds'][0]['outbounds'][] = $node_raw->name;
+        }
+
+        $singbox_config['outbounds'] = array_merge($singbox_config['outbounds'], $nodes);
+        $singbox_config['experimental']['clash_api']['cache_id'] = (string) $user->id;
+
+        return json_encode($singbox_config);
+    }
+}