Compare commits

..

2 Commits

Author SHA1 Message Date
mercury 72edcc4757 websocket transport for xray 2024-09-03 10:19:00 +04:00
mercury 5988c4fcee display warp+ key 2024-08-27 13:46:08 +04:00
18 changed files with 642 additions and 451 deletions
+324 -364
View File
@@ -133,6 +133,9 @@ class Bot
case preg_match('~^/changeWG (\d+)$~', $this->input['callback'], $m): case preg_match('~^/changeWG (\d+)$~', $this->input['callback'], $m):
$this->changeWG($m[1]); $this->changeWG($m[1]);
break; break;
case preg_match('~^/changeTransport(?: (\d+))?$~', $this->input['callback'], $m):
$this->changeTransport($m[1] ?: false);
break;
case preg_match('~^/mirror$~', $this->input['message'], $m): case preg_match('~^/mirror$~', $this->input['message'], $m):
$this->menu('mirror'); $this->menu('mirror');
break; break;
@@ -295,9 +298,6 @@ class Bot
case preg_match('~^/setSSL (\w+)$~', $this->input['callback'], $m): case preg_match('~^/setSSL (\w+)$~', $this->input['callback'], $m):
$this->setSSL($m[1]); $this->setSSL($m[1]);
break; break;
case preg_match('~^/setSingboxType (\w+)$~', $this->input['callback'], $m):
$this->setSingboxType($m[1]);
break;
case preg_match('~^/lang (\w+)$~', $this->input['callback'], $m): case preg_match('~^/lang (\w+)$~', $this->input['callback'], $m):
$this->setLang($m[1]); $this->setLang($m[1]);
break; break;
@@ -440,6 +440,9 @@ class Bot
case preg_match('~^/changeFakeDomain$~', $this->input['callback'], $m): case preg_match('~^/changeFakeDomain$~', $this->input['callback'], $m):
$this->changeFakeDomain(); $this->changeFakeDomain();
break; break;
case preg_match('~^/selfFakeDomain$~', $this->input['callback'], $m):
$this->selfFakeDomain();
break;
case preg_match('~^/changeTGDomain$~', $this->input['callback'], $m): case preg_match('~^/changeTGDomain$~', $this->input['callback'], $m):
$this->changeTGDomain(); $this->changeTGDomain();
break; break;
@@ -534,101 +537,12 @@ class Bot
} }
} }
public function restartXray($c = false) public function restartXray($c)
{ {
$c = $c ?: $this->getXray(); $c['inbounds'][0]['settings']['clients'] = array_values($c['inbounds'][0]['settings']['clients']);
$p = $this->getPacConf(); $this->ssh('pkill xray', 'xr');
if (!empty($p['xrusers'])) { file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$cl = array_filter($p['xrusers'], fn ($e) => empty($e['off']) && (empty($e['time']) || $e['time'] >= time())); $this->ssh('xray run -config /xray.json > /dev/null 2>&1 &', 'xr');
}
switch ($p['xtlsmode']) {
case 'shadow':
if (!empty($cl)) {
foreach ($cl as $v) {
$t[] = [
"name" => $v['name'],
"password" => $v['uuid'],
];
}
}
$c['inbounds'] = [
[
"type" => "shadowtls",
"tag" => "ss-tls-in",
"listen" => "0.0.0.0",
"detour" => "ss-in",
"sniff" => true,
"sniff_override_destination" => false,
"listen_port" => 443,
"version" => 3,
"strict_mode" => true,
"users" => $t ?: [],
"handshake" => [
"server" => $p['xray']['domain'],
"server_port" => 443,
"domain_strategy" => "ipv4_only"
]
],
[
"type" => "shadowsocks",
"tag" => "ss-in",
"listen" => "127.0.0.1",
"network" => "tcp",
"sniff" => false,
"sniff_override_destination" => false,
"method" => "2022-blake3-aes-128-gcm",
"password" => $p['xray']['sspwd'],
"multiplex" => [
"enabled" => true,
"padding" => true,
]
]
];
break;
case 'trojan':
break;
default:
if (!empty($cl)) {
foreach ($cl as $v) {
$t[] = [
"uuid" => $v['uuid'],
"flow" => 'xtls-rprx-vision',
"name" => $v['name'],
];
}
}
$c['inbounds'] = [
[
"type" => "vless",
"tag" => "vless",
"listen" => "0.0.0.0",
"listen_port" => 443,
"sniff" => true,
"sniff_override_destination" => false,
"users" => $t ?: [],
"tls" => [
"enabled" => true,
"server_name" => $p['xray']['domain'],
"reality" => [
"enabled" => true,
"handshake" => [
"server" => $p['xray']['domain'],
"server_port" => 443
],
"private_key" => $p['xray']['private'],
"short_id" => [
$p['xray']['shortid']
]
]
]
]
];
break;
}
$this->ssh('pkill sing-box', 'si');
file_put_contents('/config/singbox.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$this->ssh('sing-box run -c /config/singbox.json > /dev/null 2>&1 &', 'si');
} }
public function linkMtproto() public function linkMtproto()
@@ -1261,8 +1175,8 @@ class Bot
public function shutdownClientXr() public function shutdownClientXr()
{ {
try { try {
$p = $this->getPacConf(); $c = $this->getXray();
foreach ($p['xrusers'] as $k => $v) { foreach ($c['inbounds'][0]['settings']['clients'] as $k => $v) {
if (!empty($v['time']) && ($v['time'] < time())) { if (!empty($v['time']) && ($v['time'] < time())) {
$this->switchXr($k, 1); $this->switchXr($k, 1);
} }
@@ -1316,6 +1230,7 @@ class Bot
] : false, ] : false,
'mtproto' => file_get_contents('/config/mtprotosecret'), 'mtproto' => file_get_contents('/config/mtprotosecret'),
'mtprotodomain' => file_get_contents('/config/mtprotodomain'), 'mtprotodomain' => file_get_contents('/config/mtprotodomain'),
'xray' => $this->getXray(),
'oc' => file_get_contents('/config/ocserv.conf'), 'oc' => file_get_contents('/config/ocserv.conf'),
'ocu' => file_get_contents('/config/ocserv.passwd'), 'ocu' => file_get_contents('/config/ocserv.passwd'),
@@ -1377,36 +1292,11 @@ class Bot
if ($this->getPacConf()['wg1_amnezia'] != $json['pac']['wg1_amnezia']) { if ($this->getPacConf()['wg1_amnezia'] != $json['pac']['wg1_amnezia']) {
$switch_wg1amnezia = 1; $switch_wg1amnezia = 1;
} }
unset($json['pac']['subzoneslist']);
unset($json['pac']['reverselist']);
unset($json['pac']['excludelist']);
unset($json['pac']['zapret']);
$this->setPacConf($json['pac']); $this->setPacConf($json['pac']);
$out[] = 'update naiveproxy'; $out[] = 'update naiveproxy';
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out)); $this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
$this->restartNaive(); $this->restartNaive();
$this->pacUpdate('1'); $this->pacUpdate('1');
// xray
if (!empty($json['xray']['inbounds'][0]['settings']['clients'])) {
$out[] = 'migrate xray to singbox';
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
$pac = $this->getPacConf();
foreach ($json['xray']['inbounds'][0]['settings']['clients'] as $v) {
$pac['xrusers'][] = [
'name' => $v['email'],
'uuid' => $v['id'],
];
}
$pac['xray'] = [
"domain" => $json['xray']['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0] != $pac['domain'] ? $json['xray']['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0] : 'vk.com',
"public" => $json['pac']['xray'],
"private" => $json['xray']['inbounds'][0]['streamSettings']['realitySettings']['privateKey'],
"shortid" => $json['xray']['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0],
"sspwd" => trim($this->ssh('sing-box generate rand --base64 16', 'si')),
];
$this->setPacConf($pac);
}
$this->xrayUpdateRules();
} }
// wg // wg
if (!empty($json['wg'])) { if (!empty($json['wg'])) {
@@ -1458,6 +1348,13 @@ class Bot
file_put_contents('/config/mtprotodomain', $json['mtprotodomain'] ?: ''); file_put_contents('/config/mtprotodomain', $json['mtprotodomain'] ?: '');
$this->restartTG(); $this->restartTG();
} }
// xray
if (!empty($json['xray'])) {
$out[] = 'update xray';
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
$this->restartXray($json['xray']);
$this->setUpstreamDomain($json['xray']['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0]);
}
// ocserv // ocserv
if (!empty($json['oc'])) { if (!empty($json['oc'])) {
$out[] = 'update ocserv'; $out[] = 'update ocserv';
@@ -2398,19 +2295,43 @@ DNS-over-HTTPS with IP:
{ {
$c = $this->getPacConf(); $c = $this->getPacConf();
$xr = $this->getXray(); $xr = $this->getXray();
$xr['outbounds'] = [
[
"protocol" => "freedom",
"tag" => "direct",
],
[
"protocol" => "blackhole",
"tag" => "block",
],
[
"protocol" => "socks",
"tag" => "warp",
"settings" => [
'servers' => [
[
"address" => "10.10.0.13",
"port" => 4000,
],
],
],
],
];
if (!empty($c['blocklist']) && !empty(array_filter($c['blocklist']))) { if (!empty($c['blocklist']) && !empty(array_filter($c['blocklist']))) {
$rules[] = [ $rules[] = [
"outbound" => "block", "type" => "field",
"domain_suffix" => array_keys(array_filter($c['blocklist'])), "outboundTag" => "block",
"domain" => array_keys(array_filter($c['blocklist'])),
]; ];
} }
if (!empty($c['warplist']) && !empty(array_filter($c['warplist']))) { if (!empty($c['warplist']) && !empty(array_filter($c['warplist']))) {
$rules[] = [ $rules[] = [
"outbound" => "warp", "type" => "field",
"domain_suffix" => array_keys(array_filter($c['warplist'])), "outboundTag" => "warp",
"domain" => array_keys(array_filter($c['warplist'])),
]; ];
} }
$xr['route']['rules'] = $rules ?: []; $xr['routing']['rules'] = $rules ?: [];
$this->restartXray($xr); $this->restartXray($xr);
} }
@@ -3821,17 +3742,17 @@ DNS-over-HTTPS with IP:
$si = "$scheme://{$domain}/pac/" . base64_encode(serialize([ $si = "$scheme://{$domain}/pac/" . base64_encode(serialize([
'h' => $hash, 'h' => $hash,
't' => 'si', 't' => 'si',
's' => $pac['xrusers'][$i]['uuid'], 's' => $c['inbounds'][0]['settings']['clients'][$i]['id'],
])); ]));
switch ($s) { switch ($s) {
case 1: case 1:
return "$scheme://{$domain}/pac?h=$hash&t=s&s={$pac['xrusers'][$i]['uuid']}"; return "$scheme://{$domain}/pac?h=$hash&t=s&s={$c['inbounds'][0]['settings']['clients'][$i]['id']}";
case 2: case 2:
return "sing-box://import-remote-profile/?url={$si}#{$pac['xrusers'][$i]['name']}"; return "sing-box://import-remote-profile/?url={$si}#{$c['inbounds'][0]['settings']['clients'][$i]['email']}";
default: default:
return "vless://{$pac['xrusers'][$i]['uuid']}@$domain:443?security=reality&sni={$c['inbounds'][0]['tls']['reality']['handshake']['server']}&fp=chrome&pbk={$pac['xray']['public']}&sid={$c['inbounds'][0]['tls']['reality']['short_id'][0]}&type=tcp&flow=xtls-rprx-vision#{$pac['xrusers'][$i]['name']}"; return "vless://{$c['inbounds'][0]['settings']['clients'][$i]['id']}@$domain:443?security=reality&sni={$c['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0]}&fp=chrome&pbk={$pac['xray']}&sid={$c['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0]}&type=tcp&flow=xtls-rprx-vision#{$c['inbounds'][0]['settings']['clients'][$i]['email']}";
} }
} }
@@ -4040,10 +3961,14 @@ DNS-over-HTTPS with IP:
public function delxr($i) public function delxr($i)
{ {
$p = $this->getPacConf(); $r = $this->getXray();
unset($p['xrusers'][$i]); foreach ($r['inbounds'][0]['settings']['clients'] as $k => $v) {
$this->setPacConf($p); if ($i == $k) {
$this->restartXray(); unset($r['inbounds'][0]['settings']['clients'][$k]);
$this->restartXray($r);
break;
}
}
$this->xray(); $this->xray();
} }
@@ -4062,51 +3987,50 @@ DNS-over-HTTPS with IP:
public function addxrus($user) public function addxrus($user)
{ {
$uuid = trim($this->ssh('sing-box generate uuid', 'si')); $c = $this->getXray();
$pac = $this->getPacConf(); $uuid = trim($this->ssh('xray uuid', 'xr'));
$c['inbounds'][0]['settings']['clients'][] = [
$pac['xrusers'][] = [ 'id' => $uuid,
'uuid' => $uuid, 'flow' => 'xtls-rprx-vision',
'flow' => 'xtls-rprx-vision', 'email' => $user,
'name' => $user,
]; ];
$this->setPacConf($pac); $this->restartXray($c);
$this->restartXray($this->getXray()); $this->userXr(count($c['inbounds'][0]['settings']['clients']) - 1);
$this->userXr(count($pac['xrusers']) - 1);
} }
public function setTimerXr($time, $i) public function setTimerXr($time, $i)
{ {
$c = $this->getPacConf(); $time = strtotime($time);
if ($time === '0') { if ($time === false) {
unset($c['xrusers'][$i]['time']); $this->send($this->input['chat'], 'wrong format');
} else { return;
$time = strtotime($time);
if ($time === false) {
$this->send($this->input['chat'], 'wrong format');
return;
}
if (!empty($c['xrusers'][$i]['off'])) {
unset($c['xrusers'][$i]['off']);
}
$c['xrusers'][$i]['time'] = $time;
} }
$this->setPacConf($c); $c = $this->getXray();
$this->restartXray(); if (empty($time)) {
unset($c['inbounds'][0]['settings']['clients'][$i]['time']);
} else {
if (!empty($c['inbounds'][0]['settings']['clients'][$i]['off'])) {
$this->switchXr($i, 1);
$c = $this->getXray();
}
$c['inbounds'][0]['settings']['clients'][$i]['time'] = $time;
}
file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$this->userXr($i); $this->userXr($i);
} }
public function switchXr($i, $nm = 0) public function switchXr($i, $nm = 0)
{ {
$p = $this->getPacConf(); $c = $this->getXray();
unset($p['xrusers'][$i]['time']); unset($c['inbounds'][0]['settings']['clients'][$i]['time']);
if (empty($p['xrusers'][$i]['off'])) { if (empty($c['inbounds'][0]['settings']['clients'][$i]['off'])) {
$p['xrusers'][$i]['off'] = 1; $c['inbounds'][0]['settings']['clients'][$i]['off'] = $c['inbounds'][0]['settings']['clients'][$i]['id'];
$c['inbounds'][0]['settings']['clients'][$i]['id'] = trim($this->ssh('xray uuid', 'xr'));
} else { } else {
unset($p['xrusers'][$i]['off']); $c['inbounds'][0]['settings']['clients'][$i]['id'] = $c['inbounds'][0]['settings']['clients'][$i]['off'];
unset($c['inbounds'][0]['settings']['clients'][$i]['off']);
} }
$this->setPacConf($p); $this->restartXray($c);
$this->restartXray();
if (empty($nm)) { if (empty($nm)) {
$this->userXr($i); $this->userXr($i);
} }
@@ -4114,9 +4038,9 @@ DNS-over-HTTPS with IP:
public function renXrUs($name, $i) public function renXrUs($name, $i)
{ {
$c = $this->getPacConf(); $c = $this->getXray();
$c['xrusers'][$i]['name'] = $name; $c['inbounds'][0]['settings']['clients'][$i]['email'] = $name;
$this->setPacConf($c); $this->restartXray($c);
$this->userXr($i); $this->userXr($i);
} }
@@ -4170,14 +4094,10 @@ DNS-over-HTTPS with IP:
$this->templates($type); $this->templates($type);
} }
public function downloadTemplate($type, $name = false) public function downloadTemplate($type, $name)
{ {
$pac = $this->getPacConf(); $pac = $this->getPacConf();
if (!empty($name)) { $f = new \CURLStringFile(json_encode($pac["{$type}templates"][base64_decode($name)], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), base64_decode($name) . '.json', 'application/json');
$f = new \CURLStringFile(json_encode($pac["{$type}templates"][base64_decode($name)], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), base64_decode($name) . '.json', 'application/json');
} else {
$f = new \CURLFile("/config/{$type}.json", 'application/json', "$type.json");
}
$this->sendFile($this->input['chat'], $f); $this->sendFile($this->input['chat'], $f);
} }
@@ -4212,10 +4132,6 @@ DNS-over-HTTPS with IP:
'text' => "origin", 'text' => "origin",
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te&ty=$type"], 'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te&ty=$type"],
], ],
[
'text' => $this->i18n('download'),
'callback_data' => "/downloadTemplate $type",
],
[ [
'text' => $this->i18n($pac["default{$type}template"] && !empty($pac["{$type}templates"][base64_decode($pac["default{$type}template"])]) ? 'off' : 'on'), 'text' => $this->i18n($pac["default{$type}template"] && !empty($pac["{$type}templates"][base64_decode($pac["default{$type}template"])]) ? 'off' : 'on'),
'callback_data' => "/defaultTemplate $type", 'callback_data' => "/defaultTemplate $type",
@@ -4256,55 +4172,38 @@ DNS-over-HTTPS with IP:
); );
} }
public function setSingboxType($type)
{
$p = $this->getPacConf();
$p['xtlsmode'] = $type;
if (empty($p['xray']['sspwd'])) {
$p['xray']['sspwd'] = trim($this->ssh('sing-box generate rand --base64 16', 'si'));
}
$this->setPacConf($p);
$this->restartXray();
$this->xray();
}
public function xray($page = 0) public function xray($page = 0)
{ {
$pac = $this->getPacConf(); if (!$this->ssh('pgrep xray', 'xr')) {
if (!$this->ssh('pgrep sing-box', 'si') || empty($pac['xray']['private'])) {
$this->generateSecretXray(); $this->generateSecretXray();
$pac = $this->getPacConf();
} }
$c = $this->getXray();
$p = $this->getPacConf();
$text[] = "Menu -> " . $this->i18n('xray'); $text[] = "Menu -> " . $this->i18n('xray');
$text[] = "\nfake domain: <code>{$pac['xray']['domain']}</code>"; $text[] = "fake domain: <code>{$c['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0]}</code>";
$text[] = "public: <code>{$pac['xray']['public']}</code>"; $text[] = 'transport: ' . ($p['transport'] ?: 'Reality');
$text[] = "private: <code>{$pac['xray']['private']}</code>";
$text[] = "shortId: <code>{$pac['xray']['shortid']}</code>";
$text[] = "sspwd: <code>{$pac['xray']['sspwd']}</code>";
$data[] = [ $data[] = [
[ [
'text' => $this->i18n('generateSecret'), 'text' => $this->i18n('Reality') . ' ' . ($p['transport'] != 'Websocket' ? $this->i18n('on') : $this->i18n('off')),
'callback_data' => "/generateSecretXray", 'callback_data' => "/changeTransport",
], ],
[ [
'text' => $this->i18n('changeFakeDomain'), 'text' => $this->i18n('Websocket') . ' ' . ($p['transport'] == 'Websocket' ? $this->i18n('on') : $this->i18n('off')),
'callback_data' => "/changeFakeDomain", 'callback_data' => "/changeTransport 1",
], ],
]; ];
$data[] = [ if ($p['transport'] != 'Websocket') {
[ $data[] = [
'text' => $this->i18n('reality') . ' ' . ((empty($pac['xtlsmode']) || $pac['xtlsmode'] == 'reality') ? '✅' : ''), [
'callback_data' => "/setSingboxType reality", 'text' => $this->i18n('changeFakeDomain'),
], 'callback_data' => "/changeFakeDomain",
[ ],
'text' => $this->i18n('shadow') . ' ' . ($pac['xtlsmode'] == 'shadow' ? '✅' : ''), [
'callback_data' => "/setSingboxType shadow", 'text' => $this->i18n('selfFakeDomain'),
], 'callback_data' => "/selfFakeDomain",
// [ ],
// 'text' => $this->i18n('trojan') . ' ' . ($pac['xtlsmode'] == 'trojan' ? '✅' : ''), ];
// 'callback_data' => "/setSingboxType trojan", }
// ],
];
$data[] = [ $data[] = [
[ [
'text' => $this->i18n('v2ray templates'), 'text' => $this->i18n('v2ray templates'),
@@ -4321,15 +4220,15 @@ DNS-over-HTTPS with IP:
'callback_data' => "/routes", 'callback_data' => "/routes",
], ],
]; ];
$cl = $pac['xrusers'] ?: []; foreach ($c['inbounds'][0]['settings']['clients'] as $k => $v) {
foreach ($cl as $k => $v) {
if (!empty($v['off'])) { if (!empty($v['off'])) {
$off++; $off++;
} else { } else {
$on++; $on++;
} }
} }
$clients = array_filter($cl, fn($e) => !$pac['xtlslist'] ? empty($e['off']) : !empty($e['off'])); $type = $this->getPacConf()['xtlslist'];
$clients = array_filter($c['inbounds'][0]['settings']['clients'], fn($e) => !$type ? empty($e['off']) : !empty($e['off']));
uasort($clients, fn($a, $b) => ($a['time'] ?: PHP_INT_MAX) <=> ($b['time'] ?: PHP_INT_MAX)); uasort($clients, fn($a, $b) => ($a['time'] ?: PHP_INT_MAX) <=> ($b['time'] ?: PHP_INT_MAX));
$all = (int) ceil(count($clients) / $this->limit); $all = (int) ceil(count($clients) / $this->limit);
@@ -4340,7 +4239,7 @@ DNS-over-HTTPS with IP:
$time = $v['time'] ? $this->getTime($v['time']) : ''; $time = $v['time'] ? $this->getTime($v['time']) : '';
$data[] = [ $data[] = [
[ [
'text' => "{$v['name']}" . ($time ? ": $time" : ''), 'text' => "{$v['email']}" . ($time ? ": $time" : ''),
'callback_data' => "/userXr $k", 'callback_data' => "/userXr $k",
], ],
]; ];
@@ -4363,11 +4262,11 @@ DNS-over-HTTPS with IP:
'callback_data' => "/addXrUser", 'callback_data' => "/addXrUser",
], ],
[ [
'text' => $this->i18n('on') . " $on " . (!$pac['xtlslist'] ? "" : ''), 'text' => $this->i18n('on') . " $on " . (!$type ? "" : ''),
'callback_data' => "/listXr 0", 'callback_data' => "/listXr 0",
], ],
[ [
'text' => $this->i18n('off') . " $off " . ($pac['xtlslist'] ? "" : ''), 'text' => $this->i18n('off') . " $off " . ($type ? "" : ''),
'callback_data' => "/listXr 1", 'callback_data' => "/listXr 1",
], ],
]; ];
@@ -4459,6 +4358,7 @@ DNS-over-HTTPS with IP:
{ {
$text[] = "Menu -> " . $this->i18n('warp'); $text[] = "Menu -> " . $this->i18n('warp');
$text[] = "status: " . $this->warpStatus(); $text[] = "status: " . $this->warpStatus();
$text[] = "key: " . $this->getPacConf()['warp'];
$data[] = [ $data[] = [
[ [
'text' => $this->i18n('set key'), 'text' => $this->i18n('set key'),
@@ -4483,13 +4383,13 @@ DNS-over-HTTPS with IP:
public function choiceTemplate($arg) public function choiceTemplate($arg)
{ {
$arg = explode('_', $arg); $arg = explode('_', $arg);
$c = $this->getPacConf(); $c = $this->getXray();
if (!empty($arg[2])) { if (!empty($arg[2])) {
$c['xrusers'][$arg[1]]["{$arg[0]}template"] = $arg[2]; $c['inbounds'][0]['settings']['clients'][$arg[1]]["{$arg[0]}template"] = $arg[2];
} else { } else {
unset($c['xrusers'][$arg[1]]["{$arg[0]}template"]); unset($c['inbounds'][0]['settings']['clients'][$arg[1]]["{$arg[0]}template"]);
} }
$this->setPacConf($c); file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
$this->userXr($arg[1]); $this->userXr($arg[1]);
} }
@@ -4497,7 +4397,7 @@ DNS-over-HTTPS with IP:
{ {
$c = $this->getXray(); $c = $this->getXray();
$pac = $this->getPacConf(); $pac = $this->getPacConf();
$text[] = "Menu -> " . $this->i18n('xray') . " -> {$pac['xrusers'][$i]['name']}\n"; $text[] = "Menu -> " . $this->i18n('xray') . " -> {$c['inbounds'][0]['settings']['clients'][$i]['email']}\n";
$templates = $pac["{$type}templates"]; $templates = $pac["{$type}templates"];
$data[] = [ $data[] = [
[ [
@@ -4535,32 +4435,33 @@ DNS-over-HTTPS with IP:
public function userXr($i) public function userXr($i)
{ {
$c = $this->getXray()['inbounds'][0]['settings']['clients'][$i];
$pac = $this->getPacConf(); $pac = $this->getPacConf();
$c = $pac['xrusers'][$i];
$domain = $pac['domain'] ?: $this->ip; $domain = $pac['domain'] ?: $this->ip;
$scheme = empty($this->nginxGetTypeCert()) ? 'http' : 'https'; $scheme = empty($this->nginxGetTypeCert()) ? 'http' : 'https';
$hash = substr(md5($this->key), 0, 8); $hash = substr(md5($this->key), 0, 8);
$text[] = "Menu -> " . $this->i18n('xray') . " -> {$c['name']}\n"; $text[] = "Menu -> " . $this->i18n('xray') . " -> {$c['email']}\n";
$text[] = "<code>{$this->linkXray($i)}</code>\n";
$text[] = "import subscribe:"; $text[] = "import subscribe:";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=v&s={$c['uuid']}#{$c['name']}'>v2rayng</a>"; $text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=v&s={$c['id']}#{$c['email']}'>v2rayng</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=si&s={$c['uuid']}#{$c['name']}'>sing-box</a>"; $text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=si&s={$c['id']}#{$c['email']}'>sing-box</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=st&s={$c['uuid']}#{$c['name']}'>streisand</a>"; $text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=st&s={$c['id']}#{$c['email']}'>streisand</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=h&s={$c['uuid']}#{$c['name']}'>hiddify</a>"; $text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=h&s={$c['id']}#{$c['email']}'>hiddify</a>";
$text[] = "\nv2ray config: <code>$scheme://{$domain}/pac?h=$hash&t=s&s={$c['uuid']}</code>"; $text[] = "\nv2ray config: <code>$scheme://{$domain}/pac?h=$hash&t=s&s={$c['id']}</code>";
$text[] = "sing-box config: <code>$scheme://{$domain}/pac?h=$hash&t=si&s={$c['uuid']}</code>"; $text[] = "sing-box config: <code>$scheme://{$domain}/pac?h=$hash&t=si&s={$c['id']}</code>";
$text[] = "sing-box windows: <a href='$scheme://{$domain}/pac?h=$hash&t=si&r=w&s={$c['uuid']}'>windows service</a>"; $text[] = "sing-box windows: <a href='$scheme://{$domain}/pac?h=$hash&t=si&r=w&s={$c['id']}'>windows service</a>";
$data[] = [ $data[] = [
[ [
'text' => 'v2ray', 'text' => 'v2ray',
'web_app' => ['url' => "https://{$domain}/pac?h=$hash&t=s&s={$c['uuid']}"], 'web_app' => ['url' => "https://{$domain}/pac?h=$hash&t=s&s={$c['id']}"],
], ],
[ [
'text' => 'sing-box', 'text' => 'sing-box',
'web_app' => ['url' => "https://{$domain}/pac?h=$hash&t=si&s={$c['uuid']}"], 'web_app' => ['url' => "https://{$domain}/pac?h=$hash&t=si&s={$c['id']}"],
], ],
]; ];
$data[] = [ $data[] = [
@@ -4573,8 +4474,8 @@ DNS-over-HTTPS with IP:
'callback_data' => "/switchXr $i", 'callback_data' => "/switchXr $i",
], ],
]; ];
$singtemplate = $c['singtemplate'] && !empty($pac['singtemplates'][base64_decode($c['singtemplate'])]) ? base64_decode($c['singtemplate']) : 'default(' . ($pac['defaultsingtemplate'] && !empty($pac['singtemplates'][base64_decode($pac['defaultsingtemplate'])]) ? base64_decode($pac['defaultsingtemplate']) : 'origin') . ')'; $singtemplate = $c['singtemplate'] ? base64_decode($c['singtemplate']) : 'default(' . ($pac['defaultsingtemplate'] && !empty($pac['singtemplates'][base64_decode($pac['defaultsingtemplate'])]) ? base64_decode($pac['defaultsingtemplate']) : 'origin') . ')';
$v2raytemplate = $c['v2raytemplate'] && !empty($pac['v2raytemplates'][base64_decode($c['v2raytemplate'])]) ? base64_decode($c['v2raytemplate']) : 'default(' . ($pac['defaultv2raytemplate'] && !empty($pac['v2raytemplates'][base64_decode($pac['defaultv2raytemplate'])]) ? base64_decode($pac['defaultv2raytemplate']) : 'origin') . ')'; $v2raytemplate = $c['v2raytemplate'] ? base64_decode($c['v2raytemplate']) : 'default(' . ($pac['defaultv2raytemplate'] && !empty($pac['v2raytemplates'][base64_decode($pac['defaultv2raytemplate'])]) ? base64_decode($pac['defaultv2raytemplate']) : 'origin') . ')';
$data[] = [ $data[] = [
[ [
'text' => $this->i18n('v2ray') . ": $v2raytemplate", 'text' => $this->i18n('v2ray') . ": $v2raytemplate",
@@ -4623,6 +4524,45 @@ DNS-over-HTTPS with IP:
); );
} }
public function v2raySubscription($key, $fs = 0)
{
$pac = $this->getPacConf();
$domain = $pac['domain'] ?: $this->ip;
$xr = $this->getXray();
$flag = true;
foreach ($xr['inbounds'][0]['settings']['clients'] as $k => $v) {
if ($v['id'] == $key) {
if (!empty($fs)) {
return $this->userXr($k, 0, 1);
}
if (empty($v['off'])) {
$flag = false;
}
break;
}
}
if ($flag) {
return;
}
$c = json_decode(file_get_contents('/config/v2ray.json'), true);
$c['outbounds'][0]['settings']['vnext'][0]['address'] = $domain;
$c['outbounds'][0]['settings']['vnext'][0]['users'][0]['id'] = $key;
$c['outbounds'][0]['streamSettings']['realitySettings']['serverName'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0];
$c['outbounds'][0]['streamSettings']['realitySettings']['publicKey'] = $pac['xray'];
$c['outbounds'][0]['streamSettings']['realitySettings']['shortId'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0];
$c['routing']['rules'][0]['domain'] = array_keys(array_filter($pac['includelist']));
if (empty($c['routing']['rules'][0]['domain'])) {
unset($c['routing']['rules'][0]);
$c['routing']['rules'] = array_values($c['routing']['rules']);
}
echo json_encode($c);
}
public function subscription() public function subscription()
{ {
$type = $_GET['t'] == 's' ? 'v2ray' : 'sing'; $type = $_GET['t'] == 's' ? 'v2ray' : 'sing';
@@ -4633,13 +4573,13 @@ DNS-over-HTTPS with IP:
$hash = substr(md5($this->key), 0, 8); $hash = substr(md5($this->key), 0, 8);
$flag = true; $flag = true;
foreach ($pac['xrusers'] as $k => $v) { foreach ($xr['inbounds'][0]['settings']['clients'] as $k => $v) {
if ($v['uuid'] == $_GET['s']) { if ($v['id'] == $_GET['s']) {
if (empty($v['off'])) { if (empty($v['off'])) {
$flag = false; $flag = false;
} }
$uid = $v['uuid'];
$template = base64_decode($v["{$type}template"]); $template = base64_decode($v["{$type}template"]);
$uid = $v['id'];
break; break;
} }
} }
@@ -4704,10 +4644,41 @@ DNS-over-HTTPS with IP:
switch ($_GET['t']) { switch ($_GET['t']) {
case 's': case 's':
$c['outbounds'][0]['settings']['vnext'][0]['address'] = $domain; $c['outbounds'][0]['settings']['vnext'][0]['address'] = $domain;
$c['outbounds'][0]['settings']['vnext'][0]['users'][0]['id'] = $uid; $c['outbounds'][0]['settings']['vnext'][0]['users'][0] = [
$c['outbounds'][0]['streamSettings']['realitySettings']['serverName'] = $pac['xray']['domain']; 'id' => $uid,
$c['outbounds'][0]['streamSettings']['realitySettings']['publicKey'] = $pac['xray']['public']; 'encryption' => 'none',
$c['outbounds'][0]['streamSettings']['realitySettings']['shortId'] = $pac['xray']['shortid']; ];
if ($pac['transport'] == 'Websocket') {
$c['outbounds'][0]['streamSettings'] = [
"network" => "ws",
"security" => "tls",
"wsSettings" => [
"path" => "/ws?ed=2560"
],
"tlsSettings" => [
"allowInsecure" => false,
"serverName" => $domain,
"fingerprint" => "chrome"
]
];
unset($c['outbounds'][0]['mux']);
} else {
$c['outbounds'][0]['settings']['vnext'][0]['users'][0]["flow"] = "xtls-rprx-vision";
$c['outbounds'][0]['streamSettings'] = [
"network" => "tcp",
"security" => "reality",
"realitySettings" => [
"serverName" => $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0],
"fingerprint" => "chrome",
"publicKey" => $pac['xray'],
"shortId" => $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0],
]
];
$c['outbounds'][0]['mux'] = [
"enabled" => false,
"concurrency" => -1
];
}
foreach ($c['routing']['rules'] as $k => $v) { foreach ($c['routing']['rules'] as $k => $v) {
if (array_key_exists('domain', $v) && $v['domain'] == '~pac~') { if (array_key_exists('domain', $v) && $v['domain'] == '~pac~') {
@@ -4724,86 +4695,24 @@ DNS-over-HTTPS with IP:
$c['dns']['servers'][0]['address'] = "tls://" . ($pac['adguardkey'] ? "{$pac['adguardkey']}." : '') . "$domain"; $c['dns']['servers'][0]['address'] = "tls://" . ($pac['adguardkey'] ? "{$pac['adguardkey']}." : '') . "$domain";
} }
switch ($pac['xtlsmode']) { $c['outbounds'][0]['server'] = $domain;
case 'shadow': $c['outbounds'][0]['uuid'] = $uid;
$o = [ if ($pac['transport'] == 'Websocket') {
[ unset($c['outbounds'][0]['tls']['reality']);
"type" => "shadowtls", unset($c['outbounds'][0]['flow']);
"tag" => "ss-tls-out", $c['outbounds'][0]["transport"] = [
"server" => $domain, "type" => "ws",
"server_port" => 443, "path" => "/ws"
"version" => 3, ];
"password" => $uid, $c['outbounds'][0]['tls']['server_name'] = $domain;
"tls" => [ } else {
"enabled" => true, unset($c['outbounds'][0]["transport"]);
"server_name" => $pac['xray']['domain'], $c['outbounds'][0]['flow'] = 'xtls-rprx-vision';
"utls" => [ $c['outbounds'][0]['tls']['reality']['public_key'] = $pac['xray'];
"enabled" => true, $c['outbounds'][0]['tls']['server_name'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0];
"fingerprint" => "randomized" $c['outbounds'][0]['tls']['reality']['short_id'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0];
]
]
],
[
"type" => "shadowsocks",
"tag" => "proxy",
"detour" => "ss-tls-out",
"method" => "2022-blake3-aes-128-gcm",
"password" => $pac['xray']['sspwd'],
"network" => "tcp",
"udp_over_tcp" => true,
"multiplex" => [
"enabled" => true,
"padding" => true
]
]
];
break;
case 'trojan':
break;
default:
$o = [
[
"flow" => "xtls-rprx-vision",
"packet_encoding" => "",
"server" => $domain,
"server_port" => 443,
"tls" => [
"enabled" => true,
"insecure" => false,
"reality" => [
"enabled" => true,
"public_key" => $pac['xray']['public'],
"short_id" => $pac['xray']['shortid']
],
"server_name" => $pac['xray']['domain'],
"utls" => [
"enabled" => true,
"fingerprint" => "chrome"
]
],
"uuid" => $uid,
"type" => "vless",
"domain_strategy" => "ipv4_only",
"tag" => "proxy"
]
];
break;
} }
$c['outbounds'] = array_merge($o, [
[
"type" => "direct",
"tag" => "direct"
],
[
"type" => "block",
"tag" => "block"
],
[
"type" => "dns",
"tag" => "dns-out"
]
]);
foreach ($c['route']['rules'] as $k => $v) { foreach ($c['route']['rules'] as $k => $v) {
if (array_key_exists('domain_suffix', $v) && $v['domain_suffix'] == '~pac~') { if (array_key_exists('domain_suffix', $v) && $v['domain_suffix'] == '~pac~') {
$c['route']['rules'][$k]['domain_suffix'] = array_keys(array_filter($pac['includelist'] ?: [])); $c['route']['rules'][$k]['domain_suffix'] = array_keys(array_filter($pac['includelist'] ?: []));
@@ -4947,28 +4856,24 @@ DNS-over-HTTPS with IP:
public function getXray() public function getXray()
{ {
return json_decode(file_get_contents('/config/singbox.json'), true); return json_decode(file_get_contents('/config/xray.json'), true);
} }
public function generateSecretXray() public function generateSecretXray()
{ {
$c = $this->getXray(); $c = $this->getXray();
$shortId = trim($this->ssh('openssl rand -hex 8', 'si')); $shortId = trim($this->ssh('openssl rand -hex 8', 'xr'));
$keys = $this->ssh('sing-box generate reality-keypair', 'si'); $keys = $this->ssh('xray x25519', 'xr');
preg_match('~^PrivateKey:\s([^\s]+)~m', $keys, $m); preg_match('~^Private key:\s([^\s]+)~m', $keys, $m);
$private = trim($m[1]); $private = trim($m[1]);
preg_match('~^PublicKey:\s([^\s]+)~m', $keys, $m); preg_match('~^Public key:\s([^\s]+)~m', $keys, $m);
$public = trim($m[1]); $public = trim($m[1]);
$sspwd = trim($this->ssh('sing-box generate rand --base64 16', 'si')); $c['inbounds'][0]['streamSettings']['realitySettings']['privateKey'] = $private;
$pac = $this->getPacConf(); $c['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0] = $shortId;
$pac = $this->getPacConf();
$pac['xray'] = [ $pac['xray'] = $public;
'domain' => !empty($pac['xray']['domain']) ? $pac['xray']['domain'] : 'vk.com', $pac['reality']['shortId'] = $shortId;
'public' => $public, $pac['reality']['privateKey'] = $$p['reality']['shortId'];
'private' => $private,
'shortid' => $shortId,
'sspwd' => $sspwd,
];
$this->setPacConf($pac); $this->setPacConf($pac);
$this->restartXray($c); $this->restartXray($c);
} }
@@ -4976,7 +4881,7 @@ DNS-over-HTTPS with IP:
public function setUpstreamDomain($domain) public function setUpstreamDomain($domain)
{ {
$nginx = file_get_contents('/config/upstream.conf'); $nginx = file_get_contents('/config/upstream.conf');
$t = preg_replace('~#domain.+#domain~s', "#domain\n$domain singbox;\n#domain", $nginx); $t = preg_replace('~#domain.+#domain~s', "#domain\n$domain reality;\n#domain", $nginx);
file_put_contents('/config/upstream.conf', $t); file_put_contents('/config/upstream.conf', $t);
$this->ssh("nginx -s reload 2>&1", 'up'); $this->ssh("nginx -s reload 2>&1", 'up');
} }
@@ -5112,7 +5017,7 @@ DNS-over-HTTPS with IP:
], ],
], ],
[ [
'text' => $this->i18n($conf['adgbrowser'] ? 'on' : 'off') . ' ' . $this->i18n('third party browser'), 'text' => $this->i18n('third party browser') . ': ' . $this->i18n($conf['adgbrowser'] ? 'on' : 'off'),
'callback_data' => '/adguardChBr' 'callback_data' => '/adguardChBr'
], ],
], ],
@@ -5451,7 +5356,7 @@ DNS-over-HTTPS with IP:
$this->update( $this->update(
$this->input['chat'], $this->input['chat'],
$this->input['message_id'], $this->input['message_id'],
implode("\n", ['...']), implode("\n", $text ?: ['...']),
$data ?: false, $data ?: false,
); );
} }
@@ -5539,17 +5444,78 @@ DNS-over-HTTPS with IP:
]; ];
} }
public function setFakeDomain($domain) public function setFakeDomain($domain, $self = false)
{ {
$pac = $this->getPacConf(); $c = $this->getXray();
if ($pac['domain'] == $domain) { $p = $this->getPacConf();
$this->send($this->input['from'], 'wrong domain'); $c['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0] = $domain;
return; $c['inbounds'][0]['streamSettings']['realitySettings']['dest'] = $self ? "10.10.1.2:443" : "$domain:443";
} $p['reality']['domain'] = $domain;
$pac['xray']['domain'] = $domain; $p['reality']['destination'] = $self ? "10.10.1.2:443" : "$domain:443";
$this->setPacConf($pac); $this->setPacConf($p);
$this->restartXray($c);
$this->setUpstreamDomain($domain); $this->setUpstreamDomain($domain);
$this->restartXray(); $this->xray();
}
public function selfFakeDomain()
{
$c = $this->getPacConf();
if (!empty($c['domain'])) {
$this->setFakeDomain($c['domain'], 1);
} else{
$this->answer($this->input['callback_id'], 'empty domain', true);
}
}
public function changeTransport($ws = null)
{
$p = $this->getPacConf();
$x = $this->getXray();
$p['transport'] = $ws ? 'Websocket' : 'Reality';
if (!empty($ws)) {
$p['reality']['domain'] = $x['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0];
$p['reality']['destination'] = $x['inbounds'][0]['streamSettings']['realitySettings']['dest'];
$p['reality']['shortId'] = $x['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0];
foreach ($x['inbounds'][0]['settings']['clients'] as $k => $v) {
unset($x['inbounds'][0]['settings']['clients'][$k]['flow']);
}
$x['inbounds'][0]['streamSettings'] = [
"network" => "ws",
"wsSettings" => [
"path" => "/ws"
]
];
} else {
foreach ($x['inbounds'][0]['settings']['clients'] as $k => $v) {
$x['inbounds'][0]['settings']['clients'][$k]['flow'] = 'xtls-rprx-vision';
}
$x['inbounds'][0]['streamSettings'] = [
"network" => "tcp",
"realitySettings" => [
"dest" => $p['reality']['destination'],
"maxClientVer" => "",
"maxTimeDiff" => 0,
"minClientVer" => "",
"privateKey" => $p['reality']['privateKey'],
"serverNames" => [
$p['reality']['domain']
],
"shortIds" => [$p['reality']['shortId']],
"show" => false,
"xver" => 0
],
"tcpSettings" => [
"acceptProxyProtocol" => true
],
"sockopt" => [
"acceptProxyProtocol" => true
],
"security" => "reality"
];
}
$this->setPacConf($p);
$this->restartXray($x);
$this->xray(); $this->xray();
} }
@@ -5630,7 +5596,7 @@ DNS-over-HTTPS with IP:
public function nginxGetTypeCert() public function nginxGetTypeCert()
{ {
$conf = file_get_contents('/config/nginx.conf'); $conf = $this->ssh('cat /etc/nginx/nginx.conf', 'ng');
preg_match("/#~([^\s]+)/", $conf, $m); preg_match("/#~([^\s]+)/", $conf, $m);
return $m[1]; return $m[1];
} }
@@ -5924,12 +5890,6 @@ DNS-over-HTTPS with IP:
die('нет айпи'); die('нет айпи');
} }
echo "$ip\n"; echo "$ip\n";
$this->request('deleteWebhook', []);
$this->request('getUpdates', [
'offset' => -1,
'limit' => 1,
'timeout' => 5,
]);
var_dump($r = $this->request('setWebhook', [ var_dump($r = $this->request('setWebhook', [
'url' => "https://$ip/tlgrm?k={$this->key}", 'url' => "https://$ip/tlgrm?k={$this->key}",
'certificate' => curl_file_create('/certs/self_public'), 'certificate' => curl_file_create('/certs/self_public'),
+2 -2
View File
@@ -262,8 +262,8 @@ $i = [
'ru' => 'очистить', 'ru' => 'очистить',
], ],
'xray' => [ 'xray' => [
'en' => 'Sing-box', 'en' => 'Xray',
'ru' => 'Sing-box', 'ru' => 'Xray',
], ],
'geodb' => [ 'geodb' => [
'en' => 'GeoIp/GeoSite', 'en' => 'GeoIp/GeoSite',
+28 -4
View File
@@ -2,6 +2,7 @@ user nginx;
worker_processes auto; worker_processes auto;
error_log /logs/nginx_error; error_log /logs/nginx_error;
pid /var/run/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
@@ -21,8 +22,8 @@ http {
set_real_ip_from 10.10.0.10; set_real_ip_from 10.10.0.10;
server { server {
listen 80 default_server; listen 10.10.0.2:80 default_server;
listen 443 ssl http2 default_server proxy_protocol; listen 10.10.0.2:443 ssl http2 default_server proxy_protocol;
ssl_certificate /certs/self_public; ssl_certificate /certs/self_public;
ssl_certificate_key /certs/self_private; ssl_certificate_key /certs/self_private;
@@ -63,6 +64,17 @@ http {
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
} }
location /ws {
proxy_pass http://xr:443;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 5d;
}
location ~\.well-known { location ~\.well-known {
access_log /logs/nginx_certbot_access; access_log /logs/nginx_certbot_access;
root /certs/; root /certs/;
@@ -74,11 +86,12 @@ http {
#-domain #-domain
# server { # server {
# listen 80; # listen 10.10.0.2:80;
# server_name ; # server_name ;
#-domain #-domain
#-ssl #-ssl
# listen 443 ssl http2 proxy_protocol; # listen 10.10.0.2:443 ssl http2 proxy_protocol;
# listen 10.10.1.2:443 ssl http2;
# ssl_certificate /certs/cert_public; # ssl_certificate /certs/cert_public;
# ssl_certificate_key /certs/cert_private; # ssl_certificate_key /certs/cert_private;
#-ssl #-ssl
@@ -122,6 +135,17 @@ http {
# proxy_set_header Upgrade $http_upgrade; # proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade"; # proxy_set_header Connection "upgrade";
# } # }
# location /ws {
# proxy_pass http://xr:443;
# proxy_redirect off;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_read_timeout 5d;
# }
#-domain #-domain
#-ssl #-ssl
# # The DoH server block # # The DoH server block
+28 -4
View File
@@ -2,6 +2,7 @@ user nginx;
worker_processes auto; worker_processes auto;
error_log /logs/nginx_error; error_log /logs/nginx_error;
pid /var/run/nginx.pid;
events { events {
worker_connections 1024; worker_connections 1024;
@@ -21,8 +22,8 @@ http {
set_real_ip_from 10.10.0.10; set_real_ip_from 10.10.0.10;
server { server {
listen 80 default_server; listen 10.10.0.2:80 default_server;
listen 443 ssl http2 default_server proxy_protocol; listen 10.10.0.2:443 ssl http2 default_server proxy_protocol;
ssl_certificate /certs/self_public; ssl_certificate /certs/self_public;
ssl_certificate_key /certs/self_private; ssl_certificate_key /certs/self_private;
@@ -63,6 +64,17 @@ http {
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
} }
location /ws {
proxy_pass http://xr:443;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 5d;
}
location ~\.well-known { location ~\.well-known {
access_log /logs/nginx_certbot_access; access_log /logs/nginx_certbot_access;
root /certs/; root /certs/;
@@ -74,11 +86,12 @@ http {
#-domain #-domain
# server { # server {
# listen 80; # listen 10.10.0.2:80;
# server_name ; # server_name ;
#-domain #-domain
#-ssl #-ssl
# listen 443 ssl http2 proxy_protocol; # listen 10.10.0.2:443 ssl http2 proxy_protocol;
# listen 10.10.1.2:443 ssl http2;
# ssl_certificate /certs/cert_public; # ssl_certificate /certs/cert_public;
# ssl_certificate_key /certs/cert_private; # ssl_certificate_key /certs/cert_private;
#-ssl #-ssl
@@ -122,6 +135,17 @@ http {
# proxy_set_header Upgrade $http_upgrade; # proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade"; # proxy_set_header Connection "upgrade";
# } # }
# location /ws {
# proxy_pass http://xr:443;
# proxy_redirect off;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection "upgrade";
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_read_timeout 5d;
# }
#-domain #-domain
#-ssl #-ssl
# # The DoH server block # # The DoH server block
+97 -1
View File
@@ -1,3 +1,99 @@
{ {
"includelist": [] "zapret": false,
"excludelist": {
"(?:v|w)ul(?:c|k)an": true,
"^\\d": true,
"^a\\w-": true,
"^admiral": true,
"^avtomaty": true,
"^azart": true,
"^azimob": true,
"^baltplay": true,
"a(?:s|z)ino": true,
"adrenalin": true,
"alco": true,
"bet": true,
"prostitut": true,
"zenit": true,
"zerkalo": true,
"777": true
},
"includelist": {},
"reverselist": {},
"subzoneslist": {
"3dn": false,
"3nx": true,
"akadns": true,
"appspot": true,
"azurewebsites": true,
"beget": true,
"berlogovo": true,
"biz": true,
"brightcove": true,
"cc": true,
"cloudfront": true,
"co": true,
"com": true,
"cu": true,
"ddns": true,
"deviantart": true,
"dn": true,
"dp": true,
"dyndns": true,
"edgecastcdn": true,
"edu": true,
"eu": true,
"fastly": true,
"force": true,
"github": true,
"google": true,
"googleusercontent": true,
"gov": true,
"herokuapp": true,
"hldns": true,
"ho": true,
"hopto": true,
"hwcdn": true,
"i": true,
"iboards": true,
"in": true,
"info": true,
"int": true,
"itch": true,
"keenetic": true,
"kiev": true,
"kirov": true,
"linode": true,
"livejournal": true,
"maryno": true,
"mil": true,
"msk": true,
"my1": true,
"mybb2": true,
"ne": true,
"net": true,
"netdna-ssl": true,
"nnov": true,
"notion": true,
"nov": true,
"od": true,
"org": true,
"pp": true,
"pximg": true,
"pythonanywhere": true,
"ru": true,
"scaleway": true,
"sl": true,
"sl-reverse": true,
"spb": true,
"tilda": true,
"trafficmanager": true,
"tut": true,
"u-stream": true,
"ucoz": true,
"v": true,
"vercel": true,
"wix": true,
"wixmp": true
}
} }
+45 -1
View File
@@ -54,10 +54,54 @@
"detour": "direct" "detour": "direct"
} }
], ],
"rules": [
{
"outbound": "any",
"server": "dns-direct",
"disable_cache": false
}
],
"strategy": "ipv4_only", "strategy": "ipv4_only",
"independent_cache": true "independent_cache": true
}, },
"outbounds": [], "outbounds": [
{
"flow": "xtls-rprx-vision",
"packet_encoding": "",
"server": "",
"server_port": 443,
"tls": {
"enabled": true,
"insecure": false,
"reality": {
"enabled": true,
"public_key": "",
"short_id": ""
},
"server_name": "",
"utls": {
"enabled": true,
"fingerprint": "chrome"
}
},
"uuid": "",
"type": "vless",
"domain_strategy": "ipv4_only",
"tag": "proxy"
},
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": { "route": {
"auto_detect_interface": true, "auto_detect_interface": true,
"override_android_vpn": true, "override_android_vpn": true,
-26
View File
@@ -1,26 +0,0 @@
{
"inbounds": [],
"log": {
"level": "info"
},
"outbounds": [
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
},
{
"type": "socks",
"tag": "warp",
"server": "10.10.0.13",
"server_port": 4000
}
],
"route" : {
"rules": [],
"final": "direct"
}
}
+5 -14
View File
@@ -15,12 +15,8 @@ stream {
server ng:443; server ng:443;
} }
upstream si { upstream reality {
server si:443; server xr:443;
}
upstream singbox {
server 127.0.0.1:4443;
} }
upstream ocserv { upstream ocserv {
@@ -34,7 +30,7 @@ stream {
map_hash_bucket_size 128; map_hash_bucket_size 128;
map $ssl_preread_server_name $sni_name { map $ssl_preread_server_name $sni_name {
#domain #domain
vk.com singbox; www.microsoft.com reality;
#domain #domain
#ocserv #ocserv
@@ -47,22 +43,17 @@ stream {
default other; default other;
} }
server {
listen 4443 reuseport proxy_protocol;
proxy_pass si;
}
server { server {
listen 443 reuseport; listen 443 reuseport;
proxy_pass $sni_name; proxy_pass $sni_name;
ssl_preread on;
proxy_protocol on; proxy_protocol on;
ssl_preread on;
} }
server { server {
listen 443 udp; listen 443 udp;
proxy_pass $sni_name; proxy_pass $sni_name;
ssl_preread on;
proxy_protocol on; proxy_protocol on;
ssl_preread on;
} }
} }
+61
View File
@@ -0,0 +1,61 @@
{
"inbounds": [
{
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
],
"decryption": "none"
},
"sniffing": {
"destOverride": [
"http",
"tls"
],
"enabled": true
},
"streamSettings": {
"network": "tcp",
"realitySettings": {
"dest": "www.microsoft.com:443",
"maxClientVer": "",
"maxTimeDiff": 0,
"minClientVer": "",
"privateKey": "",
"serverNames": [
"www.microsoft.com"
],
"shortIds": [],
"show": false,
"xver": 0
},
"tcpSettings": {
"acceptProxyProtocol": true
},
"sockopt": {
"acceptProxyProtocol": true
},
"security": "reality"
},
"tag": "vless_tls"
}
],
"log": {
"loglevel": "info"
},
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
+21 -12
View File
@@ -10,6 +10,10 @@ networks:
ipam: ipam:
config: config:
- subnet: 10.10.0.0/24 - subnet: 10.10.0.0/24
xray:
ipam:
config:
- subnet: 10.10.1.0/24
volumes: volumes:
adguard: adguard:
@@ -23,9 +27,9 @@ services:
image: ${IMAGE} image: ${IMAGE}
volumes: volumes:
- ./config/.profile:/root/.ashrc:ro - ./config/.profile:/root/.ashrc:ro
- ./config/upstream.conf:/etc/nginx/nginx.conf
- ./scripts/start_upstream.sh:/start_upstream.sh - ./scripts/start_upstream.sh:/start_upstream.sh
- ./ssh:/ssh - ./ssh:/ssh
- ./config:/config
- ./config/sshd_config:/etc/ssh/sshd_config - ./config/sshd_config:/etc/ssh/sshd_config
- ./logs/:/logs/ - ./logs/:/logs/
ports: ports:
@@ -59,7 +63,9 @@ services:
image: ${IMAGE} image: ${IMAGE}
volumes: volumes:
- ./config/.profile:/root/.ashrc:ro - ./config/.profile:/root/.ashrc:ro
- ./config:/config - ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/include.conf:/etc/nginx/include.conf
- ./config/nginx_default.conf:/nginx_default.conf
- ./scripts/start_ng.sh:/start_ng.sh - ./scripts/start_ng.sh:/start_ng.sh
- ./certs/:/certs/ - ./certs/:/certs/
- ./ssh:/ssh - ./ssh:/ssh
@@ -83,6 +89,8 @@ services:
networks: networks:
default: default:
ipv4_address: 10.10.0.2 ipv4_address: 10.10.0.2
xray:
ipv4_address: 10.10.1.2
logging: *default-logging logging: *default-logging
php: php:
image: mercurykd/vpnbot-php:1.5 image: mercurykd/vpnbot-php:1.5
@@ -179,7 +187,7 @@ services:
- ad - ad
- ss - ss
- tg - tg
- si - xr
- oc - oc
- np - np
proxy: proxy:
@@ -390,21 +398,20 @@ services:
default: default:
ipv4_address: 10.10.0.8 ipv4_address: 10.10.0.8
logging: *default-logging logging: *default-logging
si: xr:
image: mercurykd/vpnbot-sb:1.2 image: mercurykd/vpnbot-xr:1.3
build: build:
dockerfile: dockerfile/singbox.dockerfile dockerfile: dockerfile/xray.dockerfile
args: args:
image: ${IMAGE} image: ${IMAGE}
volumes: volumes:
- ./config/.profile:/root/.ashrc:ro - ./config/.profile:/root/.ashrc:ro
- ./ssh:/ssh - ./ssh:/ssh
- ./config/sshd_config:/etc/ssh/sshd_config - ./config/sshd_config:/etc/ssh/sshd_config
- ./config:/config - ./config/xray.json:/xray.json
- ./certs:/certs - ./scripts/start_xray.sh:/start_xray.sh
- ./scripts/start_sing.sh:/start_sing.sh hostname: xray
hostname: singbox container_name: xray-${VER}
container_name: singbox-${VER}
depends_on: depends_on:
php: php:
condition: service_healthy condition: service_healthy
@@ -414,10 +421,12 @@ services:
- path: ./override.env - path: ./override.env
required: false required: false
stop_grace_period: 1s stop_grace_period: 1s
command: ["/bin/sh", "/start_sing.sh"] command: ["/bin/sh", "/start_xray.sh"]
networks: networks:
default: default:
ipv4_address: 10.10.0.9 ipv4_address: 10.10.0.9
xray:
ipv4_address: 10.10.1.9
logging: *default-logging logging: *default-logging
oc: oc:
image: mercurykd/vpnbot-oc:1.2 image: mercurykd/vpnbot-oc:1.2
-9
View File
@@ -1,9 +0,0 @@
ARG image
FROM $image
RUN apk add openssh openssl jq \
&& mkdir /root/.ssh \
&& wget https://github.com/SagerNet/sing-box/releases/download/v1.9.3/sing-box-1.9.3-linux-amd64.tar.gz \
&& tar -xf sing-box-1.9.3-linux-amd64.tar.gz \
&& mv sing-box-1.9.3-linux-amd64/sing-box /usr/bin \
&& rm sing-box-1.9.3-linux-amd64.tar.gz \
&& rm -rf /sing-box-1.9.3-linux-amd64
+12
View File
@@ -0,0 +1,12 @@
ARG image
FROM $image
RUN apk add openssh openssl jq \
&& mkdir /root/.ssh \
&& wget -O Xray-linux-64.zip $(wget -q -O - https://api.github.com/repos/XTLS/Xray-core/releases/latest | grep browser_download_url | cut -d\" -f4 | egrep 'Xray-linux-64.zip$') \
&& unzip Xray-linux-64.zip \
&& mv xray /usr/bin/ \
&& rm Xray-linux-64.zip \
&& rm geoip.dat \
&& rm geosite.dat \
&& chmod +x /usr/bin/xray
ENV ENV="/root/.ashrc"
+2 -2
View File
@@ -36,8 +36,8 @@ proxy: # консоль сервиса
docker compose exec proxy /bin/sh docker compose exec proxy /bin/sh
tg: # консоль сервиса tg: # консоль сервиса
docker compose exec tg /bin/sh docker compose exec tg /bin/sh
si: # консоль сервиса xr: # консоль сервиса
docker compose exec si /bin/sh docker compose exec xr /bin/sh
oc: # консоль сервиса oc: # консоль сервиса
docker compose exec oc /bin/sh docker compose exec oc /bin/sh
clean: clean:
+5 -5
View File
@@ -1,8 +1,8 @@
cat /ssh/key.pub > /root/.ssh/authorized_keys cat /ssh/key.pub > /root/.ssh/authorized_keys
ssh-keygen -A ssh-keygen -A
exec /usr/sbin/sshd -D -e "$@" & exec /usr/sbin/sshd -D -e "$@" &
sed "s/ss:[0-9]\+/ss:$SSPORT/" /config/nginx_default.conf > change_port sed "s/ss:[0-9]\+/ss:$SSPORT/" /nginx_default.conf > change_port
cat change_port > /config/nginx_default.conf cat change_port > /nginx_default.conf
sed "s/ss:[0-9]\+/ss:$SSPORT/" /config/nginx.conf > change_port sed "s/ss:[0-9]\+/ss:$SSPORT/" /etc/nginx/nginx.conf > change_port
cat change_port > /config/nginx.conf cat change_port > /etc/nginx/nginx.conf
nginx -g "daemon off;" -c /config/nginx.conf nginx -g "daemon off;"
-5
View File
@@ -1,5 +0,0 @@
cat /ssh/key.pub > /root/.ssh/authorized_keys
ssh-keygen -A
exec /usr/sbin/sshd -D -e "$@" &
sing-box run -c /config/singbox.json > /dev/null &
tail -f /dev/null
+1 -1
View File
@@ -1,4 +1,4 @@
cat /ssh/key.pub > /root/.ssh/authorized_keys cat /ssh/key.pub > /root/.ssh/authorized_keys
ssh-keygen -A ssh-keygen -A
exec /usr/sbin/sshd -D -e "$@" & exec /usr/sbin/sshd -D -e "$@" &
nginx -g "daemon off;" -c /config/upstream.conf nginx -g "daemon off;"
+8
View File
@@ -0,0 +1,8 @@
cat /ssh/key.pub > /root/.ssh/authorized_keys
ssh-keygen -A
exec /usr/sbin/sshd -D -e "$@" &
if [ $(cat /xray.json | jq -r '.inbounds[0].settings.clients[0].id' | wc -c) -gt 1 ]
then
xray run -config /xray.json > /dev/null &
fi
tail -f /dev/null
+2
View File
@@ -1,3 +1,5 @@
03.09.2024 v1.45
- выбор транспорта reality/websocket
26.08.2024 v1.44 26.08.2024 v1.44
- qr для xtls - qr для xtls
- фикс действий на элементом списков - фикс действий на элементом списков