|
|
|
@@ -370,6 +370,9 @@ class Bot
|
|
|
|
|
case preg_match('~^/downloadTemplate(?: (.+))?$~', $this->input['callback'], $m):
|
|
|
|
|
$this->downloadTemplate($m[1] ?: 0);
|
|
|
|
|
break;
|
|
|
|
|
case preg_match('~^/defaultTemplate(?: (.+))?$~', $this->input['callback'], $m):
|
|
|
|
|
$this->defaultTemplate($m[1] ?: 0);
|
|
|
|
|
break;
|
|
|
|
|
case preg_match('~^/singbox(?: (\w+))?$~', $this->input['callback'], $m):
|
|
|
|
|
$this->singbox($m[1] ?: false);
|
|
|
|
|
break;
|
|
|
|
@@ -1585,6 +1588,7 @@ class Bot
|
|
|
|
|
$t = preg_replace('~#-domain.+?#-domain~s', $this->uncomment($v, 'domain'), $t, 1);
|
|
|
|
|
}
|
|
|
|
|
file_put_contents('/config/nginx.conf', $t);
|
|
|
|
|
$this->adguardProtect();
|
|
|
|
|
$u = $this->ssh("nginx -t 2>&1", 'ng');
|
|
|
|
|
$out[] = $u;
|
|
|
|
|
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
|
|
|
@@ -1985,12 +1989,7 @@ class Bot
|
|
|
|
|
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
|
|
|
|
$out[] = $this->stopAd();
|
|
|
|
|
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
|
|
|
|
$c = yaml_parse_file($this->adguard);
|
|
|
|
|
$c['users'][0]['password'] = password_hash($pass, PASSWORD_DEFAULT);
|
|
|
|
|
yaml_emit_file($this->adguard, $c);
|
|
|
|
|
$p = $this->getPacConf();
|
|
|
|
|
$p['adpswd'] = $pass;
|
|
|
|
|
$this->setPacConf($p);
|
|
|
|
|
$this->adguardChangePswd($pass);
|
|
|
|
|
$out[] = $this->startAd();
|
|
|
|
|
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
|
|
|
|
sleep(3);
|
|
|
|
@@ -3182,7 +3181,6 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
public function menu($type = false, $arg = false, $return = false)
|
|
|
|
|
{
|
|
|
|
|
$domain = $this->getPacConf()['domain'] ?: $this->ip;
|
|
|
|
|
$scheme = empty($this->nginxGetTypeCert()) ? 'http' : 'https';
|
|
|
|
|
$menu = [
|
|
|
|
|
'main' => [
|
|
|
|
|
'text' => 'v' . getenv('VER'),
|
|
|
|
@@ -3251,7 +3249,7 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
[
|
|
|
|
|
'text' => $this->i18n('donate'),
|
|
|
|
|
'web_app' => [
|
|
|
|
|
'url' => "$scheme://$domain/donate.html",
|
|
|
|
|
'url' => "https://$domain/donate.html",
|
|
|
|
|
]
|
|
|
|
|
],
|
|
|
|
|
],
|
|
|
|
@@ -3613,11 +3611,22 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
$this->sendFile($this->input['chat'], $f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function defaultTemplate($name)
|
|
|
|
|
{
|
|
|
|
|
$pac = $this->getPacConf();
|
|
|
|
|
if (!empty($name)) {
|
|
|
|
|
$pac['defaulttemplate'] = $name;
|
|
|
|
|
} else {
|
|
|
|
|
unset($pac['defaulttemplate']);
|
|
|
|
|
}
|
|
|
|
|
$this->setPacConf($pac);
|
|
|
|
|
$this->singbox();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function singbox($name = false)
|
|
|
|
|
{
|
|
|
|
|
$pac = $this->getPacConf();
|
|
|
|
|
$domain = $pac['domain'] ?: $this->ip;
|
|
|
|
|
$scheme = empty($ssl = $this->nginxGetTypeCert()) ? 'http' : 'https';
|
|
|
|
|
$hash = substr(md5($this->key), 0, 8);
|
|
|
|
|
$text[] = "Menu -> " . $this->i18n('xray') . ' -> Sing-box templates';
|
|
|
|
|
$templates = $pac['singtemplates'];
|
|
|
|
@@ -3631,14 +3640,18 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
$data[] = [
|
|
|
|
|
[
|
|
|
|
|
'text' => "default: " . $this->i18n('show'),
|
|
|
|
|
'web_app' => ['url' => "$scheme://$domain/pac?h=$hash&t=te"],
|
|
|
|
|
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te"],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'text' => $this->i18n($pac['defaulttemplate'] ? 'off' : 'on'),
|
|
|
|
|
'callback_data' => "/defaultTemplate",
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
foreach ($templates as $k => $v) {
|
|
|
|
|
$data[] = [
|
|
|
|
|
[
|
|
|
|
|
'text' => "$k: " . $this->i18n('show'),
|
|
|
|
|
'web_app' => ['url' => "$scheme://$domain/pac?h=$hash&t=te&te=" . urlencode($k)],
|
|
|
|
|
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te&te=" . urlencode($k)],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'text' => $this->i18n('download'),
|
|
|
|
@@ -3648,6 +3661,10 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
'text' => $this->i18n('delete'),
|
|
|
|
|
'callback_data' => "/delTemplate " . base64_encode($k),
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
'text' => $this->i18n($pac['defaulttemplate'] == base64_encode($k) ? 'on' : 'off'),
|
|
|
|
|
'callback_data' => "/defaultTemplate " . base64_encode($k),
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -3939,7 +3956,11 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
if (!empty($template) && !empty($pac['singtemplates'][base64_decode($template)])) {
|
|
|
|
|
$c = $pac['singtemplates'][base64_decode($template)];
|
|
|
|
|
} else {
|
|
|
|
|
$c = json_decode(file_get_contents('/config/sing.json'), true);
|
|
|
|
|
if (!empty($pac['defaulttemplate'])) {
|
|
|
|
|
$c = $pac['singtemplates'][base64_decode($pac['defaulttemplate'])];
|
|
|
|
|
} else {
|
|
|
|
|
$c = json_decode(file_get_contents('/config/sing.json'), true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($c['dns']['servers'][0]['address'] == '~dns~') {
|
|
|
|
@@ -3951,12 +3972,16 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
$c['outbounds'][0]['tls']['reality']['public_key'] = $pac['xray'];
|
|
|
|
|
$c['outbounds'][0]['tls']['server_name'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0];
|
|
|
|
|
$c['outbounds'][0]['tls']['reality']['short_id'] = $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0];
|
|
|
|
|
$c['route']['rules'][1]['domain_suffix'] = array_keys(array_filter($pac['includelist']));
|
|
|
|
|
|
|
|
|
|
if (empty($c['route']['rules'][1]['domain_suffix'])) {
|
|
|
|
|
unset($c['route']['rules'][1]);
|
|
|
|
|
$c['route']['rules'] = array_values($c['route']['rules']);
|
|
|
|
|
foreach ($c['route']['rules'] as $k => $v) {
|
|
|
|
|
if (array_key_exists('domain_suffix', $v) && $v['domain_suffix'] == '~pac~') {
|
|
|
|
|
$c['route']['rules'][$k]['domain_suffix'] = array_keys(array_filter($pac['includelist']));
|
|
|
|
|
if (empty($c['route']['rules'][$k]['domain_suffix'])) {
|
|
|
|
|
unset($c['route']['rules'][$k]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$c['route']['rules'] = array_values($c['route']['rules']);
|
|
|
|
|
|
|
|
|
|
return json_encode($c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -4045,11 +4070,27 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function adguardCheckPswd()
|
|
|
|
|
{
|
|
|
|
|
if (empty($this->getPacConf()['adpswd'])) {
|
|
|
|
|
$this->adguardChangePswd(substr(hash('md5', time()), 0, 10));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function adguardChangePswd($pass)
|
|
|
|
|
{
|
|
|
|
|
$c = yaml_parse_file($this->adguard);
|
|
|
|
|
$c['users'][0]['password'] = password_hash($pass, PASSWORD_DEFAULT);
|
|
|
|
|
yaml_emit_file($this->adguard, $c);
|
|
|
|
|
$p = $this->getPacConf();
|
|
|
|
|
$p['adpswd'] = $pass;
|
|
|
|
|
$this->setPacConf($p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function adguardProtect()
|
|
|
|
|
{
|
|
|
|
|
$h = substr(hash('sha256', $this->key), 0, 8);
|
|
|
|
|
$s = empty($this->getPacConf()['adgbrowser']) ? '' : '#';
|
|
|
|
|
$a = $this->adguardBasicAuth();
|
|
|
|
|
$r = <<<CONF
|
|
|
|
|
location /adguard/ {
|
|
|
|
|
access_log /logs/nginx_adguard_access;
|
|
|
|
@@ -4895,7 +4936,17 @@ DNS-over-HTTPS with IP:
|
|
|
|
|
CURLOPT_POSTFIELDS => $data,
|
|
|
|
|
]);
|
|
|
|
|
$res = curl_exec($ch);
|
|
|
|
|
return json_decode($res, true);
|
|
|
|
|
$r = json_decode($res, true);
|
|
|
|
|
if (!empty($res['description']) || is_null($res)) {
|
|
|
|
|
file_put_contents('/logs/requests_error', var_export([
|
|
|
|
|
'r' => [
|
|
|
|
|
'method' => $method,
|
|
|
|
|
'data' => $data,
|
|
|
|
|
],
|
|
|
|
|
'a' => $res,
|
|
|
|
|
], true) . "\n", FILE_APPEND);
|
|
|
|
|
}
|
|
|
|
|
return $r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function setwebhook()
|
|
|
|
|