Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a593100b7 | |||
| 414a67c10d | |||
| f92b484011 | |||
| 7af0276944 | |||
| 24aaa8756c | |||
| 07e2beff9b | |||
| 86261e6b76 | |||
| d816582e6f | |||
| 6d1ab0cb3a | |||
| 284b025881 | |||
| 0ca93b56a3 | |||
| 7bcd8de007 | |||
| 34eb950852 | |||
| 46021855a5 | |||
| 29c18ceb9d | |||
| 49d0827b9e | |||
| 07e04c384a | |||
| 579457b4f4 | |||
| 3dac9416ca | |||
| 5b4d3b5627 | |||
| 658e125cd8 | |||
| 1840555573 | |||
| ecdc028226 | |||
| d432bf82f2 | |||
| 211e2c079d | |||
| 1696c4da7b | |||
| b8d5700eba |
+233
-40
@@ -238,6 +238,7 @@ class Bot
|
||||
break;
|
||||
case preg_match('~^/id$~', $this->input['message'], $m):
|
||||
$this->send($this->input['chat'], $this->input['from'], $this->input['message_id']);
|
||||
$this->send($this->input['chat'], $this->input['chat'], $this->input['message_id']);
|
||||
break;
|
||||
case preg_match('~^/adguardChBr$~', $this->input['callback'], $m):
|
||||
$this->adguardChBr();
|
||||
@@ -296,7 +297,7 @@ class Bot
|
||||
case preg_match('~^/delLog (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
|
||||
$this->delLog(...explode('_', $m['arg']));
|
||||
break;
|
||||
case preg_match('~^/debug$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/debug$~', $this->input['message'], $m):
|
||||
$this->debug();
|
||||
break;
|
||||
case preg_match('~^/backup$~', $this->input['callback'], $m):
|
||||
@@ -377,6 +378,9 @@ class Bot
|
||||
case preg_match('~^/renameXrUser (\d+)$~', $this->input['callback'], $m):
|
||||
$this->renameXrUser($m[1]);
|
||||
break;
|
||||
case preg_match('~^/resetXrUser (\d+)$~', $this->input['callback'], $m):
|
||||
$this->resetXrUser($m[1]);
|
||||
break;
|
||||
case preg_match('~^/v2ray$~', $this->input['callback'], $m):
|
||||
$this->v2ray();
|
||||
break;
|
||||
@@ -540,6 +544,9 @@ class Bot
|
||||
case preg_match('~^/xtlsprocess(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
$this->xtlsprocess($m[1] ?: 0);
|
||||
break;
|
||||
case preg_match('~^/xtlssubnet(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
$this->xtlssubnet($m[1] ?: 0);
|
||||
break;
|
||||
case preg_match('~^/xtlsrulesset(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
$this->xtlsrulesset($m[1] ?: 0);
|
||||
break;
|
||||
@@ -667,13 +674,75 @@ class Bot
|
||||
}
|
||||
}
|
||||
|
||||
public function restartXray($c)
|
||||
public function restartXray($c, $norestart = false)
|
||||
{
|
||||
$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');
|
||||
foreach ($c['inbounds'] as $v) {
|
||||
if ($v['tag'] == 'api') {
|
||||
$inbound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (empty($inbound)) {
|
||||
$c['inbounds'][] = [
|
||||
"listen" => "127.0.0.1",
|
||||
"port" => 8080,
|
||||
"protocol" => "dokodemo-door",
|
||||
"settings" => [
|
||||
"address" => "127.0.0.1"
|
||||
],
|
||||
"tag" => "api"
|
||||
];
|
||||
}
|
||||
foreach ($c['routing']['rules'] as $v) {
|
||||
if ($v['outboundTag'] == 'api') {
|
||||
$rule = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (empty($rule)) {
|
||||
$c['routing']['rules'][] = [
|
||||
"inboundTag" => ["api"],
|
||||
"outboundTag" => "api",
|
||||
"type" => "field"
|
||||
];
|
||||
}
|
||||
$c['stats'] = new stdClass();
|
||||
$c['api'] = [
|
||||
'services' => ['StatsService'],
|
||||
'tag' => 'api'
|
||||
];
|
||||
$l = new stdClass();
|
||||
$l->{'0'} = [
|
||||
"statsUserUplink" => true,
|
||||
"statsUserDownlink" => true
|
||||
];
|
||||
$c['policy']['levels'] = $l;
|
||||
$c['policy']['system'] = [
|
||||
"statsInboundUplink" => true,
|
||||
"statsInboundDownlink" => true,
|
||||
"statsOutboundUplink" => true,
|
||||
"statsOutboundDownlink" => true
|
||||
];
|
||||
if (empty($norestart)) {
|
||||
$c = $this->collectSession($c);
|
||||
file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
$this->ssh('pkill xray', 'xr');
|
||||
$this->ssh('xray run -config /xray.json > /dev/null 2>&1 &', 'xr');
|
||||
} else {
|
||||
file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
}
|
||||
|
||||
public function collectSession($c) {
|
||||
foreach ($c['inbounds'][0]['settings']['clients'] as $k => $v) {
|
||||
$c['inbounds'][0]['settings']['clients'][$k]['global']['download'] += $v['session']['download'];
|
||||
$c['inbounds'][0]['settings']['clients'][$k]['session']['download'] = 0;
|
||||
$c['inbounds'][0]['settings']['clients'][$k]['global']['upload'] += $v['session']['upload'];
|
||||
$c['inbounds'][0]['settings']['clients'][$k]['session']['upload'] = 0;
|
||||
}
|
||||
return $c;
|
||||
}
|
||||
|
||||
public function linkMtproto()
|
||||
@@ -1251,10 +1320,30 @@ class Bot
|
||||
$this->checkBackup($period);
|
||||
$this->checkCert();
|
||||
$this->autoAnalyzeLogs();
|
||||
$this->xrayStatsUser();
|
||||
sleep($period);
|
||||
}
|
||||
}
|
||||
|
||||
public function xrayStatsUser()
|
||||
{
|
||||
try {
|
||||
$x = $this->getXray();
|
||||
if (!empty($users = $x['inbounds'][0]['settings']['clients'])) {
|
||||
foreach ($users as $k => $v) {
|
||||
$d = json_decode($this->ssh('xray api stats --server=127.0.0.1:8080 -name "user>>>' . $v['email'] . '>>>traffic>>>downlink" 2>&1', 'xr'), true)['stat']['value'] ?: 0;
|
||||
$u = json_decode($this->ssh('xray api stats --server=127.0.0.1:8080 -name "user>>>' . $v['email'] . '>>>traffic>>>uplink" 2>&1', 'xr'), true)['stat']['value'] ?: 0;
|
||||
$x['inbounds'][0]['settings']['clients'][$k]['session'] = [
|
||||
'download' => $d,
|
||||
'upload' => $u,
|
||||
];
|
||||
}
|
||||
$this->restartXray($x, norestart: 1);
|
||||
}
|
||||
} catch (\Throwable $th) {
|
||||
}
|
||||
}
|
||||
|
||||
public function autoAnalyzeLogs()
|
||||
{
|
||||
try {
|
||||
@@ -2612,15 +2701,15 @@ DNS-over-HTTPS with IP:
|
||||
$this->xtlswarp();
|
||||
break;
|
||||
case 'processlist':
|
||||
$this->xrayUpdateRules();
|
||||
$this->xtlsprocess();
|
||||
break;
|
||||
case 'packagelist':
|
||||
$this->xrayUpdateRules();
|
||||
$this->xtlsapp();
|
||||
break;
|
||||
case 'subnetlist':
|
||||
$this->xtlssubnet();
|
||||
break;
|
||||
case 'rulessetlist':
|
||||
$this->xrayUpdateRules();
|
||||
$this->xtlsrulesset();
|
||||
break;
|
||||
case 'white':
|
||||
@@ -3435,8 +3524,6 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $this->i18n('delete'),
|
||||
'callback_data' => "/delete {$client}_$page",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/menu wg $page",
|
||||
@@ -3670,6 +3757,12 @@ DNS-over-HTTPS with IP:
|
||||
case 'packagelist':
|
||||
$dir = 'PACKAGE';
|
||||
break;
|
||||
case 'processlist':
|
||||
$dir = 'PROCESS';
|
||||
break;
|
||||
case 'subnetlist':
|
||||
$dir = 'SUBNET';
|
||||
break;
|
||||
case 'rulessetlist':
|
||||
$dir = 'rulesset';
|
||||
break;
|
||||
@@ -3716,6 +3809,22 @@ DNS-over-HTTPS with IP:
|
||||
],
|
||||
];
|
||||
break;
|
||||
case 'processlist':
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/xtlsprocess",
|
||||
],
|
||||
];
|
||||
break;
|
||||
case 'subnetlist':
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/xtlssubnet",
|
||||
],
|
||||
];
|
||||
break;
|
||||
case 'rulessetlist':
|
||||
$data[] = [
|
||||
[
|
||||
@@ -3863,7 +3972,25 @@ DNS-over-HTTPS with IP:
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . ' -> ' . $this->i18n('routes') . ' -> process list';
|
||||
|
||||
[$data] = $this->listPac('processlist', $page, 'xtlsprocess');
|
||||
$p = $this->getPacConf();
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/routes",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
$this->input['chat'],
|
||||
$this->input['message_id'],
|
||||
implode("\n", $text ?: ['...']),
|
||||
$data ?: false,
|
||||
);
|
||||
}
|
||||
|
||||
public function xtlssubnet($page = 0)
|
||||
{
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . ' -> ' . $this->i18n('routes') . ' -> subnet';
|
||||
|
||||
[$data] = $this->listPac('subnetlist', $page, 'xtlssubnet');
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
@@ -3919,7 +4046,7 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n($v ? 'on' : 'off') . ' ' . ($basename ? basename($k) . ' ' : '') . (in_array($type, ['rulessetlist', 'packagelist', 'processlist']) ? $k : idn_to_utf8($k)),
|
||||
'text' => $this->i18n($v ? 'on' : 'off') . ' ' . ($basename ? basename($k) . ' ' : '') . (in_array($type, ['rulessetlist', 'packagelist', 'processlist', 'subnetlist']) ? $k : idn_to_utf8($k)),
|
||||
'callback_data' => "/change$type " . ($i + $page * $this->limit),
|
||||
],
|
||||
[
|
||||
@@ -4119,12 +4246,6 @@ DNS-over-HTTPS with IP:
|
||||
'main' => [
|
||||
'text' => implode("\n", $main ?: []),
|
||||
'data' => [
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('config'),
|
||||
'callback_data' => "/menu config",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n($this->getPacConf()['amnezia'] ? 'amnezia' : 'wg_title'),
|
||||
@@ -4175,10 +4296,16 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/pacMenu 0",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('config'),
|
||||
'callback_data' => "/menu config",
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('chat'),
|
||||
'url' => "https://t.me/+Wfxg6-nrokBlMmYy",
|
||||
'url' => base64_decode('aHR0cHM6Ly90Lm1lLytXZnhnNi1ucm9rQmxNbVl5'),
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('donate'),
|
||||
@@ -4426,7 +4553,6 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
|
||||
$t = [
|
||||
$this->suspicious('~\d+\.\d+\.\d+\.\d+.+200\s\d+\s0$~', '/logs/upstream_access', $xr, 'possibly a Reality Degenerate'),
|
||||
$this->suspicious($this->reg, '/logs/nginx_default_access', $xr, 'possibly a scanner', true),
|
||||
$this->suspicious($this->reg, '/logs/nginx_domain_access', $xr, 'possibly a scanner', true),
|
||||
];
|
||||
@@ -4438,6 +4564,15 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
}
|
||||
|
||||
$r = $this->suspicious('~\d+\.\d+\.\d+\.\d+.+200\s\d+\s0$~', '/logs/upstream_access', $xr, 'possibly a Reality Degenerate');
|
||||
if (!empty($r)) {
|
||||
foreach ($r as $k => $v) {
|
||||
if (count($v) > 30) {
|
||||
$ip[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($return)) {
|
||||
return $ip;
|
||||
}
|
||||
@@ -5137,15 +5272,15 @@ DNS-over-HTTPS with IP:
|
||||
|
||||
public function setTimerXr($time, $i)
|
||||
{
|
||||
$time = strtotime($time);
|
||||
if ($time === false) {
|
||||
$this->send($this->input['chat'], 'wrong format');
|
||||
return;
|
||||
}
|
||||
$c = $this->getXray();
|
||||
if (empty($time)) {
|
||||
unset($c['inbounds'][0]['settings']['clients'][$i]['time']);
|
||||
} else {
|
||||
$time = strtotime($time);
|
||||
if ($time === false) {
|
||||
$this->send($this->input['chat'], 'wrong format');
|
||||
return;
|
||||
}
|
||||
if (!empty($c['inbounds'][0]['settings']['clients'][$i]['off'])) {
|
||||
$this->switchXr($i, 1);
|
||||
$c = $this->getXray();
|
||||
@@ -5182,6 +5317,17 @@ DNS-over-HTTPS with IP:
|
||||
$this->userXr($i);
|
||||
}
|
||||
|
||||
public function resetXrUser($i)
|
||||
{
|
||||
$c = $this->getXray();
|
||||
$c['inbounds'][0]['settings']['clients'][$i]['global'] = [
|
||||
'download' => 0,
|
||||
'upload' => 0,
|
||||
];
|
||||
$this->restartXray($c);
|
||||
$this->userXr($i);
|
||||
}
|
||||
|
||||
public function listXr($i)
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
@@ -5314,14 +5460,7 @@ DNS-over-HTTPS with IP:
|
||||
|
||||
public function downloadOrigin($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case 'sing':
|
||||
$f = new \CURLFile('/config/sing.json', 'application/json', 'origin.json');
|
||||
break;
|
||||
case 'v2ray':
|
||||
$f = new \CURLFile('/config/v2ray.json', 'application/json', 'origin.json');
|
||||
break;
|
||||
}
|
||||
$f = new \CURLFile("/config/$type.json", 'application/json', 'origin.json');
|
||||
$this->sendFile($this->input['chat'], $f);
|
||||
}
|
||||
|
||||
@@ -5355,6 +5494,7 @@ DNS-over-HTTPS with IP:
|
||||
<code>~pac~</code>
|
||||
<code>~package~</code>
|
||||
<code>~process~</code>
|
||||
<code>~subnet~</code>
|
||||
<code>~block~</code>
|
||||
<code>~warp~</code>
|
||||
<code>~dns~</code>
|
||||
@@ -5363,6 +5503,7 @@ DNS-over-HTTPS with IP:
|
||||
<code>~directdomain~</code>
|
||||
<code>~cdndomain~</code>
|
||||
<code>~short_id~</code>
|
||||
<code>~email~</code>
|
||||
<code>~public_key~</code>
|
||||
<code>~server_name~</code>
|
||||
<code>~ip~</code>
|
||||
@@ -5456,6 +5597,25 @@ DNS-over-HTTPS with IP:
|
||||
$this->xray();
|
||||
}
|
||||
|
||||
public function getBytes($bytes)
|
||||
{
|
||||
$t = [
|
||||
'B',
|
||||
'KB',
|
||||
'MB',
|
||||
'GB',
|
||||
'TB',
|
||||
];
|
||||
foreach ($t as $k => $v) {
|
||||
if ($k == 0) {
|
||||
continue;
|
||||
}
|
||||
if ($bytes / (1024 ** $k) < 1) {
|
||||
return round($bytes / (1024 ** ($k - 1)), 2) . " {$t[$k - 1]}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function xray($page = 0)
|
||||
{
|
||||
if (!$this->ssh('pgrep xray', 'xr')) {
|
||||
@@ -5538,10 +5698,12 @@ DNS-over-HTTPS with IP:
|
||||
$page = $page == -2 ? $all - 1 : $page;
|
||||
$clients = $page != -1 ? array_slice($clients, $page * $this->limit, $this->limit, true) : $clients;
|
||||
foreach ($clients as $k => $v) {
|
||||
$time = $v['time'] ? $this->getTime($v['time']) : '';
|
||||
$data[] = [
|
||||
$download = $this->getBytes($v['global']['download'] + $v['session']['download']);
|
||||
$upload = $this->getBytes($v['global']['upload'] + $v['session']['upload']);
|
||||
$time = $v['time'] ? $this->getTime($v['time']) : '';
|
||||
$data[] = [
|
||||
[
|
||||
'text' => "{$v['email']}" . ($time ? ": $time" : ''),
|
||||
'text' => "{$v['email']}" . ($time ? ": $time" : '') . " (↓$download ↑$upload)",
|
||||
'callback_data' => "/userXr $k",
|
||||
],
|
||||
];
|
||||
@@ -5591,9 +5753,6 @@ DNS-over-HTTPS with IP:
|
||||
{
|
||||
$text[] = "Menu -> " . $this->i18n('xray') . ' -> routes';
|
||||
|
||||
$p = $this->getPacConf();
|
||||
$outbound = $p['outbound'] ?: 'proxy';
|
||||
|
||||
$data = [
|
||||
[[
|
||||
'text' => $this->i18n('block'),
|
||||
@@ -5607,6 +5766,10 @@ DNS-over-HTTPS with IP:
|
||||
'text' => 'domains',
|
||||
'callback_data' => "/xtlsproxy",
|
||||
]],
|
||||
[[
|
||||
'text' => "subnet",
|
||||
'callback_data' => "/xtlssubnet",
|
||||
]],
|
||||
[[
|
||||
'text' => 'process',
|
||||
'callback_data' => "/xtlsprocess",
|
||||
@@ -5885,6 +6048,14 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/qrXray {$i}_2",
|
||||
],
|
||||
];
|
||||
$download = $this->getBytes($c['global']['download'] + $c['session']['download']);
|
||||
$upload = $this->getBytes($c['global']['upload'] + $c['session']['upload']);
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('reset stats') . ": ↓$download ↑$upload",
|
||||
'callback_data' => "/resetXrUser $i",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('rename'),
|
||||
@@ -6125,12 +6296,14 @@ DNS-over-HTTPS with IP:
|
||||
'"~warp~"' => json_encode(array_keys(array_filter($pac['warplist'] ?: []))),
|
||||
'"~process~"' => json_encode(array_keys(array_filter($pac['processlist'] ?: []))),
|
||||
'"~package~"' => json_encode(array_keys(array_filter($pac['packagelist'] ?: []))),
|
||||
'"~subnet~"' => json_encode(array_keys(array_filter($pac['subnetlist'] ?: []))),
|
||||
'~dns~' => "https://$domain/dns-query$hash/$uid",
|
||||
'~uid~' => $uid,
|
||||
'~domain~' => $domain,
|
||||
'~directdomain~' => $pac['domain'],
|
||||
'~cdndomain~' => $pac['linkdomain'],
|
||||
'~short_id~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0],
|
||||
'~email~' => $email,
|
||||
'~public_key~' => $pac['xray'],
|
||||
'~server_name~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0],
|
||||
'~ip~' => $this->ip,
|
||||
@@ -6234,6 +6407,9 @@ DNS-over-HTTPS with IP:
|
||||
case 'domain':
|
||||
echo yaml_emit(['payload' => array_map(fn($e) => "+.$e", $v['list'])]);
|
||||
break;
|
||||
case 'ipcidr':
|
||||
echo yaml_emit(['payload' => array_map(fn($e) => $e, $v['list'])]);
|
||||
break;
|
||||
|
||||
default:
|
||||
echo yaml_emit(['payload' => array_map(fn($e) => "PROCESS-NAME,$e", $v['list'])]);
|
||||
@@ -6829,6 +7005,8 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $this->i18n('Ports'),
|
||||
'callback_data' => "/ports",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('IP ban & Logs'),
|
||||
'callback_data' => "/ipMenu",
|
||||
@@ -6919,6 +7097,7 @@ DNS-over-HTTPS with IP:
|
||||
$text[] = 'Settings -> Ports';
|
||||
$f = '/docker/compose';
|
||||
$c = yaml_parse_file($f)['services'];
|
||||
$pac = $this->getPacConf();
|
||||
$data = [
|
||||
[[
|
||||
'text' => $this->i18n($c['wg'] ? 'on' : 'off') . ' ' . getenv('WGPORT') . ' Wireguard',
|
||||
@@ -6941,6 +7120,14 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/hidePort ss",
|
||||
]],
|
||||
];
|
||||
if (!empty($pac['restart'])) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('restart'),
|
||||
'callback_data' => "/restart",
|
||||
],
|
||||
];
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
@@ -6976,7 +7163,10 @@ DNS-over-HTTPS with IP:
|
||||
} else {
|
||||
yaml_emit_file($f, $c);
|
||||
}
|
||||
$this->restart();
|
||||
$pac = $this->getPacConf();
|
||||
$pac['restart'] = 1;
|
||||
$this->setPacConf($pac);
|
||||
$this->ports();
|
||||
}
|
||||
|
||||
public function branches()
|
||||
@@ -7113,6 +7303,9 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
file_put_contents('/update/message', '');
|
||||
file_put_contents('/update/reload_message', '');
|
||||
$pac = $this->getPacConf();
|
||||
unset($pac['restart']);
|
||||
$this->setPacConf($pac);
|
||||
}
|
||||
|
||||
public function backup()
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ $i = [
|
||||
'ru' => 'PAC',
|
||||
],
|
||||
'chat' => [
|
||||
'en' => 'discussion group',
|
||||
'en' => 'chat',
|
||||
'ru' => 'чат поддержки',
|
||||
],
|
||||
'back' => [
|
||||
|
||||
@@ -133,6 +133,14 @@
|
||||
"behavior": "domain",
|
||||
"name": "pac"
|
||||
},
|
||||
{
|
||||
"type": "RULE-SET",
|
||||
"list": "~subnet~",
|
||||
"action": "PROXY",
|
||||
"interval": 30,
|
||||
"behavior": "ipcidr",
|
||||
"name": "subnet"
|
||||
},
|
||||
{
|
||||
"type": "MATCH",
|
||||
"action": "DIRECT"
|
||||
|
||||
@@ -129,6 +129,21 @@
|
||||
],
|
||||
"outbound": "~outbound~"
|
||||
},
|
||||
{
|
||||
"addruleset": true,
|
||||
"createruleset": [
|
||||
{
|
||||
"name": "subnet",
|
||||
"interval": "30s",
|
||||
"rules": [
|
||||
{
|
||||
"ip_cidr": "~subnet~"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"outbound": "~outbound~"
|
||||
},
|
||||
{
|
||||
"addruleset": true,
|
||||
"createruleset": [
|
||||
|
||||
+111
-81
@@ -4,92 +4,122 @@
|
||||
"error": "",
|
||||
"loglevel": "warning"
|
||||
},
|
||||
"inbounds": [{
|
||||
"tag": "socks",
|
||||
"port": 10808,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "socks",
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls"],
|
||||
"routeOnly": false
|
||||
},
|
||||
"settings": {
|
||||
"auth": "noauth",
|
||||
"udp": true,
|
||||
"allowTransparent": false
|
||||
}
|
||||
}, {
|
||||
"tag": "http",
|
||||
"port": 10809,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "http",
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": ["http", "tls"],
|
||||
"routeOnly": false
|
||||
},
|
||||
"settings": {
|
||||
"auth": "noauth",
|
||||
"udp": true,
|
||||
"allowTransparent": false
|
||||
}
|
||||
}],
|
||||
"outbounds": [{
|
||||
"tag": "~outbound~",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [{
|
||||
"address": "~domain~",
|
||||
"port": 443,
|
||||
"users": [{
|
||||
"id": "~uid~",
|
||||
"alterId": 0,
|
||||
"email": "t@t.tt",
|
||||
"security": "auto",
|
||||
"encryption": "none",
|
||||
"flow": "xtls-rprx-vision"
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"serverName": "~server_name~",
|
||||
"fingerprint": "chrome",
|
||||
"show": false,
|
||||
"publicKey": "~public_key~",
|
||||
"shortId": "~short_id~",
|
||||
"spiderX": ""
|
||||
"inbounds": [
|
||||
{
|
||||
"tag": "socks",
|
||||
"port": 10808,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "socks",
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": [
|
||||
"http",
|
||||
"tls"
|
||||
],
|
||||
"routeOnly": false
|
||||
},
|
||||
"settings": {
|
||||
"auth": "noauth",
|
||||
"udp": true,
|
||||
"allowTransparent": false
|
||||
}
|
||||
},
|
||||
"mux": {
|
||||
"enabled": false,
|
||||
"concurrency": -1
|
||||
}
|
||||
}, {
|
||||
"tag": "direct",
|
||||
"protocol": "freedom"
|
||||
}, {
|
||||
"tag": "block",
|
||||
"protocol": "blackhole",
|
||||
"settings": {
|
||||
"response": {
|
||||
"type": "http"
|
||||
{
|
||||
"tag": "http",
|
||||
"port": 10809,
|
||||
"listen": "127.0.0.1",
|
||||
"protocol": "http",
|
||||
"sniffing": {
|
||||
"enabled": true,
|
||||
"destOverride": [
|
||||
"http",
|
||||
"tls"
|
||||
],
|
||||
"routeOnly": false
|
||||
},
|
||||
"settings": {
|
||||
"auth": "noauth",
|
||||
"udp": true,
|
||||
"allowTransparent": false
|
||||
}
|
||||
}
|
||||
}],
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"tag": "direct",
|
||||
"protocol": "freedom"
|
||||
},
|
||||
{
|
||||
"tag": "~outbound~",
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "~domain~",
|
||||
"port": 443,
|
||||
"users": [
|
||||
{
|
||||
"id": "~uid~",
|
||||
"alterId": 0,
|
||||
"email": "t@t.tt",
|
||||
"security": "auto",
|
||||
"encryption": "none",
|
||||
"flow": "xtls-rprx-vision"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"serverName": "~server_name~",
|
||||
"fingerprint": "chrome",
|
||||
"show": false,
|
||||
"publicKey": "~public_key~",
|
||||
"shortId": "~short_id~",
|
||||
"spiderX": ""
|
||||
}
|
||||
},
|
||||
"mux": {
|
||||
"enabled": false,
|
||||
"concurrency": -1
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "block",
|
||||
"protocol": "blackhole",
|
||||
"settings": {
|
||||
"response": {
|
||||
"type": "http"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": [{
|
||||
"type": "field",
|
||||
"outboundTag": "~outbound~",
|
||||
"domain": "~pac~"
|
||||
}, {
|
||||
"type": "field",
|
||||
"port": "0-65535",
|
||||
"outboundTag": "direct"
|
||||
}]
|
||||
"rules": [
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "block",
|
||||
"domain": "~block~"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "~outbound~",
|
||||
"domain": "~pac~"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "~outbound~",
|
||||
"ip": "~subnet~"
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
"outboundTag": "~outbound~",
|
||||
"domain": "~warp~"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+39
-1
@@ -22,6 +22,15 @@
|
||||
}
|
||||
},
|
||||
"tag": "vless_tls"
|
||||
},
|
||||
{
|
||||
"listen": "127.0.0.1",
|
||||
"port": 8080,
|
||||
"protocol": "dokodemo-door",
|
||||
"settings": {
|
||||
"address": "127.0.0.1"
|
||||
},
|
||||
"tag": "api"
|
||||
}
|
||||
],
|
||||
"log": {
|
||||
@@ -40,6 +49,35 @@
|
||||
],
|
||||
"routing": {
|
||||
"domainStrategy": "AsIs",
|
||||
"rules": []
|
||||
"rules": [
|
||||
{
|
||||
"inboundTag": [
|
||||
"api"
|
||||
],
|
||||
"outboundTag": "api",
|
||||
"type": "field"
|
||||
}
|
||||
]
|
||||
},
|
||||
"stats": {},
|
||||
"api": {
|
||||
"services": [
|
||||
"StatsService"
|
||||
],
|
||||
"tag": "api"
|
||||
},
|
||||
"policy": {
|
||||
"levels": {
|
||||
"0": {
|
||||
"statsUserUplink": true,
|
||||
"statsUserDownlink": true
|
||||
}
|
||||
},
|
||||
"system": {
|
||||
"statsInboundUplink": true,
|
||||
"statsInboundDownlink": true,
|
||||
"statsOutboundUplink": true,
|
||||
"statsOutboundDownlink": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,8 +13,17 @@ telegram bot to manage servers (inside the bot)
|
||||
---
|
||||
environment: ubuntu 22.04/24.04, debian 11/12
|
||||
|
||||
### Install:
|
||||
## Install:
|
||||
|
||||
```shell
|
||||
wget -O- https://raw.githubusercontent.com/mercurykd/vpnbot/master/scripts/init.sh | sh -s YOUR_TELEGRAM_BOT_KEY master
|
||||
```
|
||||
#### Restart:
|
||||
```shell
|
||||
make r
|
||||
```
|
||||
#### autoload:
|
||||
```shell
|
||||
crontab -e
|
||||
```
|
||||
add `@reboot cd /root/vpnbot && make r` and save
|
||||
|
||||
Binary file not shown.
@@ -1,3 +1,18 @@
|
||||
02.02.2025 v2.9
|
||||
- откат sing-box 1.11
|
||||
02.02.2025 v2.8
|
||||
- vless: корректировка статы юзера
|
||||
- sing-box 1.11
|
||||
29.01.2025 v2.7
|
||||
- vless: сброс статистики юзера
|
||||
24.01.2025 v2.6
|
||||
- правки меню
|
||||
- vless:добавлена возможность маршрутизировать список ip-сетей
|
||||
18.01.2025 v2.5
|
||||
- фикс скачивания шаблона михомо
|
||||
- обновлен singbox.exe
|
||||
- вывод статистики vless пользователей
|
||||
- смягчил паттерн поиска reality degenerate в логах
|
||||
07.01.2025 v2.4
|
||||
- вернул shadowsocks (спасибо за донат)
|
||||
04.01.2025
|
||||
|
||||
Reference in New Issue
Block a user