Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f0b43e791d | |||
| 0297417a63 | |||
| 7449e8bba3 | |||
| ad7351dc9a | |||
| 5c5c537d62 | |||
| edc877f149 | |||
| ea07b0da42 | |||
| 3d53691106 | |||
| 5f38e73d6b | |||
| bb3a807869 | |||
| 3ed487cbce | |||
| 1d69729bf1 | |||
| 387f1618b1 | |||
| 9da11e2b35 | |||
| 0b95c75005 | |||
| 62c4314beb | |||
| 1dfb3da089 | |||
| 7358730864 | |||
| 57cd1019f5 | |||
| dfbcd67f83 | |||
| 5016c6bda3 | |||
| bc3914c3b9 | |||
| 4675371f19 | |||
| 6efe31d404 |
+2
-1
@@ -21,4 +21,5 @@ update/*
|
||||
|
||||
override.env
|
||||
override.html
|
||||
override.php
|
||||
override.php
|
||||
docker-compose.override.yml
|
||||
+683
-50
@@ -11,6 +11,7 @@ class Bot
|
||||
public $file;
|
||||
public $dns;
|
||||
public $mtu;
|
||||
public $logs;
|
||||
|
||||
public function __construct($key, $i18n)
|
||||
{
|
||||
@@ -28,6 +29,12 @@ class Bot
|
||||
$this->limit = $this->getPacConf()['limitpage'] ?: 5;
|
||||
$this->adguard = '/config/AdGuardHome.yaml';
|
||||
$this->update = '/update/json';
|
||||
$this->logs = [
|
||||
'nginx_default_access',
|
||||
'nginx_domain_access',
|
||||
'upstream_access',
|
||||
'xray',
|
||||
];
|
||||
}
|
||||
|
||||
public function input()
|
||||
@@ -139,9 +146,49 @@ class Bot
|
||||
case preg_match('~^/mirror$~', $this->input['message'], $m):
|
||||
$this->menu('mirror');
|
||||
break;
|
||||
case preg_match('~^/switchBanIp$~', $this->input['callback'], $m):
|
||||
$this->switchBanIp();
|
||||
break;
|
||||
case preg_match('~^/switchScanIp$~', $this->input['callback'], $m):
|
||||
$this->switchScanIp();
|
||||
break;
|
||||
case preg_match('~^/autoScanTimeout$~', $this->input['callback'], $m):
|
||||
$this->autoScanTimeout();
|
||||
break;
|
||||
case preg_match('~^/autoupdate$~', $this->input['message'], $m):
|
||||
$this->autoupdate();
|
||||
break;
|
||||
case preg_match('~^/ports$~', $this->input['callback'], $m):
|
||||
$this->ports();
|
||||
break;
|
||||
case preg_match('~^/ip$~', $this->input['message'], $m):
|
||||
case preg_match('~^/analysisIp$~', $this->input['callback'], $m):
|
||||
$this->analysisIp();
|
||||
break;
|
||||
case preg_match('~^/ipMenu$~', $this->input['callback'], $m):
|
||||
$this->ipMenu();
|
||||
break;
|
||||
case preg_match('~^/cleanDeny(?:\s(\d))?$~', $this->input['callback'], $m):
|
||||
$this->cleanDeny($m[1]);
|
||||
break;
|
||||
case preg_match('~^/denyList (.+?)(?:\s(\d))?$~', $this->input['callback'], $m):
|
||||
$this->denyList($m[1], $m[2] ?: 0);
|
||||
break;
|
||||
case preg_match('~^/cleanLogs (.+?)(?:\s(1))?$~', $this->input['callback'], $m):
|
||||
$this->cleanLogs($m[1], $m[2]);
|
||||
break;
|
||||
case preg_match('~^/allowIp (\d+\.\d+\.\d+\.\d+) (\d+)(?:\s(\d+))?$~', $this->input['callback'], $m):
|
||||
$this->allowIp($m[1], $m[2], $m[3]);
|
||||
break;
|
||||
case preg_match('~^/searchIp (.+)$~', $this->input['callback'], $m):
|
||||
$this->searchIp($m[1]);
|
||||
break;
|
||||
case preg_match('~^/denyIp (.+?)(?:\s(\d)\s(\d+?)\s(\d))?$~', $this->input['callback'], $m):
|
||||
$this->denyIp($m[1], $m[2], $m[3], $m[4]);
|
||||
break;
|
||||
case preg_match('~^/whiteIp (.+?)(?:\s(\d)\s(\d+?)\s(\d))?$~', $this->input['callback'], $m):
|
||||
$this->whiteIp($m[1], $m[2], $m[3], $m[4]);
|
||||
break;
|
||||
case preg_match('~^/adgFillAllowedClients(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
$this->adgFillAllowedClients($m[1] ?: false);
|
||||
break;
|
||||
@@ -181,6 +228,9 @@ class Bot
|
||||
case preg_match('~^/exportList (\w+)$~', $this->input['callback'], $m):
|
||||
$this->exportList($m[1]);
|
||||
break;
|
||||
case preg_match('~^/hidePort (\w+)$~', $this->input['callback'], $m):
|
||||
$this->hidePort($m[1]);
|
||||
break;
|
||||
case preg_match('~^/deleteYes (\w+)$~', $this->input['callback'], $m):
|
||||
$this->deleteYes($m[1]);
|
||||
break;
|
||||
@@ -193,6 +243,9 @@ class Bot
|
||||
case preg_match('~^/applyupdatebot$~', $this->input['callback'], $m):
|
||||
$this->applyupdatebot();
|
||||
break;
|
||||
case preg_match('~^/restart$~', $this->input['callback'], $m):
|
||||
$this->restart();
|
||||
break;
|
||||
case preg_match('~^/branches$~', $this->input['callback'], $m):
|
||||
$this->branches();
|
||||
break;
|
||||
@@ -211,6 +264,9 @@ class Bot
|
||||
case preg_match('~^/clearLog (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->clearLog(...explode('_', $m['arg']));
|
||||
break;
|
||||
case preg_match('~^/cleanLog$~', $this->input['callback'], $m):
|
||||
$this->cleanLog();
|
||||
break;
|
||||
case preg_match('~^/delLog (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->delLog(...explode('_', $m['arg']));
|
||||
break;
|
||||
@@ -582,6 +638,7 @@ class Bot
|
||||
public function restartXray($c)
|
||||
{
|
||||
$c['inbounds'][0]['settings']['clients'] = array_values($c['inbounds'][0]['settings']['clients']);
|
||||
$c['log']['access'] = '/logs/xray';
|
||||
$this->ssh('pkill xray', 'xr');
|
||||
file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
$this->ssh('xray run -config /xray.json > /dev/null 2>&1 &', 'xr');
|
||||
@@ -1088,10 +1145,55 @@ class Bot
|
||||
$this->checkVersion();
|
||||
$this->checkBackup($period);
|
||||
$this->checkCert();
|
||||
$this->autoAnalyzeLogs();
|
||||
sleep($period);
|
||||
}
|
||||
}
|
||||
|
||||
public function autoAnalyzeLogs()
|
||||
{
|
||||
try {
|
||||
$pac = $this->getPacConf();
|
||||
if (!empty($pac['autoscan'])) {
|
||||
$r = $this->analysisIp(1);
|
||||
require __DIR__ . '/config.php';
|
||||
if (!empty($c['admin']) && (empty($this->time3) || ((time() - $this->time3) > $pac['autoscan_timeout']))) {
|
||||
$this->time3 = time();
|
||||
if (!empty($r)) {
|
||||
foreach ($r as $k => $v) {
|
||||
$tmp = array_unique($v);
|
||||
foreach ($tmp as $i) {
|
||||
$t[$i]++;
|
||||
}
|
||||
}
|
||||
foreach ($t as $k => $v) {
|
||||
$text .= "\n$v $k";
|
||||
}
|
||||
if (!empty($pac['autodeny'])) {
|
||||
$this->denyIp(array_keys($r));
|
||||
$ban = count(array_keys($r));
|
||||
foreach (array_keys($r) as $v) {
|
||||
$ips[] = [[
|
||||
'text' => "logs $v",
|
||||
'callback_data' => "/searchIp $v",
|
||||
]];
|
||||
}
|
||||
}
|
||||
foreach ($c['admin'] as $k => $v) {
|
||||
$this->send($v, "suspicious ips found: $text" . ($ban ? "\nbanned:$ban" : ''), button: $ips ?: [[
|
||||
[
|
||||
'text' => $this->i18n('analyze'),
|
||||
'callback_data' => '/analysisIp',
|
||||
],
|
||||
]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
public function checkBackup($delta)
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
@@ -2079,10 +2181,12 @@ class Bot
|
||||
public function adguardSync()
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
$pac['adpswd'] = $pac['adpswd'] ?: substr(hash('md5', time()), 0, 10);
|
||||
$this->setPacConf($pac);
|
||||
$ssl = $this->nginxGetTypeCert();
|
||||
$c = yaml_parse_file($this->adguard);
|
||||
$this->stopAd();
|
||||
$c['users'][0]['password'] = $pac['adpswd'] ?: password_hash(substr(hash('md5', time()), 0, 10), PASSWORD_DEFAULT);
|
||||
$c['users'][0]['password'] = password_hash($pac['adpswd'], PASSWORD_DEFAULT);
|
||||
if (!empty($ssl) && !empty($pac['domain']) && empty($c['tls']['enabled'])) {
|
||||
$c['tls']['enabled'] = true;
|
||||
$c['tls']['server_name'] = $pac['domain'];
|
||||
@@ -3934,7 +4038,7 @@ DNS-over-HTTPS with IP:
|
||||
public function menu($type = false, $arg = false, $return = false)
|
||||
{
|
||||
$domain = $this->getPacConf()['domain'] ?: $this->ip;
|
||||
$cron = exec('pgrep -f cron.php');
|
||||
$cron = $this->ssh('pgrep -f cron.php', 'service');
|
||||
$menu = [
|
||||
'main' => [
|
||||
'text' => 'v' . getenv('VER') . ($this->dontshowcron ? '' : "\ncron: " . $this->i18n($cron ? 'on' : 'off') . ($cron ? '' : ' show <code>logs/php_error</code>')),
|
||||
@@ -3989,6 +4093,12 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/pacMenu 0",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('IP ban'),
|
||||
'callback_data' => "/ipMenu",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('config'),
|
||||
@@ -3998,7 +4108,7 @@ DNS-over-HTTPS with IP:
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('chat'),
|
||||
'url' => "https://t.me/+BYuWVd36cZYwNTMy",
|
||||
'url' => "https://t.me/+Wfxg6-nrokBlMmYy",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('donate'),
|
||||
@@ -4009,18 +4119,18 @@ DNS-over-HTTPS with IP:
|
||||
],
|
||||
],
|
||||
],
|
||||
'wg' => $type == 'wg' ? $this->statusWg($arg) : false,
|
||||
'wg' => $type == 'wg' ? $this->statusWg($arg) : false,
|
||||
'client' => $type == 'client' ? $this->getClient(...explode('_', $arg)) : false,
|
||||
'addpeer' => $type == 'addpeer' ? $this->addWg(...explode('_', $arg)) : false,
|
||||
'pac' => $type == 'pac' ? $this->pacMenu($arg) : false,
|
||||
'adguard' => $type == 'adguard' ? $this->adguardMenu() : false,
|
||||
'config' => $type == 'config' ? $this->configMenu() : false,
|
||||
'ss' => $type == 'ss' ? $this->menuSS() : false,
|
||||
'lang' => $type == 'lang' ? $this->menuLang() : false,
|
||||
'oc' => $type == 'oc' ? $this->ocMenu() : false,
|
||||
'naive' => $type == 'naive' ? $this->naiveMenu() : false,
|
||||
'mirror' => $type == 'mirror' ? $this->mirrorMenu() : false,
|
||||
'update' => $type == 'update' ? $this->updatebot() : false,
|
||||
'addpeer' => $type == 'addpeer' ? $this->addWg(...explode('_', $arg)) : false,
|
||||
'pac' => $type == 'pac' ? $this->pacMenu($arg) : false,
|
||||
'adguard' => $type == 'adguard' ? $this->adguardMenu() : false,
|
||||
'config' => $type == 'config' ? $this->configMenu() : false,
|
||||
'ss' => $type == 'ss' ? $this->menuSS() : false,
|
||||
'lang' => $type == 'lang' ? $this->menuLang() : false,
|
||||
'oc' => $type == 'oc' ? $this->ocMenu() : false,
|
||||
'naive' => $type == 'naive' ? $this->naiveMenu() : false,
|
||||
'mirror' => $type == 'mirror' ? $this->mirrorMenu() : false,
|
||||
'update' => $type == 'update' ? $this->updatebot() : false,
|
||||
];
|
||||
|
||||
$text = $menu[$type ?: 'main' ]['text'];
|
||||
@@ -4047,6 +4157,391 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
}
|
||||
|
||||
public function switchScanIp()
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
$c['autoscan'] = $c['autoscan'] ? 0 : 1;
|
||||
$this->setPacConf($c);
|
||||
$this->ipMenu();
|
||||
}
|
||||
|
||||
public function switchBanIp()
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
$c['autodeny'] = $c['autodeny'] ? 0 : 1;
|
||||
$this->setPacConf($c);
|
||||
$this->ipMenu();
|
||||
}
|
||||
|
||||
public function ipMenu()
|
||||
{
|
||||
$text = 'Menu -> IP';
|
||||
$pac = $this->getPacConf();
|
||||
$d = count($pac['deny'] ?: []);
|
||||
$w = count($pac['white'] ?: []);
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('autoscan') . ': ' . ($pac['autoscan'] ? $this->getTime(strtotime(($pac['autoscan_timeout'] ?: 3600) . ' seconds')) : $this->i18n('off')),
|
||||
'callback_data' => '/autoScanTimeout',
|
||||
],
|
||||
];
|
||||
if (!empty($pac['autoscan'])) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('autodeny') . ': ' . $this->i18n($pac['autodeny'] ? 'on' : 'off'),
|
||||
'callback_data' => '/switchBanIp',
|
||||
],
|
||||
];
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('allow list') . ": $w",
|
||||
'callback_data' => '/denyList 0 1',
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('deny list') . ": $d",
|
||||
'callback_data' => '/denyList 0 0',
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('analyze'),
|
||||
'callback_data' => '/analysisIp',
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/menu",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
$this->input['chat'],
|
||||
$this->input['message_id'],
|
||||
$text,
|
||||
$data ?: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function analysisIp($return = false)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
foreach (array_merge($pac['white'] ?: [], $pac['deny'] ?: [], ['10.10.0.10']) as $v) {
|
||||
$xr[$v] = true;
|
||||
}
|
||||
if ($r = fopen('/logs/nginx_tlgrm_access', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+)~', $l, $m)) {
|
||||
$xr[$m[1]] = true;
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
if ($r = fopen('/logs/xray', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+)(?=.+accepted)~', $l, $m)) {
|
||||
$xr[$m[1]] = true;
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
|
||||
if ($r = fopen('/logs/upstream_access', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+).+200\s\d+\s0$~', $l, $m)) {
|
||||
if (empty($xr[$m[1]])) {
|
||||
$ip[$m[1]][] = 'possibly a Reality Degenerate';
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
|
||||
$reg = [
|
||||
'GET /ws.+ HTTP',
|
||||
'GET /adguard/.+ HTTP',
|
||||
'GET /webapp.+ HTTP',
|
||||
'GET /pac.+ HTTP',
|
||||
'GET \.well-known.+ HTTP',
|
||||
'GET /v2ray.+ HTTP',
|
||||
'GET /dns-query.+ HTTP',
|
||||
'GET / HTTP',
|
||||
'GET /tlgrm.+ HTTP',
|
||||
'GET /jsoneditor.min.css HTTP',
|
||||
'GET /jsoneditor.min.js HTTP',
|
||||
'GET /jquery-3.7.1.min.js HTTP',
|
||||
'GET /img/jsoneditor-icons.svg HTTP',
|
||||
'GET /favicon.ico HTTP',
|
||||
];
|
||||
|
||||
if ($r = fopen('/logs/nginx_default_access', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (!preg_match('~' . implode('|', $reg) . '~', $l)) {
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+)~', $l, $m)) {
|
||||
if (empty($xr[$m[1]])) {
|
||||
$ip[$m[1]][] = 'possibly a scanner';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
|
||||
if ($r = fopen('/logs/nginx_domain_access', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (!preg_match('~' . implode('|', $reg) . '~', $l)) {
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+)~', $l, $m)) {
|
||||
if (empty($xr[$m[1]])) {
|
||||
$ip[$m[1]][] = 'possibly a scanner';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
if (!empty($ip)) {
|
||||
foreach ($ip as $k => $v) {
|
||||
if ($i > 10) {
|
||||
break;
|
||||
}
|
||||
$comment = implode(', ', array_unique($v));
|
||||
if (!empty($return)) {
|
||||
$ret[$k] = $v;
|
||||
} else {
|
||||
$this->send($this->input['from'], "$k $comment\n", button: [[
|
||||
[
|
||||
'text' => $this->i18n('deny'),
|
||||
'callback_data' => "/denyIp $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('allow'),
|
||||
'callback_data' => "/whiteIp $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('logs'),
|
||||
'callback_data' => "/searchIp $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('clean logs'),
|
||||
'callback_data' => "/cleanLogs $k",
|
||||
],
|
||||
]]);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
if (!empty($return)) {
|
||||
return $ret;
|
||||
}
|
||||
} else {
|
||||
$this->answer($this->input['callback_id'], 'empty');
|
||||
}
|
||||
}
|
||||
|
||||
public function searchIp($ip)
|
||||
{
|
||||
foreach ($this->logs as $v) {
|
||||
if ($r = fopen("/logs/$v", 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (preg_match('~' . preg_quote($ip) . '~', $l)) {
|
||||
$res[$v][] = $l;
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
}
|
||||
if (!empty($res)) {
|
||||
foreach ($res as $k => $v) {
|
||||
$head= "$k:\n";
|
||||
$t = array_chunk($v, 10);
|
||||
foreach ($t as $j) {
|
||||
$text = "$head<pre>";
|
||||
foreach ($j as $i) {
|
||||
$text .= htmlspecialchars($i, ENT_HTML5, 'UTF-8');
|
||||
}
|
||||
$text .= '</pre>';
|
||||
$this->send($this->input['from'], $text, $this->input['message_id']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->answer($this->input['callback_id'], 'empty');
|
||||
}
|
||||
}
|
||||
|
||||
public function denyList($page = 0, $white = 0)
|
||||
{
|
||||
$text = 'Menu -> IP -> ' . ($white ? 'white' : 'deny') . ' list';
|
||||
$domains = $this->getPacConf()[$white ? 'white' : 'deny'] ?: [];
|
||||
$all = (int) ceil(count($domains) / $this->limit);
|
||||
$page = min($page, $all - 1);
|
||||
$page = $page < 0 ? $all - 1 : $page;
|
||||
|
||||
if (!empty($domains)) {
|
||||
foreach (array_slice($domains, $page * $this->limit, $this->limit) as $v) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('delete') . " $v",
|
||||
'callback_data' => "/allowIp $v $page" . ($white ? " 1" : ''),
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n($white ? 'deny' : 'allow'),
|
||||
'callback_data' => ($white ? "/denyIp" : "/whiteIp") . " $v 1 $page $white",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('logs'),
|
||||
'callback_data' => "/searchIp $v",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('clean logs'),
|
||||
'callback_data' => "/cleanLogs $v 1",
|
||||
],
|
||||
];
|
||||
}
|
||||
if ($all > 1) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => '<<',
|
||||
'callback_data' => "/denyList " . ($page - 1 >= 0 ? $page - 1 : $all - 1) . ($white ? " 1" : ' 0'),
|
||||
],
|
||||
[
|
||||
'text' => '>>',
|
||||
'callback_data' => "/denyList " . ($page < $all - 1 ? $page + 1 : 0) . ($white ? " 1" : ' 0'),
|
||||
]
|
||||
];
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('delete all'),
|
||||
'callback_data' => "/cleanDeny" . ($white ? " 1" : ''),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/ipMenu",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
$this->input['chat'],
|
||||
$this->input['message_id'],
|
||||
$text,
|
||||
$data ?: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function cleanDeny($white = 0)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
unset($pac[$white ? 'white' : 'deny']);
|
||||
$this->setPacConf($pac);
|
||||
$this->syncDeny();
|
||||
$this->ipMenu();
|
||||
}
|
||||
|
||||
public function denyIp($ip, $nodelete = false, $page = 0, $white = 0)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
if (is_array($ip)) {
|
||||
foreach ($ip as $v) {
|
||||
$pac['deny'][] = $v;
|
||||
if (($t = array_search($v, $pac['white'] ?: [])) !== false) {
|
||||
unset($pac['white'][$t]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$pac['deny'][] = $ip;
|
||||
if (($t = array_search($ip, $pac['white'] ?: [])) !== false) {
|
||||
unset($pac['white'][$t]);
|
||||
}
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
if (empty($nodelete)) {
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
$this->syncDeny();
|
||||
if (!empty($nodelete)) {
|
||||
$this->denyList($page, $white);
|
||||
}
|
||||
}
|
||||
|
||||
public function whiteIp($ip, $nodelete = false, $page = 0, $white = 0)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
if (is_array($ip)) {
|
||||
foreach ($ip as $v) {
|
||||
$pac['white'][] = $v;
|
||||
if (($t = array_search($v, $pac['deny'] ?: [])) !== false) {
|
||||
unset($pac['deny'][$t]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$pac['white'][] = $ip;
|
||||
if (($t = array_search($ip, $pac['deny'] ?: [])) !== false) {
|
||||
unset($pac['deny'][$t]);
|
||||
}
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
if (empty($nodelete)) {
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
$this->syncDeny();
|
||||
if (!empty($nodelete)) {
|
||||
$this->denyList($page, $white);
|
||||
}
|
||||
}
|
||||
|
||||
public function allowIp($ip, $page, $white = 0)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
unset($pac[$white ? 'white' : 'deny'][array_search($ip, $pac[$white ? 'white' : 'deny'])]);
|
||||
$this->setPacConf($pac);
|
||||
$this->syncDeny();
|
||||
$this->denyList($page, $white);
|
||||
}
|
||||
|
||||
public function cleanLogs($ip, $nodelete = false)
|
||||
{
|
||||
foreach ($this->logs as $v) {
|
||||
exec("sed -i '/$ip/d' /logs/$v");
|
||||
}
|
||||
if (empty($nodelete)) {
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
}
|
||||
|
||||
public function syncDeny()
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
if (!empty($pac['white'])) {
|
||||
$pac['white'] = array_unique($pac['white']);
|
||||
sort($pac['white']);
|
||||
foreach ($pac['white'] as $v) {
|
||||
$text .= "allow $v;\n";
|
||||
}
|
||||
}
|
||||
if (!empty($pac['deny'])) {
|
||||
$pac['deny'] = array_unique($pac['deny']);
|
||||
sort($pac['deny']);
|
||||
foreach ($pac['deny'] as $v) {
|
||||
$text .= "deny $v;\n";
|
||||
}
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
file_put_contents('/config/deny', $text ?: '');
|
||||
$this->ssh('nginx -s reload', 'up');
|
||||
}
|
||||
|
||||
public function linkXray($i, $s = false)
|
||||
{
|
||||
$c = $this->getXray();
|
||||
@@ -4417,6 +4912,36 @@ DNS-over-HTTPS with IP:
|
||||
];
|
||||
}
|
||||
|
||||
public function autoScanTimeout()
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
"@{$this->input['username']} send time:",
|
||||
$this->input['message_id'],
|
||||
reply: 'send time:',
|
||||
);
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
'start_callback' => $this->input['callback_id'],
|
||||
'callback' => 'setAutoScanTimeout',
|
||||
'args' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function setAutoScanTimeout($time)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
if (empty($time)) {
|
||||
unset($pac['autoscan_timeout']);
|
||||
unset($pac['autoscan']);
|
||||
} else {
|
||||
$pac['autoscan_timeout'] = strtotime($time, 0);
|
||||
$pac['autoscan'] = 1;
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
$this->ipMenu();
|
||||
}
|
||||
|
||||
public function templateCopy($type)
|
||||
{
|
||||
$r = $this->send(
|
||||
@@ -4462,7 +4987,7 @@ DNS-over-HTTPS with IP:
|
||||
$pac = $this->getPacConf();
|
||||
switch ($name) {
|
||||
case 'origin':
|
||||
file_put_contents("/config/$type.json", $json);
|
||||
file_put_contents("/config/$type.json", json_encode(json_decode($json, true), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -4716,6 +5241,7 @@ DNS-over-HTTPS with IP:
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . ' -> routes';
|
||||
|
||||
$p = $this->getPacConf();
|
||||
$outbound = $p['outbound'] ?: 'proxy';
|
||||
|
||||
$data = [
|
||||
[[
|
||||
@@ -4731,19 +5257,19 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/xtlsrulesset",
|
||||
]],
|
||||
[[
|
||||
'text' => 'domains: ' . ($p['domains_outbound'] ? 'direct' : 'proxy'),
|
||||
'text' => 'domains: ' . ($p['domains_outbound'] ? 'direct' : $outbound),
|
||||
'callback_data' => "/xtlsproxy",
|
||||
]],
|
||||
[[
|
||||
'text' => 'process: ' . ($p['process_outbound'] ? 'direct' : 'proxy'),
|
||||
'text' => 'process: ' . ($p['process_outbound'] ? 'direct' : $outbound),
|
||||
'callback_data' => "/xtlsprocess",
|
||||
]],
|
||||
[[
|
||||
'text' => 'package: ' . ($p['app_outbound'] ? 'direct' : 'proxy'),
|
||||
'text' => 'package: ' . ($p['app_outbound'] ? 'direct' : $outbound),
|
||||
'callback_data' => "/xtlsapp",
|
||||
]],
|
||||
[[
|
||||
'text' => 'final: ' . ($p['final_outbound'] ? 'proxy' : 'direct'),
|
||||
'text' => 'final: ' . ($p['final_outbound'] ? $outbound : 'direct'),
|
||||
'callback_data' => "/finalOutbound",
|
||||
]],
|
||||
];
|
||||
@@ -5112,15 +5638,26 @@ DNS-over-HTTPS with IP:
|
||||
break;
|
||||
}
|
||||
|
||||
$outbound = $pac['outbound'] ?: 'proxy';
|
||||
$c = json_decode($this->replaceTags(json_encode($c), [
|
||||
'~outbound~' => $outbound,
|
||||
]), true);
|
||||
foreach ($c['outbounds'] as $k => $v) {
|
||||
if ($v['tag'] == $outbound) {
|
||||
$index = $k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($_GET['t']) {
|
||||
case 's':
|
||||
$c['outbounds'][0]['settings']['vnext'][0]['address'] = '~domain~';
|
||||
$c['outbounds'][0]['settings']['vnext'][0]['users'][0] = [
|
||||
$c['outbounds'][$index]['settings']['vnext'][0]['address'] = '~domain~';
|
||||
$c['outbounds'][$index]['settings']['vnext'][0]['users'][0] = [
|
||||
'id' => '~uid~',
|
||||
'encryption' => 'none',
|
||||
];
|
||||
if ($pac['transport'] == 'Websocket') {
|
||||
$c['outbounds'][0]['streamSettings'] = [
|
||||
$c['outbounds'][$index]['streamSettings'] = [
|
||||
"network" => "ws",
|
||||
"security" => "tls",
|
||||
"wsSettings" => [
|
||||
@@ -5132,10 +5669,10 @@ DNS-over-HTTPS with IP:
|
||||
"fingerprint" => "chrome"
|
||||
]
|
||||
];
|
||||
unset($c['outbounds'][0]['mux']);
|
||||
unset($c['outbounds'][$index]['mux']);
|
||||
} else {
|
||||
$c['outbounds'][0]['settings']['vnext'][0]['users'][0]["flow"] = "xtls-rprx-vision";
|
||||
$c['outbounds'][0]['streamSettings'] = [
|
||||
$c['outbounds'][$index]['settings']['vnext'][0]['users'][0]["flow"] = "xtls-rprx-vision";
|
||||
$c['outbounds'][$index]['streamSettings'] = [
|
||||
"network" => "tcp",
|
||||
"security" => "reality",
|
||||
"realitySettings" => [
|
||||
@@ -5145,29 +5682,29 @@ DNS-over-HTTPS with IP:
|
||||
"shortId" => '~short_id~',
|
||||
]
|
||||
];
|
||||
$c['outbounds'][0]['mux'] = [
|
||||
$c['outbounds'][$index]['mux'] = [
|
||||
"enabled" => false,
|
||||
"concurrency" => -1
|
||||
];
|
||||
}
|
||||
break;
|
||||
case 'si':
|
||||
$c['outbounds'][0]['server'] = '~domain~';
|
||||
$c['outbounds'][0]['uuid'] = '~uid~';
|
||||
$c['outbounds'][$index]['server'] = '~domain~';
|
||||
$c['outbounds'][$index]['uuid'] = '~uid~';
|
||||
if ($pac['transport'] == 'Websocket') {
|
||||
unset($c['outbounds'][0]['tls']['reality']);
|
||||
unset($c['outbounds'][0]['flow']);
|
||||
$c['outbounds'][0]["transport"] = [
|
||||
unset($c['outbounds'][$index]['tls']['reality']);
|
||||
unset($c['outbounds'][$index]['flow']);
|
||||
$c['outbounds'][$index]["transport"] = [
|
||||
"type" => "ws",
|
||||
"path" => "/ws"
|
||||
];
|
||||
$c['outbounds'][0]['tls']['server_name'] = '~domain~';
|
||||
$c['outbounds'][$index]['tls']['server_name'] = '~domain~';
|
||||
} else {
|
||||
unset($c['outbounds'][0]["transport"]);
|
||||
$c['outbounds'][0]['flow'] = 'xtls-rprx-vision';
|
||||
$c['outbounds'][0]['tls']['reality']['public_key'] = '~public_key~';
|
||||
$c['outbounds'][0]['tls']['server_name'] = '~server_name~';
|
||||
$c['outbounds'][0]['tls']['reality']['short_id'] = '~short_id~';
|
||||
unset($c['outbounds'][$index]["transport"]);
|
||||
$c['outbounds'][$index]['flow'] = 'xtls-rprx-vision';
|
||||
$c['outbounds'][$index]['tls']['reality']['public_key'] = '~public_key~';
|
||||
$c['outbounds'][$index]['tls']['server_name'] = '~server_name~';
|
||||
$c['outbounds'][$index]['tls']['reality']['short_id'] = '~short_id~';
|
||||
}
|
||||
|
||||
$c['route'] = $this->addRuleSet($c['route']);
|
||||
@@ -5183,10 +5720,11 @@ DNS-over-HTTPS with IP:
|
||||
'~short_id~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0],
|
||||
'~public_key~' => $pac['xray'],
|
||||
'~server_name~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0],
|
||||
'~app_outbound~' => $pac['app_outbound'] ? 'direct' : 'proxy',
|
||||
'~process_outbound~' => $pac['process_outbound'] ? 'direct' : 'proxy',
|
||||
'~domains_outbound~' => $pac['domains_outbound'] ? 'direct' : 'proxy',
|
||||
'~final_outbound~' => $pac['final_outbound'] ? 'proxy' : 'direct',
|
||||
'~app_outbound~' => $pac['app_outbound'] ? 'direct' : $outbound,
|
||||
'~process_outbound~' => $pac['process_outbound'] ? 'direct' : $outbound,
|
||||
'~domains_outbound~' => $pac['domains_outbound'] ? 'direct' : $outbound,
|
||||
'~final_outbound~' => $pac['final_outbound'] ? $outbound : 'direct',
|
||||
'~ip~' => $this->ip,
|
||||
]);
|
||||
$json = $this->clearEmptyRules($json);
|
||||
|
||||
@@ -5468,7 +6006,7 @@ DNS-over-HTTPS with IP:
|
||||
$text .= "DNS over HTTPS:\n<code>$ip</code>\n<code>$scheme://$domain/dns-query" . ($conf['adguardkey'] ? "/{$conf['adguardkey']}" : '') . "</code>\n\n";
|
||||
$text .= "DNS over TLS:\n<code>tls://" . ($conf['adguardkey'] ? "{$conf['adguardkey']}." : '') . "$domain</code>";
|
||||
}
|
||||
$status = $this->i18n(exec("JSON=1 dnslookup google.com ad") ? 'on' : 'off');
|
||||
$status = $this->i18n(exec("JSON=1 timeout 2 dnslookup google.com ad") ? 'on' : 'off');
|
||||
$safesearch = yaml_parse_file($this->adguard)['filtering']['safe_search']['enabled'];
|
||||
$text .= "\n\nstatus: $status\t\tsafesearch: " . $this->i18n($safesearch ? 'on' : 'off');
|
||||
$allowedClients = yaml_parse_file($this->adguard)['dns']['allowed_clients'];
|
||||
@@ -5563,8 +6101,8 @@ DNS-over-HTTPS with IP:
|
||||
} else {
|
||||
$c['dns']['allowed_clients'] = [];
|
||||
$c['dns']['allowed_clients'][] = '10.10.0.0/24';
|
||||
if (!empty($pac['adguardKey'])) {
|
||||
$c['dns']['allowed_clients'][] = $pac['adguardKey'];
|
||||
if (!empty($pac['adguardkey'])) {
|
||||
$c['dns']['allowed_clients'][] = $pac['adguardkey'];
|
||||
}
|
||||
$c['dns']['allowed_clients'][] = getenv('WGADDRESS');
|
||||
$c['dns']['allowed_clients'][] = getenv('WG1ADDRESS');
|
||||
@@ -5675,6 +6213,20 @@ DNS-over-HTTPS with IP:
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
|
||||
public function restart()
|
||||
{
|
||||
$r = $this->send($this->input['from'], 'restart...');
|
||||
file_put_contents('/update/reload_message', "{$this->input['from']}:{$r['result']['message_id']}");
|
||||
file_put_contents('/update/key', $this->key);
|
||||
file_put_contents('/update/curl', json_encode([
|
||||
'chat_id' => $this->input['chat'],
|
||||
'message_id' => $r['result']['message_id'],
|
||||
'text' => '~t~'
|
||||
], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
file_put_contents('/update/pipe', '2');
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
|
||||
public function configMenu()
|
||||
{
|
||||
exec('git -C / fetch');
|
||||
@@ -5802,6 +6354,10 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $this->i18n('fake html'),
|
||||
'callback_data' => "/addOverrideHtml",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('ports'),
|
||||
'callback_data' => "/ports",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
@@ -5818,6 +6374,10 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $this->i18n(exec('git -C / rev-list --count HEAD..@{u}') ? 'have updates' : 'no updates'),
|
||||
'callback_data' => "/menu update",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('restart'),
|
||||
'callback_data' => "/restart",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
@@ -5831,6 +6391,69 @@ DNS-over-HTTPS with IP:
|
||||
];
|
||||
}
|
||||
|
||||
public function ports()
|
||||
{
|
||||
$text[] = 'Settings -> Ports';
|
||||
$f = '/docker/compose';
|
||||
$c = yaml_parse_file($f)['services'];
|
||||
$data = [
|
||||
[[
|
||||
'text' => 'Letsencrypt 80 ' . $this->i18n($c['ng'] ? 'off' : 'on'),
|
||||
'callback_data' => "/hidePort ng",
|
||||
]],
|
||||
[[
|
||||
'text' => 'Shadowsocks ' . getenv('SSPORT') . ' ' . $this->i18n($c['ss'] ? 'off' : 'on'),
|
||||
'callback_data' => "/hidePort ss",
|
||||
]],
|
||||
[[
|
||||
'text' => 'DoT 853 ' . $this->i18n($c['ad'] ? 'off' : 'on'),
|
||||
'callback_data' => "/hidePort ad",
|
||||
]],
|
||||
[[
|
||||
'text' => 'Wireguard-1 ' . getenv('WGPORT') . ' ' . $this->i18n($c['wg'] ? 'off' : 'on'),
|
||||
'callback_data' => "/hidePort wg",
|
||||
]],
|
||||
[[
|
||||
'text' => 'Wireguard-2 ' . getenv('WG1PORT') . ' ' . $this->i18n($c['wg1'] ? 'off' : 'on'),
|
||||
'callback_data' => "/hidePort wg1",
|
||||
]],
|
||||
[[
|
||||
'text' => 'MTProto ' . getenv('TGPORT') . ' ' . $this->i18n($c['tg'] ? 'off' : 'on'),
|
||||
'callback_data' => "/hidePort tg",
|
||||
]],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/menu config",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
$this->input['chat'],
|
||||
$this->input['message_id'],
|
||||
implode("\n", $text ?: ['...']),
|
||||
$data ?: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function hidePort($container)
|
||||
{
|
||||
$f = '/docker/compose';
|
||||
$c = yaml_parse_file($f);
|
||||
if (!empty($c['services'][$container])) {
|
||||
unset($c['services'][$container]);
|
||||
} else {
|
||||
$c['services'][$container]['ports'] = [];
|
||||
}
|
||||
if (empty($c['services'])) {
|
||||
file_put_contents($f, '');
|
||||
} else {
|
||||
yaml_emit_file($f, $c);
|
||||
file_put_contents($f, str_replace('ports:', 'ports: !override', file_get_contents($f)));
|
||||
}
|
||||
$this->ports();
|
||||
}
|
||||
|
||||
public function branches()
|
||||
{
|
||||
exec('git -C / branch -r', $m);
|
||||
@@ -5871,20 +6494,22 @@ DNS-over-HTTPS with IP:
|
||||
$size = filesize("/logs/$v");
|
||||
$data[] = [
|
||||
[
|
||||
'text' => "$v ($size)",
|
||||
'text' => "$size $v",
|
||||
'callback_data' => "/getLog $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('clear'),
|
||||
'text' => $this->i18n('clean'),
|
||||
'callback_data' => "/clearLog $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('delete'),
|
||||
'callback_data' => "/delLog $k",
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('clean all'),
|
||||
'callback_data' => "/cleanLog",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
@@ -5923,6 +6548,14 @@ DNS-over-HTTPS with IP:
|
||||
$this->logs();
|
||||
}
|
||||
|
||||
public function cleanLog()
|
||||
{
|
||||
foreach (scandir('/logs/') as $k => $v) {
|
||||
file_put_contents("/logs/$v", '');
|
||||
}
|
||||
$this->logs();
|
||||
}
|
||||
|
||||
public function delLog($i)
|
||||
{
|
||||
foreach (scandir('/logs/') as $k => $v) {
|
||||
|
||||
@@ -353,4 +353,24 @@ $i = [
|
||||
'en' => 'delete allowed clients',
|
||||
'ru' => 'очистить белый список клиентов',
|
||||
],
|
||||
'success' => [
|
||||
'en' => 'success',
|
||||
'ru' => 'сохранено',
|
||||
],
|
||||
'error' => [
|
||||
'en' => 'error',
|
||||
'ru' => 'ошибка',
|
||||
],
|
||||
'save' => [
|
||||
'en' => 'save',
|
||||
'ru' => 'сохранить',
|
||||
],
|
||||
'copy' => [
|
||||
'en' => 'copy',
|
||||
'ru' => 'копировать',
|
||||
],
|
||||
'restart' => [
|
||||
'en' => 'restart',
|
||||
'ru' => 'перезагрузка',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -20,4 +20,5 @@ if (!empty($bot->selfupdate)) {
|
||||
$bot->dontshowcron = 1;
|
||||
$bot->adguardSync();
|
||||
$bot->sslip();
|
||||
$bot->syncDeny();
|
||||
$bot->cleanDocker();
|
||||
|
||||
+2
-2
@@ -87,7 +87,7 @@
|
||||
"uuid": "~uid~",
|
||||
"type": "vless",
|
||||
"domain_strategy": "ipv4_only",
|
||||
"tag": "proxy"
|
||||
"tag": "~outbound~"
|
||||
},
|
||||
{
|
||||
"type": "direct",
|
||||
@@ -178,7 +178,7 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"outbound": "proxy"
|
||||
"outbound": "~outbound~"
|
||||
},
|
||||
{
|
||||
"outbound": "direct"
|
||||
|
||||
@@ -11,6 +11,11 @@ events {
|
||||
}
|
||||
|
||||
stream {
|
||||
include /etc/nginx/deny;
|
||||
log_format basic '$remote_addr [$time_local] '
|
||||
'$protocol $status $bytes_sent $bytes_received';
|
||||
access_log /logs/upstream_access basic;
|
||||
|
||||
upstream other {
|
||||
server ng:443;
|
||||
}
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@
|
||||
}
|
||||
}],
|
||||
"outbounds": [{
|
||||
"tag": "proxy",
|
||||
"tag": "~outbound~",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [{
|
||||
@@ -84,7 +84,7 @@
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [{
|
||||
"type": "field",
|
||||
"outboundTag": "proxy",
|
||||
"outboundTag": "~outbound~",
|
||||
"domain": "~pac~"
|
||||
}, {
|
||||
"type": "field",
|
||||
|
||||
+2
-1
@@ -42,7 +42,8 @@
|
||||
}
|
||||
],
|
||||
"log": {
|
||||
"loglevel": "info"
|
||||
"loglevel": "info",
|
||||
"access": "/logs/xray"
|
||||
},
|
||||
"outbounds": [
|
||||
{
|
||||
|
||||
+5
-2
@@ -29,6 +29,7 @@ services:
|
||||
volumes:
|
||||
- ./config/.profile:/root/.ashrc:ro
|
||||
- ./config/upstream.conf:/etc/nginx/nginx.conf
|
||||
- ./config/deny:/etc/nginx/deny
|
||||
- ./scripts/start_upstream.sh:/start_upstream.sh
|
||||
- ./ssh:/ssh
|
||||
- ./config/sshd_config:/etc/ssh/sshd_config
|
||||
@@ -95,7 +96,7 @@ services:
|
||||
ipv4_address: 10.10.1.2
|
||||
logging: *default-logging
|
||||
php:
|
||||
image: mercurykd/vpnbot-php:1.5
|
||||
image: mercurykd/vpnbot-php:1.6
|
||||
build:
|
||||
dockerfile: dockerfile/php.dockerfile
|
||||
args:
|
||||
@@ -118,6 +119,7 @@ services:
|
||||
- ./update:/update
|
||||
- ./.git:/.git
|
||||
- ./singbox_windows:/singbox
|
||||
- ./docker-compose.override.yml:/docker/compose
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
IP: ${IP}
|
||||
@@ -145,7 +147,7 @@ services:
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
service:
|
||||
image: mercurykd/vpnbot-php:1.5
|
||||
image: mercurykd/vpnbot-php:1.6
|
||||
build:
|
||||
dockerfile: dockerfile/php.dockerfile
|
||||
args:
|
||||
@@ -412,6 +414,7 @@ services:
|
||||
- ./config/sshd_config:/etc/ssh/sshd_config
|
||||
- ./config/xray.json:/xray.json
|
||||
- ./scripts/start_xray.sh:/start_xray.sh
|
||||
- ./logs:/logs
|
||||
hostname: xray
|
||||
container_name: xray-${VER}
|
||||
depends_on:
|
||||
|
||||
@@ -32,4 +32,6 @@ RUN apk add --no-cache --update php81 \
|
||||
&& mv sing-box-1.8.11-linux-amd64/sing-box /usr/bin \
|
||||
&& rm sing-box-1.8.11-linux-amd64.tar.gz \
|
||||
&& rm -rf /sing-box-1.8.11-linux-amd64
|
||||
ENV ENV="/root/.ashrc"
|
||||
RUN apk add openssh \
|
||||
&& mkdir /root/.ssh
|
||||
ENV ENV="/root/.ashrc"
|
||||
|
||||
@@ -3,7 +3,7 @@ b:
|
||||
u: # запуск контейнеров
|
||||
$(eval IP := $(shell curl -s -t 1 2ip.io || curl -s -t 1 ipinfo.io/ip || curl -s -t 1 ifconfig.me))
|
||||
bash ./update/update.sh &
|
||||
touch ./override.env
|
||||
touch ./override.env ./docker-compose.override.yml
|
||||
IP=$(IP) VER=$(shell git describe --tags) docker compose --env-file ./.env --env-file ./override.env up -d --force-recreate
|
||||
d: # остановка контейнеров
|
||||
-kill -9 $(shell cat ./update/update_pid) > /dev/null
|
||||
|
||||
+1
-11
@@ -10,17 +10,7 @@ apt install -y \
|
||||
iproute2 \
|
||||
xtables-addons-common \
|
||||
xtables-addons-dkms
|
||||
mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]')/gpg | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg
|
||||
echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/$(lsb_release -is | tr '[:upper:]' '[:lower:]') \
|
||||
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
apt update
|
||||
apt install -y docker-ce docker-ce-cli containerd.io
|
||||
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
|
||||
mkdir -p $DOCKER_CONFIG/cli-plugins
|
||||
curl -SL https://github.com/docker/compose/releases/download/v2.29.6/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
|
||||
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
|
||||
git clone https://github.com/mercurykd/vpnbot.git
|
||||
cd ./vpnbot
|
||||
echo "<?php
|
||||
|
||||
@@ -3,7 +3,6 @@ ssh-keygen -m PEM -t rsa -f /ssh/key -N ''
|
||||
openssl req -newkey rsa:2048 -sha256 -nodes -x509 -days 365 -keyout /certs/self_private -out /certs/self_public -subj "/C=NN/ST=N/L=N/O=N/CN=$IP"
|
||||
php init.php
|
||||
if [[ -f "/start" && -f "/ssh/key.pub" && -s "/ssh/key.pub" ]]; then
|
||||
php cron.php &
|
||||
unitd --log /logs/unit_error
|
||||
curl -X PUT --data-binary @/config/unit.json --unix-socket /var/run/control.unit.sock http://localhost/config
|
||||
pkill unitd
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
php service.php
|
||||
cat /ssh/key.pub > /root/.ssh/authorized_keys
|
||||
ssh-keygen -A
|
||||
exec /usr/sbin/sshd -D -e "$@" &
|
||||
php service.php
|
||||
php cron.php
|
||||
@@ -6,7 +6,7 @@ After=docker.service
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
WorkingDirectory=path
|
||||
ExecStartPre=/bin/sh -c "touch ./override.env"
|
||||
ExecStartPre=/bin/sh -c "touch ./override.env ./docker-compose.override.yml"
|
||||
ExecStart=/bin/sh -c "IP=$(curl https://ipinfo.io/ip) VER=$(git describe --tags) docker compose --env-file ./.env --env-file ./override.env up -d --force-recreate"
|
||||
ExecStartPost=/bin/sh -c "bash ./update/update.sh &"
|
||||
ExecStop=/bin/sh -c "docker compose down --remove-orphans"
|
||||
|
||||
+12
-9
@@ -12,17 +12,20 @@ do
|
||||
key=$(cat $pwd/update/key)
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "останавливаю бота"/')"
|
||||
docker compose down --remove-orphans
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "очищаю директорию"/')"
|
||||
git reset --hard && git clean -fd
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "скачиваю обновление"/')"
|
||||
git fetch
|
||||
if [[ -n "$branch" ]]
|
||||
if [[ "$cmd" == "1" ]]
|
||||
then
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "меняю ветку"/')"
|
||||
git checkout -t origin/$branch || git checkout $branch
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "очищаю директорию"/')"
|
||||
git reset --hard && git clean -fd
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "скачиваю обновление"/')"
|
||||
git fetch
|
||||
if [[ -n "$branch" ]]
|
||||
then
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "меняю ветку"/')"
|
||||
git checkout -t origin/$branch || git checkout $branch
|
||||
fi
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "применяю обновления"/')"
|
||||
git pull > ./update/message
|
||||
fi
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "применяю обновления"/')"
|
||||
git pull > ./update/message
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "запускаю бота"/')"
|
||||
IP=$(curl ipinfo.io/ip) VER=$(git describe --tags) docker compose --env-file ./.env --env-file ./override.env up -d --force-recreate
|
||||
bash $pwd/update/update.sh &
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
14.11.2024 v1.99
|
||||
- анализ логов и бан айпишников
|
||||
11.11.2024 v1.98
|
||||
- фикс заполнения clientId при наполнении белого списка клиентов adg
|
||||
09.11.2024 v1.97
|
||||
- новая ссылка на чат поддержки. пожалуйста не размещайте ее на форумах и чатах во избежание набега leafers https://www.youtube.com/watch?v=9tlNJmjuKD4
|
||||
06.11.2024 v1.96
|
||||
- фикс пароля adguard
|
||||
- таймаоут для проверки статуса adguard
|
||||
04.11.2024 v1.95
|
||||
- отключение портов контейнеров из меню
|
||||
- перезагрузка из меню
|
||||
04.11.2024 v1.94
|
||||
- xray: возможность перемещать и переименовывать outbound заполняемый ботом
|
||||
04.11.2024 v1.93
|
||||
- adguardHome: сброс настроек
|
||||
- adguardHome: статус работоспособности
|
||||
|
||||
Reference in New Issue
Block a user