Compare commits

...

27 Commits

Author SHA1 Message Date
mercury 1a593100b7 update version 2025-02-02 14:24:05 +04:00
mercury 414a67c10d Revert "update singbox 1.11 windows x64"
This reverts commit 284b025881.
2025-02-02 13:29:51 +04:00
mercury f92b484011 Revert "fix singbox template"
This reverts commit 86261e6b76.
2025-02-02 11:52:02 +04:00
mercury 7af0276944 Revert "Migrate to sing-box 1.11"
This reverts commit 6d1ab0cb3a.
2025-02-02 01:56:15 +04:00
mercury 24aaa8756c update version 2025-02-02 00:05:02 +04:00
mercury 07e2beff9b xray stats improve 2025-01-31 18:15:48 +04:00
mercury 86261e6b76 fix singbox template 2025-01-31 12:30:45 +04:00
Konstantin d816582e6f Merge pull request #34 from legiz-ru/dev
Migrate to sing-box 1.11
2025-01-30 19:04:30 +04:00
legiz-ru 6d1ab0cb3a Migrate to sing-box 1.11 2025-01-30 17:55:27 +03:00
legiz-ru 284b025881 update singbox 1.11 windows x64 2025-01-30 17:51:19 +03:00
mercury 0ca93b56a3 vless: ~email~ tag in subscription 2025-01-29 18:18:28 +04:00
mercury 7bcd8de007 vless: reset stats user 2025-01-29 11:04:06 +04:00
mercury 34eb950852 ip-cidr route 2025-01-24 22:09:05 +04:00
mercury 46021855a5 improve wg client menu 2025-01-23 00:55:44 +04:00
mercury 29c18ceb9d update readme 2025-01-20 01:04:24 +04:00
mercury 49d0827b9e update version 2025-01-18 23:39:39 +04:00
mercury 07e04c384a Merge branch 'dev' of github.com:mercurykd/vpnbot into dev 2025-01-18 23:33:29 +04:00
mercury 579457b4f4 show xray stats 2025-01-18 23:33:00 +04:00
mercury 3dac9416ca fix download mihomo template 2025-01-18 23:32:31 +04:00
mercury 5b4d3b5627 reality degenerate pattern improve 2025-01-18 23:31:58 +04:00
mercury 658e125cd8 show group id 2025-01-18 23:31:01 +04:00
Konstantin 1840555573 Merge pull request #33 from legiz-ru/dev
update singbox 1.10.7 windows x64
2025-01-18 18:23:20 +04:00
legiz-ru ecdc028226 update singbox 1.10.7 windows x64 2025-01-18 16:57:39 +03:00
mercury d432bf82f2 force inclusion of xray statistics 2025-01-16 01:04:33 +04:00
mercury 211e2c079d collect xray metrics 2025-01-13 15:32:54 +04:00
Konstantin 1696c4da7b Merge pull request #32 from legiz-ru/dev
v2ray(xray) client templates update
2025-01-12 02:23:56 +04:00
legiz-ru b8d5700eba v2ray(xray) client update
return warp+block domain routes
replace rule for directing
2025-01-12 01:17:23 +03:00
9 changed files with 432 additions and 124 deletions
+233 -40
View File
@@ -238,6 +238,7 @@ class Bot
break; break;
case preg_match('~^/id$~', $this->input['message'], $m): 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['from'], $this->input['message_id']);
$this->send($this->input['chat'], $this->input['chat'], $this->input['message_id']);
break; break;
case preg_match('~^/adguardChBr$~', $this->input['callback'], $m): case preg_match('~^/adguardChBr$~', $this->input['callback'], $m):
$this->adguardChBr(); $this->adguardChBr();
@@ -296,7 +297,7 @@ class Bot
case preg_match('~^/delLog (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m): case preg_match('~^/delLog (?P<arg>\d+(?:_(?:-)?\d+)?)$~', $this->input['callback'], $m):
$this->delLog(...explode('_', $m['arg'])); $this->delLog(...explode('_', $m['arg']));
break; break;
case preg_match('~^/debug$~', $this->input['callback'], $m): case preg_match('~^/debug$~', $this->input['message'], $m):
$this->debug(); $this->debug();
break; break;
case preg_match('~^/backup$~', $this->input['callback'], $m): case preg_match('~^/backup$~', $this->input['callback'], $m):
@@ -377,6 +378,9 @@ class Bot
case preg_match('~^/renameXrUser (\d+)$~', $this->input['callback'], $m): case preg_match('~^/renameXrUser (\d+)$~', $this->input['callback'], $m):
$this->renameXrUser($m[1]); $this->renameXrUser($m[1]);
break; break;
case preg_match('~^/resetXrUser (\d+)$~', $this->input['callback'], $m):
$this->resetXrUser($m[1]);
break;
case preg_match('~^/v2ray$~', $this->input['callback'], $m): case preg_match('~^/v2ray$~', $this->input['callback'], $m):
$this->v2ray(); $this->v2ray();
break; break;
@@ -540,6 +544,9 @@ class Bot
case preg_match('~^/xtlsprocess(?: (\d+))?$~', $this->input['callback'], $m): case preg_match('~^/xtlsprocess(?: (\d+))?$~', $this->input['callback'], $m):
$this->xtlsprocess($m[1] ?: 0); $this->xtlsprocess($m[1] ?: 0);
break; 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): case preg_match('~^/xtlsrulesset(?: (\d+))?$~', $this->input['callback'], $m):
$this->xtlsrulesset($m[1] ?: 0); $this->xtlsrulesset($m[1] ?: 0);
break; 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['inbounds'][0]['settings']['clients'] = array_values($c['inbounds'][0]['settings']['clients']);
$c['log']['access'] = '/logs/xray'; $c['log']['access'] = '/logs/xray';
$this->ssh('pkill xray', 'xr'); foreach ($c['inbounds'] as $v) {
file_put_contents('/config/xray.json', json_encode($c, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); if ($v['tag'] == 'api') {
$this->ssh('xray run -config /xray.json > /dev/null 2>&1 &', 'xr'); $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() public function linkMtproto()
@@ -1251,10 +1320,30 @@ class Bot
$this->checkBackup($period); $this->checkBackup($period);
$this->checkCert(); $this->checkCert();
$this->autoAnalyzeLogs(); $this->autoAnalyzeLogs();
$this->xrayStatsUser();
sleep($period); 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() public function autoAnalyzeLogs()
{ {
try { try {
@@ -2612,15 +2701,15 @@ DNS-over-HTTPS with IP:
$this->xtlswarp(); $this->xtlswarp();
break; break;
case 'processlist': case 'processlist':
$this->xrayUpdateRules();
$this->xtlsprocess(); $this->xtlsprocess();
break; break;
case 'packagelist': case 'packagelist':
$this->xrayUpdateRules();
$this->xtlsapp(); $this->xtlsapp();
break; break;
case 'subnetlist':
$this->xtlssubnet();
break;
case 'rulessetlist': case 'rulessetlist':
$this->xrayUpdateRules();
$this->xtlsrulesset(); $this->xtlsrulesset();
break; break;
case 'white': case 'white':
@@ -3435,8 +3524,6 @@ DNS-over-HTTPS with IP:
'text' => $this->i18n('delete'), 'text' => $this->i18n('delete'),
'callback_data' => "/delete {$client}_$page", 'callback_data' => "/delete {$client}_$page",
], ],
],
[
[ [
'text' => $this->i18n('back'), 'text' => $this->i18n('back'),
'callback_data' => "/menu wg $page", 'callback_data' => "/menu wg $page",
@@ -3670,6 +3757,12 @@ DNS-over-HTTPS with IP:
case 'packagelist': case 'packagelist':
$dir = 'PACKAGE'; $dir = 'PACKAGE';
break; break;
case 'processlist':
$dir = 'PROCESS';
break;
case 'subnetlist':
$dir = 'SUBNET';
break;
case 'rulessetlist': case 'rulessetlist':
$dir = 'rulesset'; $dir = 'rulesset';
break; break;
@@ -3716,6 +3809,22 @@ DNS-over-HTTPS with IP:
], ],
]; ];
break; 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': case 'rulessetlist':
$data[] = [ $data[] = [
[ [
@@ -3863,7 +3972,25 @@ DNS-over-HTTPS with IP:
$text[] = "Menu -> " . $this->i18n('xray') . ' -> ' . $this->i18n('routes') . ' -> process list'; $text[] = "Menu -> " . $this->i18n('xray') . ' -> ' . $this->i18n('routes') . ' -> process list';
[$data] = $this->listPac('processlist', $page, 'xtlsprocess'); [$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[] = [ $data[] = [
[ [
'text' => $this->i18n('back'), 'text' => $this->i18n('back'),
@@ -3919,7 +4046,7 @@ DNS-over-HTTPS with IP:
} }
$data[] = [ $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), 'callback_data' => "/change$type " . ($i + $page * $this->limit),
], ],
[ [
@@ -4119,12 +4246,6 @@ DNS-over-HTTPS with IP:
'main' => [ 'main' => [
'text' => implode("\n", $main ?: []), 'text' => implode("\n", $main ?: []),
'data' => [ 'data' => [
[
[
'text' => $this->i18n('config'),
'callback_data' => "/menu config",
],
],
[ [
[ [
'text' => $this->i18n($this->getPacConf()['amnezia'] ? 'amnezia' : 'wg_title'), 'text' => $this->i18n($this->getPacConf()['amnezia'] ? 'amnezia' : 'wg_title'),
@@ -4175,10 +4296,16 @@ DNS-over-HTTPS with IP:
'callback_data' => "/pacMenu 0", 'callback_data' => "/pacMenu 0",
], ],
], ],
[
[
'text' => $this->i18n('config'),
'callback_data' => "/menu config",
],
],
[ [
[ [
'text' => $this->i18n('chat'), 'text' => $this->i18n('chat'),
'url' => "https://t.me/+Wfxg6-nrokBlMmYy", 'url' => base64_decode('aHR0cHM6Ly90Lm1lLytXZnhnNi1ucm9rQmxNbVl5'),
], ],
[ [
'text' => $this->i18n('donate'), 'text' => $this->i18n('donate'),
@@ -4426,7 +4553,6 @@ DNS-over-HTTPS with IP:
} }
$t = [ $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_default_access', $xr, 'possibly a scanner', true),
$this->suspicious($this->reg, '/logs/nginx_domain_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)) { if (!empty($return)) {
return $ip; return $ip;
} }
@@ -5137,15 +5272,15 @@ DNS-over-HTTPS with IP:
public function setTimerXr($time, $i) public function setTimerXr($time, $i)
{ {
$time = strtotime($time);
if ($time === false) {
$this->send($this->input['chat'], 'wrong format');
return;
}
$c = $this->getXray(); $c = $this->getXray();
if (empty($time)) { if (empty($time)) {
unset($c['inbounds'][0]['settings']['clients'][$i]['time']); unset($c['inbounds'][0]['settings']['clients'][$i]['time']);
} else { } else {
$time = strtotime($time);
if ($time === false) {
$this->send($this->input['chat'], 'wrong format');
return;
}
if (!empty($c['inbounds'][0]['settings']['clients'][$i]['off'])) { if (!empty($c['inbounds'][0]['settings']['clients'][$i]['off'])) {
$this->switchXr($i, 1); $this->switchXr($i, 1);
$c = $this->getXray(); $c = $this->getXray();
@@ -5182,6 +5317,17 @@ DNS-over-HTTPS with IP:
$this->userXr($i); $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) public function listXr($i)
{ {
$c = $this->getPacConf(); $c = $this->getPacConf();
@@ -5314,14 +5460,7 @@ DNS-over-HTTPS with IP:
public function downloadOrigin($type) public function downloadOrigin($type)
{ {
switch ($type) { $f = new \CURLFile("/config/$type.json", 'application/json', 'origin.json');
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;
}
$this->sendFile($this->input['chat'], $f); $this->sendFile($this->input['chat'], $f);
} }
@@ -5355,6 +5494,7 @@ DNS-over-HTTPS with IP:
<code>~pac~</code> <code>~pac~</code>
<code>~package~</code> <code>~package~</code>
<code>~process~</code> <code>~process~</code>
<code>~subnet~</code>
<code>~block~</code> <code>~block~</code>
<code>~warp~</code> <code>~warp~</code>
<code>~dns~</code> <code>~dns~</code>
@@ -5363,6 +5503,7 @@ DNS-over-HTTPS with IP:
<code>~directdomain~</code> <code>~directdomain~</code>
<code>~cdndomain~</code> <code>~cdndomain~</code>
<code>~short_id~</code> <code>~short_id~</code>
<code>~email~</code>
<code>~public_key~</code> <code>~public_key~</code>
<code>~server_name~</code> <code>~server_name~</code>
<code>~ip~</code> <code>~ip~</code>
@@ -5456,6 +5597,25 @@ DNS-over-HTTPS with IP:
$this->xray(); $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) public function xray($page = 0)
{ {
if (!$this->ssh('pgrep xray', 'xr')) { if (!$this->ssh('pgrep xray', 'xr')) {
@@ -5538,10 +5698,12 @@ DNS-over-HTTPS with IP:
$page = $page == -2 ? $all - 1 : $page; $page = $page == -2 ? $all - 1 : $page;
$clients = $page != -1 ? array_slice($clients, $page * $this->limit, $this->limit, true) : $clients; $clients = $page != -1 ? array_slice($clients, $page * $this->limit, $this->limit, true) : $clients;
foreach ($clients as $k => $v) { foreach ($clients as $k => $v) {
$time = $v['time'] ? $this->getTime($v['time']) : ''; $download = $this->getBytes($v['global']['download'] + $v['session']['download']);
$data[] = [ $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", 'callback_data' => "/userXr $k",
], ],
]; ];
@@ -5591,9 +5753,6 @@ DNS-over-HTTPS with IP:
{ {
$text[] = "Menu -> " . $this->i18n('xray') . ' -> routes'; $text[] = "Menu -> " . $this->i18n('xray') . ' -> routes';
$p = $this->getPacConf();
$outbound = $p['outbound'] ?: 'proxy';
$data = [ $data = [
[[ [[
'text' => $this->i18n('block'), 'text' => $this->i18n('block'),
@@ -5607,6 +5766,10 @@ DNS-over-HTTPS with IP:
'text' => 'domains', 'text' => 'domains',
'callback_data' => "/xtlsproxy", 'callback_data' => "/xtlsproxy",
]], ]],
[[
'text' => "subnet",
'callback_data' => "/xtlssubnet",
]],
[[ [[
'text' => 'process', 'text' => 'process',
'callback_data' => "/xtlsprocess", 'callback_data' => "/xtlsprocess",
@@ -5885,6 +6048,14 @@ DNS-over-HTTPS with IP:
'callback_data' => "/qrXray {$i}_2", '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[] = [ $data[] = [
[ [
'text' => $this->i18n('rename'), 'text' => $this->i18n('rename'),
@@ -6125,12 +6296,14 @@ DNS-over-HTTPS with IP:
'"~warp~"' => json_encode(array_keys(array_filter($pac['warplist'] ?: []))), '"~warp~"' => json_encode(array_keys(array_filter($pac['warplist'] ?: []))),
'"~process~"' => json_encode(array_keys(array_filter($pac['processlist'] ?: []))), '"~process~"' => json_encode(array_keys(array_filter($pac['processlist'] ?: []))),
'"~package~"' => json_encode(array_keys(array_filter($pac['packagelist'] ?: []))), '"~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", '~dns~' => "https://$domain/dns-query$hash/$uid",
'~uid~' => $uid, '~uid~' => $uid,
'~domain~' => $domain, '~domain~' => $domain,
'~directdomain~' => $pac['domain'], '~directdomain~' => $pac['domain'],
'~cdndomain~' => $pac['linkdomain'], '~cdndomain~' => $pac['linkdomain'],
'~short_id~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0], '~short_id~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['shortIds'][0],
'~email~' => $email,
'~public_key~' => $pac['xray'], '~public_key~' => $pac['xray'],
'~server_name~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0], '~server_name~' => $xr['inbounds'][0]['streamSettings']['realitySettings']['serverNames'][0],
'~ip~' => $this->ip, '~ip~' => $this->ip,
@@ -6234,6 +6407,9 @@ DNS-over-HTTPS with IP:
case 'domain': case 'domain':
echo yaml_emit(['payload' => array_map(fn($e) => "+.$e", $v['list'])]); echo yaml_emit(['payload' => array_map(fn($e) => "+.$e", $v['list'])]);
break; break;
case 'ipcidr':
echo yaml_emit(['payload' => array_map(fn($e) => $e, $v['list'])]);
break;
default: default:
echo yaml_emit(['payload' => array_map(fn($e) => "PROCESS-NAME,$e", $v['list'])]); 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'), 'text' => $this->i18n('Ports'),
'callback_data' => "/ports", 'callback_data' => "/ports",
], ],
];
$data[] = [
[ [
'text' => $this->i18n('IP ban & Logs'), 'text' => $this->i18n('IP ban & Logs'),
'callback_data' => "/ipMenu", 'callback_data' => "/ipMenu",
@@ -6919,6 +7097,7 @@ DNS-over-HTTPS with IP:
$text[] = 'Settings -> Ports'; $text[] = 'Settings -> Ports';
$f = '/docker/compose'; $f = '/docker/compose';
$c = yaml_parse_file($f)['services']; $c = yaml_parse_file($f)['services'];
$pac = $this->getPacConf();
$data = [ $data = [
[[ [[
'text' => $this->i18n($c['wg'] ? 'on' : 'off') . ' ' . getenv('WGPORT') . ' Wireguard', 'text' => $this->i18n($c['wg'] ? 'on' : 'off') . ' ' . getenv('WGPORT') . ' Wireguard',
@@ -6941,6 +7120,14 @@ DNS-over-HTTPS with IP:
'callback_data' => "/hidePort ss", 'callback_data' => "/hidePort ss",
]], ]],
]; ];
if (!empty($pac['restart'])) {
$data[] = [
[
'text' => $this->i18n('restart'),
'callback_data' => "/restart",
],
];
}
$data[] = [ $data[] = [
[ [
'text' => $this->i18n('back'), 'text' => $this->i18n('back'),
@@ -6976,7 +7163,10 @@ DNS-over-HTTPS with IP:
} else { } else {
yaml_emit_file($f, $c); yaml_emit_file($f, $c);
} }
$this->restart(); $pac = $this->getPacConf();
$pac['restart'] = 1;
$this->setPacConf($pac);
$this->ports();
} }
public function branches() public function branches()
@@ -7113,6 +7303,9 @@ DNS-over-HTTPS with IP:
} }
file_put_contents('/update/message', ''); file_put_contents('/update/message', '');
file_put_contents('/update/reload_message', ''); file_put_contents('/update/reload_message', '');
$pac = $this->getPacConf();
unset($pac['restart']);
$this->setPacConf($pac);
} }
public function backup() public function backup()
+1 -1
View File
@@ -30,7 +30,7 @@ $i = [
'ru' => 'PAC', 'ru' => 'PAC',
], ],
'chat' => [ 'chat' => [
'en' => 'discussion group', 'en' => 'chat',
'ru' => 'чат поддержки', 'ru' => 'чат поддержки',
], ],
'back' => [ 'back' => [
+8
View File
@@ -133,6 +133,14 @@
"behavior": "domain", "behavior": "domain",
"name": "pac" "name": "pac"
}, },
{
"type": "RULE-SET",
"list": "~subnet~",
"action": "PROXY",
"interval": 30,
"behavior": "ipcidr",
"name": "subnet"
},
{ {
"type": "MATCH", "type": "MATCH",
"action": "DIRECT" "action": "DIRECT"
+15
View File
@@ -129,6 +129,21 @@
], ],
"outbound": "~outbound~" "outbound": "~outbound~"
}, },
{
"addruleset": true,
"createruleset": [
{
"name": "subnet",
"interval": "30s",
"rules": [
{
"ip_cidr": "~subnet~"
}
]
}
],
"outbound": "~outbound~"
},
{ {
"addruleset": true, "addruleset": true,
"createruleset": [ "createruleset": [
+111 -81
View File
@@ -4,92 +4,122 @@
"error": "", "error": "",
"loglevel": "warning" "loglevel": "warning"
}, },
"inbounds": [{ "inbounds": [
"tag": "socks", {
"port": 10808, "tag": "socks",
"listen": "127.0.0.1", "port": 10808,
"protocol": "socks", "listen": "127.0.0.1",
"sniffing": { "protocol": "socks",
"enabled": true, "sniffing": {
"destOverride": ["http", "tls"], "enabled": true,
"routeOnly": false "destOverride": [
}, "http",
"settings": { "tls"
"auth": "noauth", ],
"udp": true, "routeOnly": false
"allowTransparent": false },
} "settings": {
}, { "auth": "noauth",
"tag": "http", "udp": true,
"port": 10809, "allowTransparent": false
"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": ""
} }
}, },
"mux": { {
"enabled": false, "tag": "http",
"concurrency": -1 "port": 10809,
} "listen": "127.0.0.1",
}, { "protocol": "http",
"tag": "direct", "sniffing": {
"protocol": "freedom" "enabled": true,
}, { "destOverride": [
"tag": "block", "http",
"protocol": "blackhole", "tls"
"settings": { ],
"response": { "routeOnly": false
"type": "http" },
"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": { "routing": {
"domainStrategy": "AsIs", "domainStrategy": "AsIs",
"rules": [{ "rules": [
"type": "field", {
"outboundTag": "~outbound~", "type": "field",
"domain": "~pac~" "outboundTag": "block",
}, { "domain": "~block~"
"type": "field", },
"port": "0-65535", {
"outboundTag": "direct" "type": "field",
}] "outboundTag": "~outbound~",
"domain": "~pac~"
},
{
"type": "field",
"outboundTag": "~outbound~",
"ip": "~subnet~"
},
{
"type": "field",
"outboundTag": "~outbound~",
"domain": "~warp~"
}
]
} }
} }
+39 -1
View File
@@ -22,6 +22,15 @@
} }
}, },
"tag": "vless_tls" "tag": "vless_tls"
},
{
"listen": "127.0.0.1",
"port": 8080,
"protocol": "dokodemo-door",
"settings": {
"address": "127.0.0.1"
},
"tag": "api"
} }
], ],
"log": { "log": {
@@ -40,6 +49,35 @@
], ],
"routing": { "routing": {
"domainStrategy": "AsIs", "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
}
} }
} }
+10 -1
View File
@@ -13,8 +13,17 @@ telegram bot to manage servers (inside the bot)
--- ---
environment: ubuntu 22.04/24.04, debian 11/12 environment: ubuntu 22.04/24.04, debian 11/12
### Install: ## Install:
```shell ```shell
wget -O- https://raw.githubusercontent.com/mercurykd/vpnbot/master/scripts/init.sh | sh -s YOUR_TELEGRAM_BOT_KEY master 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.
+15
View File
@@ -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 07.01.2025 v2.4
- вернул shadowsocks (спасибо за донат) - вернул shadowsocks (спасибо за донат)
04.01.2025 04.01.2025