From ec49ba3fd13527c3c34c1052abbcbf497dcac286 Mon Sep 17 00:00:00 2001 From: yootus <151767033+yootus@users.noreply.github.com> Date: Thu, 2 Apr 2026 15:47:41 +0800 Subject: [PATCH] =?UTF-8?q?Loon=E5=92=8CSurfboard=E9=80=82=E9=85=8Danytls?= =?UTF-8?q?=20(#854)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Loon适配anytls * Surfboard适配anytls Surfboard适配anytls --- app/Protocols/Loon.php | 29 +++++++++++++++++++++++++++++ app/Protocols/Surfboard.php | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/app/Protocols/Loon.php b/app/Protocols/Loon.php index 27c12b4..56df854 100644 --- a/app/Protocols/Loon.php +++ b/app/Protocols/Loon.php @@ -15,6 +15,7 @@ class Loon extends AbstractProtocol Server::TYPE_TROJAN, Server::TYPE_HYSTERIA, Server::TYPE_VLESS, + Server::TYPE_ANYTLS, ]; protected $protocolRequirements = [ @@ -47,6 +48,9 @@ class Loon extends AbstractProtocol if ($item['type'] === Server::TYPE_VLESS) { $uri .= self::buildVless($item['password'], $item); } + if ($item['type'] === Server::TYPE_ANYTLS) { + $uri .= self::buildAnyTLS($item['password'], $item); + } } return response($uri) ->header('content-type', 'text/plain') @@ -325,4 +329,29 @@ class Loon extends AbstractProtocol $uri .= "\r\n"; return $uri; } + + public static function buildAnyTLS($password, $server) + { + $protocol_settings = data_get($server, 'protocol_settings', []); + + $config = [ + "{$server['name']}=anytls", + "{$server['host']}", + "{$server['port']}", + "{$password}", + "udp=true" + ]; + + if ($serverName = data_get($protocol_settings, 'tls.server_name')) { + $config[] = "sni={$serverName}"; + } + // ✅ 跳过证书校验 + if (data_get($protocol_settings, 'tls.allow_insecure')) { + $config[] = 'skip-cert-verify=true'; + } + + $config = array_filter($config); + + return implode(',', $config) . "\r\n"; + } } diff --git a/app/Protocols/Surfboard.php b/app/Protocols/Surfboard.php index f514538..23fcf09 100644 --- a/app/Protocols/Surfboard.php +++ b/app/Protocols/Surfboard.php @@ -14,6 +14,7 @@ class Surfboard extends AbstractProtocol Server::TYPE_SHADOWSOCKS, Server::TYPE_VMESS, Server::TYPE_TROJAN, + Server::TYPE_ANYTLS, ]; const CUSTOM_TEMPLATE_FILE = 'resources/rules/custom.surfboard.conf'; const DEFAULT_TEMPLATE_FILE = 'resources/rules/default.surfboard.conf'; @@ -59,6 +60,10 @@ class Surfboard extends AbstractProtocol // [Proxy Group] $proxyGroup .= $item['name'] . ', '; } + if ($item['type'] === Server::TYPE_ANYTLS) { + $proxies .= self::buildAnyTLS($item['password'], $item); + $proxyGroup .= $item['name'] . ', '; + } } $config = subscribe_template('surfboard'); @@ -193,4 +198,32 @@ class Surfboard extends AbstractProtocol $uri .= "\r\n"; return $uri; } + + public static function buildAnyTLS($password, $server) + { + $protocol_settings = data_get($server, 'protocol_settings', []); + + $config = [ + "{$server['name']}=anytls", + "{$server['host']}", + "{$server['port']}", + "password={$password}", + "tfo=true", + "udp-relay=true" + ]; + + // SNI + if ($serverName = data_get($protocol_settings, 'tls.server_name')) { + $config[] = "sni={$serverName}"; + } + + // 跳过证书校验 + if (data_get($protocol_settings, 'tls.allow_insecure')) { + $config[] = "skip-cert-verify=true"; + } + + $config = array_filter($config); + + return implode(',', $config) . "\r\n"; + } }