202 lines
7.9 KiB
PHP
202 lines
7.9 KiB
PHP
<?php
|
||
|
||
namespace App\Utils\Client\Protocols;
|
||
|
||
use Symfony\Component\Yaml\Yaml;
|
||
use App\Utils\Client\Protocol;
|
||
use Config;
|
||
use App\Utils\Helper;
|
||
|
||
class Mozilla extends Protocol
|
||
{
|
||
public $flag = 'mozilla';
|
||
|
||
public function handle()
|
||
{
|
||
$servers = $this->servers;
|
||
$user = $this->user;
|
||
header("userinfo: upload={$user['u']}; download={$user['d']}; total={$user['transfer_enable']}");
|
||
$defaultConfig = base_path() . '/resources/rules/default.mozilla.yaml';
|
||
if (\File::exists($defaultConfig) == false) {
|
||
$defaultConfig = base_path() . '/resources/rules/default.clash.yaml';
|
||
}
|
||
header("content-disposition:attachment;filename*=UTF-8''111");
|
||
$config = Yaml::parseFile($defaultConfig);
|
||
$proxy = [];
|
||
$proxies = [];
|
||
$proxiesOther = [];
|
||
|
||
foreach ($servers as $item) {
|
||
$isGroups = false;
|
||
if (!empty($item['tags'])) {
|
||
foreach ($item['tags'] as $tag) {
|
||
if (strpos($tag, 'node:') === 0) {
|
||
$group = substr($tag, 5);
|
||
if ($group !== '') {
|
||
$proxiesOther[$group][] = $item['name'];
|
||
if (strpos($item['name'], $group) !== false) {
|
||
$isGroups = true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
switch ($item['type']) {
|
||
case 'shadowsocks':
|
||
$proxy[] = self::buildShadowsocks($user['uuid'], $item);
|
||
break;
|
||
|
||
case 'v2ray':
|
||
$proxy[] = self::buildVmess($user['uuid'], $item);
|
||
break;
|
||
|
||
case 'trojan':
|
||
$proxy[] = self::buildTrojan($user['uuid'], $item);
|
||
break;
|
||
|
||
default:
|
||
continue 2;
|
||
}
|
||
|
||
if (!$isGroups) {
|
||
$proxies[] = $item['name'];
|
||
}
|
||
}
|
||
$proxiesOther0 = $config['proxy-groups'][0]['proxies'];
|
||
$config['proxy-groups'][0]['proxies']=array();
|
||
$config['proxies'] = array_merge($config['proxies'] ?: [], $proxy);
|
||
foreach ($config['proxy-groups'] as $k => $v) {
|
||
if (!is_array($config['proxy-groups'][$k]['proxies'])) {
|
||
continue;
|
||
}
|
||
if(array_key_exists($config['proxy-groups'][$k]['name'], $proxiesOther)){
|
||
$config['proxy-groups'][$k]['proxies'] = array_merge($config['proxy-groups'][$k]['proxies'], $proxiesOther[$config['proxy-groups'][$k]['name']]);
|
||
unset($proxiesOther[$config['proxy-groups'][$k]['name']]);
|
||
}else if($config['proxy-groups'][$k]['type'] !== 'select' || $config['proxy-groups'][$k]['name'] == 'manual_node'){
|
||
$config['proxy-groups'][$k]['proxies'] = array_merge($config['proxy-groups'][$k]['proxies'], $proxies);
|
||
}
|
||
}
|
||
|
||
|
||
foreach ($proxiesOther as $k => $v) {
|
||
$vo = ['name' => $k, 'type' => 'fallback','proxies' => $v,'url' => "http://www.gstatic.com/generate_204",'interval' => 600];
|
||
array_push($config['proxy-groups'], $vo);
|
||
array_push($proxiesOther0,$k);
|
||
}
|
||
$config['proxy-groups'][0]['proxies'] = array_merge($proxiesOther0,$config['proxy-groups'][0]['proxies']);
|
||
// Force the current subscription domain to be a direct rule
|
||
$subsDomain = $_SERVER['SERVER_NAME'];
|
||
$subsDomainRule = "DOMAIN,{$subsDomain},DIRECT";
|
||
array_unshift($config['rules'], $subsDomainRule);
|
||
$yaml = Yaml::dump($config);
|
||
// $json = json_encode($config, JSON_UNESCAPED_UNICODE);
|
||
// 初始化向量(IV)必须是唯一且随机的,对于每个加密操作都应该不同
|
||
$key="M8T74hb17KR183b6";
|
||
$iv = "242itTn000C480h1";
|
||
// 加密数据
|
||
$encrypted = openssl_encrypt($yaml, 'aes-128-cbc', $key, 0, $iv);
|
||
return $encrypted;
|
||
}
|
||
|
||
public static function buildShadowsocks($password, $server): array
|
||
{
|
||
$array = [];
|
||
$array['name'] = $server['name'];
|
||
$array['type'] = 'ss';
|
||
$array['server'] = $server['host'];
|
||
$array['port'] = $server['port'];
|
||
$array['cipher'] = $server['cipher'];
|
||
$array['password'] = $password;
|
||
$array['udp'] = true;
|
||
return $array;
|
||
}
|
||
|
||
public static function buildVmess($uuid, $server): array
|
||
{
|
||
$array = [];
|
||
$array['name'] = $server['name'];
|
||
$array['type'] = 'vless';
|
||
$array['server'] = $server['host'];
|
||
$array['port'] = $server['port'];
|
||
$array['uuid'] = $uuid;
|
||
$array['alterId'] = $server['alter_id'];
|
||
$array['cipher'] = 'auto';
|
||
$array['udp'] = true;
|
||
|
||
switch ($server['tls']) {
|
||
case 1:
|
||
$tlsSettings = $server['tls_settings'];
|
||
$array['tls'] = true;
|
||
if (isset($tlsSettings['allow_insecure']) && !empty($tlsSettings['allow_insecure'])) {
|
||
$array['skip-cert-verify'] = (bool)$tlsSettings['allow_insecure'];
|
||
}
|
||
if (isset($tlsSettings['server_name']) && !empty($tlsSettings['server_name'])) {
|
||
$array['servername'] = $tlsSettings['server_name'];
|
||
}
|
||
break;
|
||
case 2:
|
||
$array['flow'] = 'xtls-rprx-vision';
|
||
$tlsSettings = $server['tls_settings'];
|
||
$array['tls'] = true;
|
||
if (isset($tlsSettings['allow_insecure']) && !empty($tlsSettings['allow_insecure'])) {
|
||
$array['skip-cert-verify'] = (bool)$tlsSettings['allow_insecure'];
|
||
}
|
||
if (isset($tlsSettings['server_name']) && !empty($tlsSettings['server_name'])) {
|
||
$array['servername'] = $tlsSettings['server_name'];
|
||
}
|
||
$array['reality-opts'] = [
|
||
'public-key' => $tlsSettings['public_key'],
|
||
'short-id' => $tlsSettings['short_id']
|
||
];
|
||
$array['client-fingerprint'] = Helper::getRandFingerprint();
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
switch ($server['network']) {
|
||
case 'ws':
|
||
$array['network'] = 'ws';
|
||
if (isset($server['network_settings'])) {
|
||
$wsSettings = $server['network_settings'];
|
||
if (isset($wsSettings['path']) && !empty($wsSettings['path'])) {
|
||
$array['ws-path'] = $wsSettings['path'];
|
||
}
|
||
if (isset($wsSettings['headers']['Host']) && !empty($wsSettings['headers']['Host'])) {
|
||
$array['ws-headers'] = ['Host' => $wsSettings['headers']['Host']];
|
||
}
|
||
}
|
||
break;
|
||
case 'grpc':
|
||
$array['network'] = 'grpc';
|
||
if (isset($server['network_settings'])) {
|
||
$grpcObject = $server['network_settings'];
|
||
$array['grpc-opts'] = [];
|
||
$array['grpc-opts']['grpc-service-name'] = $grpcObject['serviceName'];
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
return $array;
|
||
}
|
||
|
||
public static function buildTrojan($password, $server): array
|
||
{
|
||
$array = [];
|
||
$array['name'] = $server['name'];
|
||
$array['type'] = 'trojan';
|
||
$array['server'] = $server['host'];
|
||
$array['port'] = $server['port'];
|
||
$array['password'] = $password;
|
||
$array['udp'] = true;
|
||
if (!empty($server['server_name'])) {
|
||
$array['sni'] = $server['server_name'];
|
||
}
|
||
if (!empty($server['allow_insecure'])) {
|
||
$array['skip-cert-verify'] = (bool)$server['allow_insecure'];
|
||
}
|
||
return $array;
|
||
}
|
||
}
|