feat: Refactor uTLS & Multiplex Support, Node Status Push Optimization

- Server/ServerSave/Server.php: Unified utls and multiplex schema, validation, and defaults for vmess/vless/trojan/mieru protocols, enabling more flexible protocol configuration.
- Protocols (SingBox/ClashMeta/Shadowrocket/Stash/General): All protocol generators now support utls (client-fingerprint/fp) and multiplex options. Removed getRandFingerprint, replaced with getTlsFingerprint supporting random/custom fingerprints.
- Helper.php: Refactored TLS fingerprint utility to support object/string/random input.
- ServerService: Abstracted updateMetrics method to unify HTTP/WS node status caching logic.
- NodeWebSocketServer: Improved node connection, status push, and full sync logic; adjusted log levels; clarified push logic.
- ServerController: Reused ServerService for node metrics handling, reducing code duplication.
- Docs: Improved aapanel installation docs, added fix for empty admin dashboard.
This commit is contained in:
xboard
2026-03-16 23:09:56 +08:00
parent 65363ea918
commit b55091a066
14 changed files with 352 additions and 116 deletions
+45 -27
View File
@@ -3,7 +3,6 @@ namespace App\Protocols;
use App\Utils\Helper;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use App\Support\AbstractProtocol;
use App\Models\Server;
@@ -20,7 +19,6 @@ class SingBox extends AbstractProtocol
Server::TYPE_ANYTLS,
Server::TYPE_SOCKS,
Server::TYPE_HTTP,
Server::TYPE_MIERU,
];
private $config;
const CUSTOM_TEMPLATE_FILE = 'resources/rules/custom.sing-box.json';
@@ -55,9 +53,6 @@ class SingBox extends AbstractProtocol
'juicity' => [
'base_version' => '1.7.0'
],
'shadowtls' => [
'base_version' => '1.6.0'
],
'wireguard' => [
'base_version' => '1.5.0'
],
@@ -292,11 +287,16 @@ class SingBox extends AbstractProtocol
'enabled' => true,
'insecure' => (bool) data_get($protocol_settings, 'tls_settings.allow_insecure'),
];
$this->appendUtls($array['tls'], $protocol_settings);
if ($serverName = data_get($protocol_settings, 'tls_settings.server_name')) {
$array['tls']['server_name'] = $serverName;
}
}
$this->appendMultiplex($array, $protocol_settings);
$transport = match ($protocol_settings['network']) {
'tcp' => data_get($protocol_settings, 'network_settings.header.type', 'none') !== 'none' ? [
'type' => 'http',
@@ -354,12 +354,10 @@ class SingBox extends AbstractProtocol
$tlsConfig = [
'enabled' => true,
'insecure' => (bool) data_get($protocol_settings, 'tls_settings.allow_insecure'),
'utls' => [
'enabled' => true,
'fingerprint' => Helper::getRandFingerprint()
]
];
$this->appendUtls($tlsConfig, $protocol_settings);
switch ($protocol_settings['tls']) {
case 1:
if ($serverName = data_get($protocol_settings, 'tls_settings.server_name')) {
@@ -379,6 +377,8 @@ class SingBox extends AbstractProtocol
$array['tls'] = $tlsConfig;
}
$this->appendMultiplex($array, $protocol_settings);
$transport = match ($protocol_settings['network']) {
'tcp' => data_get($protocol_settings, 'network_settings.header.type') == 'http' ? [
'type' => 'http',
@@ -433,9 +433,15 @@ class SingBox extends AbstractProtocol
'insecure' => (bool) data_get($protocol_settings, 'allow_insecure', false),
]
];
$this->appendUtls($array['tls'], $protocol_settings);
if ($serverName = data_get($protocol_settings, 'server_name')) {
$array['tls']['server_name'] = $serverName;
}
$this->appendMultiplex($array, $protocol_settings);
$transport = match (data_get($protocol_settings, 'network')) {
'grpc' => [
'type' => 'grpc',
@@ -619,27 +625,39 @@ class SingBox extends AbstractProtocol
return $array;
}
protected function buildMieru($password, $server): array
protected function appendMultiplex(&$array, $protocol_settings)
{
$protocol_settings = data_get($server, 'protocol_settings', []);
$array = [
'type' => 'mieru',
'tag' => $server['name'],
'server' => $server['host'],
'server_port' => $server['port'],
'username' => $password,
'password' => $password,
'transport' => strtolower(data_get($protocol_settings, 'transport', 'tcp')),
];
if (isset($server['ports'])) {
$array['server_port_range'] = [$server['ports']];
if ($multiplex = data_get($protocol_settings, 'multiplex')) {
if (data_get($multiplex, 'enabled')) {
$array['multiplex'] = [
'enabled' => true,
'protocol' => data_get($multiplex, 'protocol', 'yamux'),
'max_connections' => data_get($multiplex, 'max_connections'),
'min_streams' => data_get($multiplex, 'min_streams'),
'max_streams' => data_get($multiplex, 'max_streams'),
'padding' => (bool) data_get($multiplex, 'padding', false),
];
if (data_get($multiplex, 'brutal.enabled')) {
$array['multiplex']['brutal'] = [
'enabled' => true,
'up_mbps' => data_get($multiplex, 'brutal.up_mbps'),
'down_mbps' => data_get($multiplex, 'brutal.down_mbps'),
];
}
$array['multiplex'] = array_filter($array['multiplex'], fn($v) => !is_null($v));
}
}
}
if ($multiplexing = data_get($protocol_settings, 'multiplexing')) {
$array['multiplexing'] = $multiplexing;
protected function appendUtls(&$tlsConfig, $protocol_settings)
{
if ($utls = data_get($protocol_settings, 'utls')) {
if (data_get($utls, 'enabled')) {
$tlsConfig['utls'] = [
'enabled' => true,
'fingerprint' => Helper::getTlsFingerprint($utls)
];
}
}
return $array;
}
}