Skip to content

Commit

Permalink
feat: 补全SingBox订阅下发
Browse files Browse the repository at this point in the history
  • Loading branch information
gua committed Nov 16, 2023
1 parent 77e5880 commit 36830db
Showing 1 changed file with 203 additions and 60 deletions.
263 changes: 203 additions & 60 deletions app/Protocols/SingBox.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<?php
namespace App\Protocols;

use App\Models\ServerHysteria;
use App\Models\User;
use App\Utils\Helper;

class SingBox
{
Expand All @@ -23,7 +22,8 @@ public function handle()
$outbounds = $this->buildOutbounds();
$config['outbounds'] = $outbounds;

return response($config, 200);
return json_encode($config);
//return response($config, 200);
}

protected function loadConfig()
Expand Down Expand Up @@ -55,17 +55,35 @@ protected function buildOutbounds()
$outbounds[] = &$selector;

foreach ($this->servers as $item) {
if ($item['type'] === 'shadowsocks') {
$ssConfig = $this->buildShadowsocks($this->user['uuid'], $item);
$outbounds[] = $ssConfig;
$selector['outbounds'][] = $item['name'];
$urltest['outbounds'][] = $item['name'];
}
if ($item['type'] === 'trojan') {
$trojanConfig = $this->buildTrojan($this->user['uuid'], $item);
$outbounds[] = $trojanConfig;
$selector['outbounds'][] = $item['name'];
$urltest['outbounds'][] = $item['name'];
}
if ($item['type'] === 'vmess') {
$vmessConfig = $this->buildVmess($this->user['uuid'], $item);
$outbounds[] = $vmessConfig;
$selector['outbounds'][] = $item['name'];
$urltest['outbounds'][] = $item['name'];
}
if ($item['type'] === 'vless') {
$vlessConfig = $this->buildVless($this->user['uuid'], $item);
$outbounds[] = $vlessConfig;
$selector['outbounds'][] = $item['name'];
$urltest['outbounds'][] = $item['name'];
} elseif ($item['type'] === 'hysteria') {
}
if ($item['type'] === 'hysteria') {
$hysteriaConfig = $this->buildHysteria($this->user['uuid'], $item, $this->user);
$outbounds[] = $hysteriaConfig;
$tag = $item['version'] == 2 ? "Hy2" : "Hy";
$selector['outbounds'][] = "[$tag]{$item['name']}";
$urltest['outbounds'][] = "[$tag]{$item['name']}";
$selector['outbounds'][] = $item['name'];
$urltest['outbounds'][] = $item['name'];
}
}

Expand All @@ -77,94 +95,219 @@ protected function buildOutbounds()
return $outbounds;
}

/**
* Vless订阅
*/
protected function buildShadowsocks($password, $server)
{
if ($server['cipher'] === '2022-blake3-aes-128-gcm') {
$serverKey = Helper::getServerKey($server['created_at'], 16);
$userKey = Helper::uuidToBase64($password, 16);
$password = "{$serverKey}:{$userKey}";
}
if ($server['cipher'] === '2022-blake3-aes-256-gcm') {
$serverKey = Helper::getServerKey($server['created_at'], 32);
$userKey = Helper::uuidToBase64($password, 32);
$password = "{$serverKey}:{$userKey}";
}
$array = [];
$array['tag'] = $server['name'];
$array['type'] = 'shadowsocks';
$array['server'] = $server['host'];
$array['server_port'] = $server['port'];
$array['method'] = $server['cipher'];
$array['password'] = $password;

protected function buildVless($password, $server)
return $array;
}


protected function buildVmess($uuid, $server)
{
$tlsSettings = $server['tls_settings'] ?? [];
$tlsConfig = [];
$array = [];
$array['tag'] = $server['name'];
$array['type'] = 'vmess';
$array['server'] = $server['host'];
$array['server_port'] = $server['port'];
$array['uuid'] = $uuid;
$array['security'] = 'auto';
$array['alter_id'] = 0;
$array['transport']= [];

if ($server['tls']) {
$tlsConfig = [];
$tlsConfig['enabled'] = true;

switch ($server['tls']) {
case 1:
$tlsConfig['insecure'] = (bool) ($tlsSettings['allowInsecure'] ?? false);
$tlsConfig['server_name'] = $tlsSettings['serverName'] ?? null;
break;

case 2:
$tlsConfig['insecure'] = (bool) ($tlsSettings['allowInsecure'] ?? false);
$tlsConfig['server_name'] = $tlsSettings['server_name'] ?? null;

if (
isset($tlsSettings['public_key'], $tlsSettings['short_id']) &&
!empty($tlsSettings['server_name'])
) {
$tlsConfig['reality'] = [
'enabled' => true,
'public_key' => $tlsSettings['public_key'],
'short_id' => $tlsSettings['short_id']
];

$fingerprints = ['chrome', 'firefox', 'safari', 'ios', 'edge', 'qq'];
$tlsConfig['utls'] = [
"enabled" => true,
"fingerprint" => $fingerprints[array_rand($fingerprints)]
];
}
break;
if ($server['tlsSettings']) {
$tlsSettings = $server['tlsSettings'] ?? [];
$tlsConfig['insecure'] = $tlsSettings['allowInsecure'] ? true : false;
$tlsConfig['server_name'] = $tlsSettings['serverName'] ?? null;
}
$array['tls'] = $tlsConfig;
}
if ($server['network'] === 'tcp') {
$tcpSettings = $server['networkSettings'];
if (isset($tcpSettings['header']['type']) && $tcpSettings['header']['type'] == 'http') $array['transport']['type'] = $tcpSettings['header']['type'];
if (isset($tcpSettings['header']['request']['path'])) $array['transport']['path'] = $tcpSettings['header']['request']['path'];
}
if ($server['network'] === 'ws') {
$array['transport']['type'] ='ws';
if ($server['networkSettings']) {
$wsSettings = $server['networkSettings'];
if (isset($wsSettings['path']) && !empty($wsSettings['path'])) $array['transport']['path'] = $wsSettings['path'];
if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) $array['transport']['headers'] = ['Host' => array($wsSettings['headers']['Host'])];
$array['transport']['max_early_data'] = 2048;
$array['transport']['early_data_header_name'] = 'Sec-WebSocket-Protocol';
}
}
if ($server['network'] === 'grpc') {
$array['transport']['type'] ='grpc';
if ($server['networkSettings']) {
$grpcSettings = $server['networkSettings'];
if (isset($grpcSettings['serviceName'])) $array['transport']['service_name'] = $grpcSettings['serviceName'];
}
}

return [
return $array;
}

protected function buildVless($password, $server)
{
$array = [
"type" => "vless",
"tag" => $server['name'],
"server" => $server['host'],
"server_port" => $server['port'],
"uuid" => $password,
"flow" => $server['flow'],
"packet_encoding" => "xudp",
"tls" => $tlsConfig
"packet_encoding" => "xudp"
];

$tlsSettings = $server['tls_settings'] ?? [];

if ($server['tls']) {
$tlsConfig = [];
$tlsConfig['enabled'] = true;
$array['flow'] = !empty($server['flow']) ? $server['flow'] : "";
$tlsSettings = $server['tls_settings'] ?? [];
if ($server['tls_settings']) {
$tlsConfig['insecure'] = isset($tlsSettings['allow_insecure']) && $tlsSettings['allow_insecure'] == 1 ? true : false;
$tlsConfig['server_name'] = $tlsSettings['server_name'] ?? null;
if ($server['tls'] == 2) {
$tlsConfig['reality'] = [
'enabled' => true,
'public_key' => $tlsSettings['public_key'],
'short_id' => $tlsSettings['short_id']
];
}
$fingerprints = ['chrome', 'firefox', 'safari', 'ios', 'edge', 'qq'];
$tlsConfig['utls'] = [
"enabled" => true,
"fingerprint" => $fingerprints[array_rand($fingerprints)]
];
}
$array['tls'] = $tlsConfig;
}

if ($server['network'] === 'tcp') {
$tcpSettings = $server['network_settings'];
if (isset($tcpSettings['header']['type']) && $tcpSettings['header']['type'] == 'http') $array['transport']['type'] = $tcpSettings['header']['type'];
if (isset($tcpSettings['header']['request']['path'])) $array['transport']['path'] = $tcpSettings['header']['request']['path'];
}
if ($server['network'] === 'ws') {
$array['transport']['type'] ='ws';
if ($server['network_settings']) {
$wsSettings = $server['network_settings'];
if (isset($wsSettings['path']) && !empty($wsSettings['path'])) $array['transport']['path'] = $wsSettings['path'];
if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) $array['transport']['headers'] = ['Host' => array($wsSettings['headers']['Host'])];
$array['transport']['max_early_data'] = 2048;
$array['transport']['early_data_header_name'] = 'Sec-WebSocket-Protocol';
}
}
if ($server['network'] === 'grpc') {
$array['transport']['type'] ='grpc';
if ($server['network_settings']) {
$grpcSettings = $server['network_settings'];
if (isset($grpcSettings['serviceName'])) $array['transport']['service_name'] = $grpcSettings['serviceName'];
}
}
if ($server['network'] === 'h2') {
$array['transport']['type'] = 'http';
if ($server['network_settings']) {
$h2Settings = $server['network_settings'];
if (isset($h2Settings['host'])) $array['transport']['host'] = array($h2Settings['host']);
if (isset($h2Settings['path'])) $array['transport']['path'] = $h2Settings['path'];
}
}

return $array;
}

protected function buildTrojan($password, $server)
{
$array = [];
$array['tag'] = $server['name'];
$array['type'] = 'trojan';
$array['server'] = $server['host'];
$array['server_port'] = $server['port'];
$array['password'] = $password;

$array['tls'] = [
'enabled' => true,
'insecure' => $server['allow_insecure'] ? true : false,
'server_name' => $server['server_name']
];

if(isset($server['network']) && in_array($server['network'], ["grpc", "ws"])){
$array['transport']['type'] = $server['network'];
// grpc配置
if($server['network'] === "grpc" && isset($server['network_settings']['serviceName'])) {
$array['transport']['service_name'] = $server['network_settings']['serviceName'];
}
// ws配置
if($server['network'] === "ws") {
if(isset($server['network_settings']['path'])) {
$array['transport']['path'] = $server['network_settings']['path'];
}
if(isset($server['network_settings']['headers']['Host'])){
$array['transport']['headers'] = ['Host' => array($server['network_settings']['headers']['Host'])];
}
$array['transport']['max_early_data'] = 2048;
$array['transport']['early_data_header_name'] = 'Sec-WebSocket-Protocol';
}
};

return $array;
}

protected function buildHysteria($password, $server, $user)
{
$array = [
'server' => $server['host'],
'server_port' => $server['port'],
'up_mbps' => $user->speed_limit ? min($server['up_mbps'], $user->speed_limit) : $server['up_mbps'],
'down_mbps' => $user->speed_limit ? min($server['down_mbps'], $user->speed_limit) : $server['down_mbps'],
"tls" => [
"enabled" => true,
'tls' => [
'enabled' => true,
'insecure' => $server['insecure'] ? true : false,
"server_name" => $server['server_name']
'server_name' => $server['server_name']
]
];

if ($server['version'] == 1) {
if (is_null($server['version']) || $server['version'] == 1) {
$array['auth_str'] = $password;
$array['tag'] = "[Hy]" . $server['name'];
$array['tag'] = $server['name'];
$array['type'] = 'hysteria';

if ($server['is_obfs']) {
$array['obfs'] = $server['server_key'];
$array['up_mbps'] = $user->speed_limit ? min($server['down_mbps'], $user->speed_limit) : $server['down_mbps'];
$array['down_mbps'] = $user->speed_limit ? min($server['up_mbps'], $user->speed_limit) : $server['up_mbps'];
if (isset($server['obfs']) && isset($server['obfs_password'])) {
$array['obfs'] = $server['obfs_password'];
}

$array['disable_mtu_discovery'] = true;
$array['tls']['alpn'] = [ServerHysteria::$alpnMap[$server['alpn']]];

} elseif ($server['version'] == 2) {
$array['password'] = $password;
$array['tag'] = "[Hy2]" . $server['name'];
$array['tag'] = $server['name'];
$array['type'] = 'hysteria2';
$array['password'] = $password;

if ($server['is_obfs']) {
$array['obfs']['type'] = 'salamander';
$array['obfs']['password'] = $server['server_key'];
if (isset($server['obfs'])) {
$array['obfs']['type'] = $server['obfs'];
$array['obfs']['password'] = $server['obfs_password'];
}
}

Expand Down

0 comments on commit 36830db

Please sign in to comment.