-
Notifications
You must be signed in to change notification settings - Fork 581
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add deepbwork、shadowsockstidalab、trojantidala api
- Loading branch information
xboard
committed
Jan 18, 2025
1 parent
1298a6f
commit cf57020
Showing
4 changed files
with
397 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers\V1\Server; | ||
|
||
use App\Exceptions\ApiException; | ||
use App\Http\Controllers\Controller; | ||
use App\Models\Server; | ||
use App\Models\ServerVmess; | ||
use App\Services\ServerService; | ||
use App\Services\UserService; | ||
use App\Utils\CacheKey; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Support\Facades\Cache; | ||
|
||
/* | ||
* V2ray Aurora | ||
* Github: https://github.com/tokumeikoi/aurora | ||
*/ | ||
class DeepbworkController extends Controller | ||
{ | ||
CONST V2RAY_CONFIG = '{"log":{"loglevel":"debug","access":"access.log","error":"error.log"},"api":{"services":["HandlerService","StatsService"],"tag":"api"},"dns":{},"stats":{},"inbounds":[{"port":443,"protocol":"vmess","settings":{"clients":[]},"sniffing":{"enabled":true,"destOverride":["http","tls"]},"streamSettings":{"network":"tcp"},"tag":"proxy"},{"listen":"127.0.0.1","port":23333,"protocol":"dokodemo-door","settings":{"address":"0.0.0.0"},"tag":"api"}],"outbounds":[{"protocol":"freedom","settings":{}},{"protocol":"blackhole","settings":{},"tag":"block"}],"routing":{"rules":[{"type":"field","inboundTag":"api","outboundTag":"api"}]},"policy":{"levels":{"0":{"handshake":4,"connIdle":300,"uplinkOnly":5,"downlinkOnly":30,"statsUserUplink":true,"statsUserDownlink":true}}}}'; | ||
|
||
// 后端获取用户 | ||
public function user(Request $request) | ||
{ | ||
ini_set('memory_limit', -1); | ||
$node = $request->input('node_info'); | ||
Cache::put(CacheKey::get('SERVER_VMESS_LAST_CHECK_AT', $node->id), time(), 3600); | ||
$users = ServerService::getAvailableUsers($node->group_ids); | ||
$result = []; | ||
foreach ($users as $user) { | ||
$user->v2ray_user = [ | ||
"uuid" => $user->uuid, | ||
"email" => sprintf("%[email protected]", $user->uuid), | ||
"alter_id" => 0, | ||
"level" => 0, | ||
]; | ||
unset($user->uuid); | ||
array_push($result, $user); | ||
} | ||
$eTag = sha1(json_encode($result)); | ||
if (strpos($request->header('If-None-Match'), $eTag) !== false ) { | ||
return response(null,304); | ||
} | ||
return response([ | ||
'msg' => 'ok', | ||
'data' => $result, | ||
])->header('ETag', "\"{$eTag}\""); | ||
} | ||
|
||
// 后端提交数据 | ||
public function submit(Request $request) | ||
{ | ||
$node = $request->input('node_info'); | ||
$data = json_decode(request()->getContent(), true); | ||
Cache::put(CacheKey::get('SERVER_VMESS_ONLINE_USER', $node->id), count($data), 3600); | ||
Cache::put(CacheKey::get('SERVER_VMESS_LAST_PUSH_AT', $node->id), time(), 3600); | ||
$userService = new UserService(); | ||
$formatData = []; | ||
|
||
foreach ($data as $item) { | ||
$formatData[$item['user_id']] = [$item['u'], $item['d']]; | ||
} | ||
$userService->trafficFetch($node->toArray(), 'vmess', $formatData); | ||
|
||
return response([ | ||
'ret' => 1, | ||
'msg' => 'ok' | ||
]); | ||
} | ||
|
||
// 后端获取配置 | ||
public function config(Request $request) | ||
{ | ||
$node = $request->input('node_info'); | ||
$request->validate([ | ||
'node_id' => 'required', | ||
'local_port' => 'required' | ||
],[ | ||
'node_id.required' => '节点ID不能为空', | ||
'local_port.required' => '本地端口不能为空' | ||
]); | ||
try { | ||
$json = $this->getV2RayConfig($node, $request->input('local_port')); | ||
} catch (\Exception $e) { | ||
\Log::error($e); | ||
throw new ApiException($e->getMessage()); | ||
} | ||
|
||
return(json_encode($json, JSON_UNESCAPED_UNICODE)); | ||
} | ||
|
||
private function getV2RayConfig($node , int $localPort) | ||
{ | ||
$json = json_decode(self::V2RAY_CONFIG); | ||
$json->log->loglevel = (int)admin_setting('server_log_enable') ? 'debug' : 'none'; | ||
$json->inbounds[1]->port = (int)$localPort; | ||
$json->inbounds[0]->port = (int)$node ->server_port; | ||
$json->inbounds[0]->streamSettings->network = $node->network; | ||
$this->setDns($node, $json); | ||
$this->setNetwork($node, $json); | ||
$this->setRule($node, $json); | ||
$this->setTls($node, $json); | ||
|
||
return $json; | ||
} | ||
|
||
private function setDns(Server $server, object $json) | ||
{ | ||
if ($server->dnsSettings) { | ||
$dns = $server->dnsSettings; | ||
if (isset($dns->servers)) { | ||
array_push($dns->servers, '1.1.1.1'); | ||
array_push($dns->servers, 'localhost'); | ||
} | ||
$json->dns = $dns; | ||
$json->outbounds[0]->settings->domainStrategy = 'UseIP'; | ||
} | ||
} | ||
|
||
private function setNetwork(Server $server, object $json) | ||
{ | ||
if ($server->networkSettings) { | ||
switch ($server->network) { | ||
case 'tcp': | ||
$json->inbounds[0]->streamSettings->tcpSettings = $server->networkSettings; | ||
break; | ||
case 'kcp': | ||
$json->inbounds[0]->streamSettings->kcpSettings = $server->networkSettings; | ||
break; | ||
case 'ws': | ||
$json->inbounds[0]->streamSettings->wsSettings = $server->networkSettings; | ||
break; | ||
case 'http': | ||
$json->inbounds[0]->streamSettings->httpSettings = $server->networkSettings; | ||
break; | ||
case 'domainsocket': | ||
$json->inbounds[0]->streamSettings->dsSettings = $server->networkSettings; | ||
break; | ||
case 'quic': | ||
$json->inbounds[0]->streamSettings->quicSettings = $server->networkSettings; | ||
break; | ||
case 'grpc': | ||
$json->inbounds[0]->streamSettings->grpcSettings = $server->networkSettings; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
private function setRule(Server $server, object $json) | ||
{ | ||
$domainRules = array_filter(explode(PHP_EOL, admin_setting('server_v2ray_domain'))); | ||
$protocolRules = array_filter(explode(PHP_EOL, admin_setting('server_v2ray_protocol'))); | ||
if ($server->ruleSettings) { | ||
$ruleSettings = $server->ruleSettings; | ||
// domain | ||
if (isset($ruleSettings->domain)) { | ||
$ruleSettings->domain = array_filter($ruleSettings->domain); | ||
if (!empty($ruleSettings->domain)) { | ||
$domainRules = array_merge($domainRules, $ruleSettings->domain); | ||
} | ||
} | ||
// protocol | ||
if (isset($ruleSettings->protocol)) { | ||
$ruleSettings->protocol = array_filter($ruleSettings->protocol); | ||
if (!empty($ruleSettings->protocol)) { | ||
$protocolRules = array_merge($protocolRules, $ruleSettings->protocol); | ||
} | ||
} | ||
} | ||
if (!empty($domainRules)) { | ||
$domainObj = new \StdClass(); | ||
$domainObj->type = 'field'; | ||
$domainObj->domain = $domainRules; | ||
$domainObj->outboundTag = 'block'; | ||
array_push($json->routing->rules, $domainObj); | ||
} | ||
if (!empty($protocolRules)) { | ||
$protocolObj = new \StdClass(); | ||
$protocolObj->type = 'field'; | ||
$protocolObj->protocol = $protocolRules; | ||
$protocolObj->outboundTag = 'block'; | ||
array_push($json->routing->rules, $protocolObj); | ||
} | ||
if (empty($domainRules) && empty($protocolRules)) { | ||
$json->inbounds[0]->sniffing->enabled = false; | ||
} | ||
} | ||
|
||
private function setTls(Server $server, object $json) | ||
{ | ||
if ((int)$server->tls) { | ||
$tlsSettings = $server->tlsSettings; | ||
$json->inbounds[0]->streamSettings->security = 'tls'; | ||
$tls = (object)[ | ||
'certificateFile' => '/root/.cert/server.crt', | ||
'keyFile' => '/root/.cert/server.key' | ||
]; | ||
$json->inbounds[0]->streamSettings->tlsSettings = new \StdClass(); | ||
if (isset($tlsSettings->serverName)) { | ||
$json->inbounds[0]->streamSettings->tlsSettings->serverName = (string)$tlsSettings->serverName; | ||
} | ||
if (isset($tlsSettings->allowInsecure)) { | ||
$json->inbounds[0]->streamSettings->tlsSettings->allowInsecure = (int)$tlsSettings->allowInsecure ? true : false; | ||
} | ||
$json->inbounds[0]->streamSettings->tlsSettings->certificates[0] = $tls; | ||
} | ||
} | ||
} |
65 changes: 65 additions & 0 deletions
65
app/Http/Controllers/V1/Server/ShadowsocksTidalabController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers\V1\Server; | ||
|
||
use App\Exceptions\ApiException; | ||
use App\Http\Controllers\Controller; | ||
use App\Models\ServerShadowsocks; | ||
use App\Services\ServerService; | ||
use App\Services\UserService; | ||
use App\Utils\CacheKey; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Support\Facades\Cache; | ||
|
||
/* | ||
* Tidal Lab Shadowsocks | ||
* Github: https://github.com/tokumeikoi/tidalab-ss | ||
*/ | ||
class ShadowsocksTidalabController extends Controller | ||
{ | ||
// 后端获取用户 | ||
public function user(Request $request) | ||
{ | ||
ini_set('memory_limit', -1); | ||
$server = $request->input('node_info'); | ||
Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_LAST_CHECK_AT', $server->id), time(), 3600); | ||
$users = ServerService::getAvailableUsers($server->group_id); | ||
$result = []; | ||
foreach ($users as $user) { | ||
array_push($result, [ | ||
'id' => $user->id, | ||
'port' => $server->server_port, | ||
'cipher' => $server->cipher, | ||
'secret' => $user->uuid | ||
]); | ||
} | ||
$eTag = sha1(json_encode($result)); | ||
if (strpos($request->header('If-None-Match'), $eTag) !== false ) { | ||
return response(null,304); | ||
} | ||
return response([ | ||
'data' => $result | ||
])->header('ETag', "\"{$eTag}\""); | ||
} | ||
|
||
// 后端提交数据 | ||
public function submit(Request $request) | ||
{ | ||
$server = $request->input('node_info'); | ||
$data = json_decode(request()->getContent(), true); | ||
Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_ONLINE_USER', $server->id), count($data), 3600); | ||
Cache::put(CacheKey::get('SERVER_SHADOWSOCKS_LAST_PUSH_AT', $server->id), time(), 3600); | ||
$userService = new UserService(); | ||
$formatData = []; | ||
|
||
foreach ($data as $item) { | ||
$formatData[$item['user_id']] = [$item['u'], $item['d']]; | ||
} | ||
$userService->trafficFetch($server->toArray(), 'shadowsocks', $formatData); | ||
|
||
return response([ | ||
'ret' => 1, | ||
'msg' => 'ok' | ||
]); | ||
} | ||
} |
108 changes: 108 additions & 0 deletions
108
app/Http/Controllers/V1/Server/TrojanTidalabController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
<?php | ||
|
||
namespace App\Http\Controllers\V1\Server; | ||
|
||
use App\Exceptions\ApiException; | ||
use App\Http\Controllers\Controller; | ||
use App\Models\ServerTrojan; | ||
use App\Services\ServerService; | ||
use App\Services\UserService; | ||
use App\Utils\CacheKey; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Support\Facades\Cache; | ||
|
||
/* | ||
* Tidal Lab Trojan | ||
* Github: https://github.com/tokumeikoi/tidalab-trojan | ||
*/ | ||
class TrojanTidalabController extends Controller | ||
{ | ||
const TROJAN_CONFIG = '{"run_type":"server","local_addr":"0.0.0.0","local_port":443,"remote_addr":"www.taobao.com","remote_port":80,"password":[],"ssl":{"cert":"server.crt","key":"server.key","sni":"domain.com"},"api":{"enabled":true,"api_addr":"127.0.0.1","api_port":10000}}'; | ||
|
||
// 后端获取用户 | ||
public function user(Request $request) | ||
{ | ||
ini_set('memory_limit', -1); | ||
$server = $request->input('node_info'); | ||
if ($server->type !== 'trojan') { | ||
return $this->fail([400, '节点不存在']); | ||
} | ||
Cache::put(CacheKey::get('SERVER_TROJAN_LAST_CHECK_AT', $server->id), time(), 3600); | ||
$users = ServerService::getAvailableUsers($server->group_id); | ||
$result = []; | ||
foreach ($users as $user) { | ||
$user->trojan_user = [ | ||
"password" => $user->uuid, | ||
]; | ||
unset($user->uuid); | ||
array_push($result, $user); | ||
} | ||
$eTag = sha1(json_encode($result)); | ||
if (strpos($request->header('If-None-Match'), $eTag) !== false) { | ||
return response(null, 304); | ||
} | ||
return response([ | ||
'msg' => 'ok', | ||
'data' => $result, | ||
])->header('ETag', "\"{$eTag}\""); | ||
} | ||
|
||
// 后端提交数据 | ||
public function submit(Request $request) | ||
{ | ||
$server = $request->input('node_info'); | ||
if ($server->type !== 'trojan') { | ||
return $this->fail([400, '节点不存在']); | ||
} | ||
$data = json_decode(request()->getContent(), true); | ||
Cache::put(CacheKey::get('SERVER_TROJAN_ONLINE_USER', $server->id), count($data), 3600); | ||
Cache::put(CacheKey::get('SERVER_TROJAN_LAST_PUSH_AT', $server->id), time(), 3600); | ||
$userService = new UserService(); | ||
$formatData = []; | ||
foreach ($data as $item) { | ||
$formatData[$item['user_id']] = [$item['u'], $item['d']]; | ||
} | ||
$userService->trafficFetch($server->toArray(), 'trojan', $formatData); | ||
|
||
return response([ | ||
'ret' => 1, | ||
'msg' => 'ok' | ||
]); | ||
} | ||
|
||
// 后端获取配置 | ||
public function config(Request $request) | ||
{ | ||
$server = $request->input('node_info'); | ||
if ($server->type !== 'trojan') { | ||
return $this->fail([400, '节点不存在']); | ||
} | ||
$request->validate([ | ||
'node_id' => 'required', | ||
'local_port' => 'required' | ||
], [ | ||
'node_id.required' => '节点ID不能为空', | ||
'local_port.required' => '本地端口不能为空' | ||
]); | ||
try { | ||
$json = $this->getTrojanConfig($request->input('node_id'), $request->input('local_port')); | ||
} catch (\Exception $e) { | ||
\Log::error($e); | ||
return $this->fail([500, '配置获取失败']); | ||
} | ||
|
||
return (json_encode($json, JSON_UNESCAPED_UNICODE)); | ||
} | ||
|
||
private function getTrojanConfig($server, int $localPort) | ||
{ | ||
$protocolSettings = $server->protocol_settings; | ||
$json = json_decode(self::TROJAN_CONFIG); | ||
$json->local_port = $server->server_port; | ||
$json->ssl->sni = data_get($protocolSettings, 'server_name', $server->host); | ||
$json->ssl->cert = "/root/.cert/server.crt"; | ||
$json->ssl->key = "/root/.cert/server.key"; | ||
$json->api->api_port = $localPort; | ||
return $json; | ||
} | ||
} |
Oops, something went wrong.