Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 24aaa8756c | |||
| 07e2beff9b | |||
| 86261e6b76 | |||
| d816582e6f | |||
| 6d1ab0cb3a | |||
| 284b025881 | |||
| 0ca93b56a3 | |||
| 7bcd8de007 | |||
| 34eb950852 | |||
| 46021855a5 | |||
| 29c18ceb9d | |||
| 49d0827b9e | |||
| 07e04c384a | |||
| 579457b4f4 | |||
| 3dac9416ca | |||
| 5b4d3b5627 | |||
| 658e125cd8 | |||
| 1840555573 | |||
| ecdc028226 | |||
| d432bf82f2 | |||
| 211e2c079d | |||
| 1696c4da7b | |||
| b8d5700eba | |||
| 7e20c14299 | |||
| b9155cf674 | |||
| 159f775e12 | |||
| ae672439be | |||
| 6dafba5618 | |||
| 7daf61a4f5 | |||
| f9266827c9 | |||
| 9e22c64771 | |||
| a2026a4436 | |||
| 95c5b5b8fd | |||
| efbe20485a | |||
| 475eea1f47 | |||
| 02d9cdcccc | |||
| d633799f11 | |||
| ead66c3951 | |||
| bd7742d8b2 | |||
| ac593629a8 |
+355
-69
@@ -37,20 +37,9 @@ class Bot
|
|||||||
'xray',
|
'xray',
|
||||||
];
|
];
|
||||||
$this->reg = '~' . implode('|', [
|
$this->reg = '~' . implode('|', [
|
||||||
'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 / 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',
|
'GET /favicon.ico HTTP',
|
||||||
|
preg_quote($this->getHashBot())
|
||||||
]) . '~';
|
]) . '~';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,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();
|
||||||
@@ -307,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):
|
||||||
@@ -358,12 +348,18 @@ class Bot
|
|||||||
case preg_match('~^/changeCamouflage$~', $this->input['callback'], $m):
|
case preg_match('~^/changeCamouflage$~', $this->input['callback'], $m):
|
||||||
$this->changeCamouflage();
|
$this->changeCamouflage();
|
||||||
break;
|
break;
|
||||||
|
case preg_match('~^/changeOcDomain$~', $this->input['callback'], $m):
|
||||||
|
$this->changeOcDomain();
|
||||||
|
break;
|
||||||
case preg_match('~^/changeOcPass$~', $this->input['callback'], $m):
|
case preg_match('~^/changeOcPass$~', $this->input['callback'], $m):
|
||||||
$this->changeOcPass();
|
$this->changeOcPass();
|
||||||
break;
|
break;
|
||||||
case preg_match('~^/changeNaiveUser$~', $this->input['callback'], $m):
|
case preg_match('~^/changeNaiveUser$~', $this->input['callback'], $m):
|
||||||
$this->changeNaiveUser();
|
$this->changeNaiveUser();
|
||||||
break;
|
break;
|
||||||
|
case preg_match('~^/changeNaiveSubdomain$~', $this->input['callback'], $m):
|
||||||
|
$this->changeNaiveSubdomain();
|
||||||
|
break;
|
||||||
case preg_match('~^/changeNaivePass$~', $this->input['callback'], $m):
|
case preg_match('~^/changeNaivePass$~', $this->input['callback'], $m):
|
||||||
$this->changeNaivePass();
|
$this->changeNaivePass();
|
||||||
break;
|
break;
|
||||||
@@ -382,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;
|
||||||
@@ -545,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;
|
||||||
@@ -672,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()
|
||||||
@@ -816,7 +880,7 @@ class Bot
|
|||||||
$this->input['chat'],
|
$this->input['chat'],
|
||||||
"@{$this->input['username']} enter camouflage key",
|
"@{$this->input['username']} enter camouflage key",
|
||||||
$this->input['message_id'],
|
$this->input['message_id'],
|
||||||
reply: 'enter password',
|
reply: 'enter camouflage key',
|
||||||
);
|
);
|
||||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||||
'start_message' => $this->input['message_id'],
|
'start_message' => $this->input['message_id'],
|
||||||
@@ -826,6 +890,22 @@ class Bot
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function changeOcDomain()
|
||||||
|
{
|
||||||
|
$r = $this->send(
|
||||||
|
$this->input['chat'],
|
||||||
|
"@{$this->input['username']} enter subdomain",
|
||||||
|
$this->input['message_id'],
|
||||||
|
reply: 'enter subdomain',
|
||||||
|
);
|
||||||
|
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||||
|
'start_message' => $this->input['message_id'],
|
||||||
|
'start_callback' => $this->input['callback_id'],
|
||||||
|
'callback' => 'chOcSubdomain',
|
||||||
|
'args' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function changeOcDns()
|
public function changeOcDns()
|
||||||
{
|
{
|
||||||
$r = $this->send(
|
$r = $this->send(
|
||||||
@@ -864,7 +944,7 @@ class Bot
|
|||||||
$this->input['chat'],
|
$this->input['chat'],
|
||||||
"@{$this->input['username']} enter login",
|
"@{$this->input['username']} enter login",
|
||||||
$this->input['message_id'],
|
$this->input['message_id'],
|
||||||
reply: 'enter password',
|
reply: 'enter login',
|
||||||
);
|
);
|
||||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||||
'start_message' => $this->input['message_id'],
|
'start_message' => $this->input['message_id'],
|
||||||
@@ -874,6 +954,22 @@ class Bot
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function changeNaiveSubdomain()
|
||||||
|
{
|
||||||
|
$r = $this->send(
|
||||||
|
$this->input['chat'],
|
||||||
|
"@{$this->input['username']} enter subdomain",
|
||||||
|
$this->input['message_id'],
|
||||||
|
reply: 'enter subdomain',
|
||||||
|
);
|
||||||
|
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||||
|
'start_message' => $this->input['message_id'],
|
||||||
|
'start_callback' => $this->input['callback_id'],
|
||||||
|
'callback' => 'chNpSubdomain',
|
||||||
|
'args' => [],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public function changeNaivePass()
|
public function changeNaivePass()
|
||||||
{
|
{
|
||||||
$r = $this->send(
|
$r = $this->send(
|
||||||
@@ -987,6 +1083,34 @@ class Bot
|
|||||||
$this->menu('oc');
|
$this->menu('oc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function chOcSubdomain($domain)
|
||||||
|
{
|
||||||
|
$pac = $this->getPacConf();
|
||||||
|
if (empty($domain)) {
|
||||||
|
unset($pac["oc_domain"]);
|
||||||
|
} else {
|
||||||
|
$pac["oc_domain"] = $domain;
|
||||||
|
}
|
||||||
|
$this->setPacConf($pac);
|
||||||
|
$this->chocdomain($pac['domain']);
|
||||||
|
$this->setUpstreamDomainOcserv($pac['domain']);
|
||||||
|
$this->menu('oc');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function chNpSubdomain($domain)
|
||||||
|
{
|
||||||
|
$pac = $this->getPacConf();
|
||||||
|
if (!empty($data)) {
|
||||||
|
unset($pac['np_domain']);
|
||||||
|
} else {
|
||||||
|
$pac['np_domain'] = $domain;
|
||||||
|
}
|
||||||
|
$this->setPacConf($pac);
|
||||||
|
$this->restartNaive();
|
||||||
|
$this->setUpstreamDomainNaive($pac['domain']);
|
||||||
|
$this->menu('naive');
|
||||||
|
}
|
||||||
|
|
||||||
public function chnplogin($user)
|
public function chnplogin($user)
|
||||||
{
|
{
|
||||||
$pac = $this->getPacConf();
|
$pac = $this->getPacConf();
|
||||||
@@ -1196,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 {
|
||||||
@@ -1476,6 +1620,8 @@ class Bot
|
|||||||
'xray' => $this->getXray(),
|
'xray' => $this->getXray(),
|
||||||
'oc' => file_get_contents('/config/ocserv.conf'),
|
'oc' => file_get_contents('/config/ocserv.conf'),
|
||||||
'ocu' => file_get_contents('/config/ocserv.passwd'),
|
'ocu' => file_get_contents('/config/ocserv.passwd'),
|
||||||
|
'ss' => $this->getSSConfig(),
|
||||||
|
'sl' => $this->getSSLocalConfig(),
|
||||||
|
|
||||||
];
|
];
|
||||||
return json_encode($conf, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
return json_encode($conf, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||||
@@ -1557,6 +1703,22 @@ class Bot
|
|||||||
yaml_emit_file($this->adguard, $json['ad']);
|
yaml_emit_file($this->adguard, $json['ad']);
|
||||||
$this->startAd();
|
$this->startAd();
|
||||||
}
|
}
|
||||||
|
// ss
|
||||||
|
if (!empty($json['ss'])) {
|
||||||
|
$out[] = 'update shadowsocks server';
|
||||||
|
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
||||||
|
$this->ssh('pkill ssserver', 'ss');
|
||||||
|
file_put_contents('/config/ssserver.json', json_encode($json['ss'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||||
|
$this->ssh('ssserver -v -d -c /config.json', 'ss');
|
||||||
|
}
|
||||||
|
// sl
|
||||||
|
if (!empty($json['sl'])) {
|
||||||
|
$out[] = 'update shadowsocks proxy';
|
||||||
|
$this->update($this->input['chat'], $this->input['message_id'], implode("\n", $out));
|
||||||
|
$this->ssh('pkill sslocal', 'proxy');
|
||||||
|
file_put_contents('/config/sslocal.json', json_encode($json['sl'], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
||||||
|
$this->ssh('sslocal -v -d -c /config.json', 'proxy');
|
||||||
|
}
|
||||||
// mtproto
|
// mtproto
|
||||||
if (!empty($json['mtproto'])) {
|
if (!empty($json['mtproto'])) {
|
||||||
$out[] = 'update mtproto';
|
$out[] = 'update mtproto';
|
||||||
@@ -2539,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':
|
||||||
@@ -3362,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",
|
||||||
@@ -3597,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;
|
||||||
@@ -3643,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[] = [
|
||||||
[
|
[
|
||||||
@@ -3790,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'),
|
||||||
@@ -3846,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),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -3940,14 +4140,12 @@ DNS-over-HTTPS with IP:
|
|||||||
|
|
||||||
public function menuSS()
|
public function menuSS()
|
||||||
{
|
{
|
||||||
$conf = $this->getPacConf();
|
$hash = $this->getHashBot();
|
||||||
$ip = $this->ip;
|
|
||||||
$domain = $this->getDomain();
|
$domain = $this->getDomain();
|
||||||
$scheme = empty($ssl = $this->nginxGetTypeCert()) ? 'http' : 'https';
|
|
||||||
$ss = $this->getSSConfig();
|
$ss = $this->getSSConfig();
|
||||||
$v2ray = !empty($ss['plugin']) ? 'ON' : 'OFF';
|
$v2ray = !empty($ss['plugin']) ? 'ON' : 'OFF';
|
||||||
$port = !empty($ss['plugin']) ? (!empty($ssl) ? 443 : 80) : getenv('SSPORT');
|
$port = !empty($ss['plugin']) ? 443 : getenv('SSPORT');
|
||||||
$options = !empty($ssl) && !empty($ss['plugin']) ? "tls;fast-open;path=/v2ray;host=$domain" : "path=/v2ray;host=$domain";
|
$options = !empty($ss['plugin']) ? "tls;fast-open;path=/v2ray$hash;host=$domain" : "path=/v2ray$hash;host=$domain";
|
||||||
|
|
||||||
$text = "Menu -> ShadowSocks";
|
$text = "Menu -> ShadowSocks";
|
||||||
$data[] = [
|
$data[] = [
|
||||||
@@ -3956,7 +4154,7 @@ DNS-over-HTTPS with IP:
|
|||||||
'callback_data' => "/sspswd",
|
'callback_data' => "/sspswd",
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
$ss_link = preg_replace('~==~', '', 'ss://' . base64_encode("{$ss['method']}:{$ss['password']}")) . "@$domain:$port" . (!empty($ss['plugin']) ? '?plugin=' . urlencode("v2ray-plugin;path=/v2ray;host=$domain" . (!empty($ssl) ? ';tls' : '')) : '');
|
$ss_link = preg_replace('~==~', '', 'ss://' . base64_encode("{$ss['method']}:{$ss['password']}")) . "@$domain:$port" . (!empty($ss['plugin']) ? '?plugin=' . urlencode("v2ray-plugin;path=/v2ray$hash;host=$domain;tls") : '');
|
||||||
$text .= "\n\n<code>$ss_link</code>\n";
|
$text .= "\n\n<code>$ss_link</code>\n";
|
||||||
$text .= "\n\npassword: <span class='tg-spoiler'>{$ss['password']}</span>";
|
$text .= "\n\npassword: <span class='tg-spoiler'>{$ss['password']}</span>";
|
||||||
$text .= "\n\nserver: <code>$domain:$port</code>";
|
$text .= "\n\nserver: <code>$domain:$port</code>";
|
||||||
@@ -4024,16 +4222,17 @@ DNS-over-HTTPS with IP:
|
|||||||
$c = yaml_parse_file($f)['services'];
|
$c = yaml_parse_file($f)['services'];
|
||||||
$main[] = 'v' . getenv('VER') . " $branch" . ($update ? ' (have updates)' : '');
|
$main[] = 'v' . getenv('VER') . " $branch" . ($update ? ' (have updates)' : '');
|
||||||
$main[] = '';
|
$main[] = '';
|
||||||
$main[] = $this->i18n($c['wg'] ? 'on' : 'off') . ' ' . getenv('WGPORT') . ' Wireguard';
|
|
||||||
$main[] = $this->i18n($c['wg1'] ? 'on' : 'off') . ' ' . getenv('WG1PORT') . ' Wireguard 1';
|
|
||||||
$main[] = $this->i18n($c['tg'] ? 'on' : 'off') . ' ' . getenv('TGPORT') . ' MTProto';
|
|
||||||
$main[] = $this->i18n($c['ad'] ? 'on' : 'off') . ' 853 AdguardHome DoT';
|
|
||||||
$main[] = '';
|
|
||||||
$main[] = $cron;
|
$main[] = $cron;
|
||||||
$main[] = $this->i18n($backup ? 'on' : 'off') . ' autobackup' . ($backup ? " $backup" : '');
|
$main[] = $this->i18n($backup ? 'on' : 'off') . ' autobackup' . ($backup ? " $backup" : '');
|
||||||
$main[] = $this->i18n($conf['autoupdate'] ? 'on' : 'off') . ' autoupdate';
|
$main[] = $this->i18n($conf['autoupdate'] ? 'on' : 'off') . ' autoupdate';
|
||||||
$main[] = $this->i18n($conf['autoscan'] ? 'on' : 'off') . ' autoscan';
|
$main[] = $this->i18n($conf['autoscan'] ? 'on' : 'off') . ' autoscan';
|
||||||
$main[] = $this->i18n($conf['autodeny'] ? 'on' : 'off') . ' autoblock' . ($conf['deny'] ? ': ' . count($conf['deny']) : '');
|
$main[] = $this->i18n($conf['autodeny'] ? 'on' : 'off') . ' autoblock' . ($conf['deny'] ? ': ' . count($conf['deny']) : '');
|
||||||
|
$main[] = '';
|
||||||
|
$main[] = $this->i18n($c['wg'] ? 'on' : 'off') . ' ' . getenv('WGPORT') . ' Wireguard';
|
||||||
|
$main[] = $this->i18n($c['wg1'] ? 'on' : 'off') . ' ' . getenv('WG1PORT') . ' Wireguard 1';
|
||||||
|
$main[] = $this->i18n($c['tg'] ? 'on' : 'off') . ' ' . getenv('TGPORT') . ' MTProto';
|
||||||
|
$main[] = $this->i18n($c['ad'] ? 'on' : 'off') . ' 853 AdguardHome DoT';
|
||||||
|
$main[] = $this->i18n($c['ss'] ? 'on' : 'off') . ' 8388 Shadowsocks';
|
||||||
if (!empty($conf['domain'])) {
|
if (!empty($conf['domain'])) {
|
||||||
$main[] = '';
|
$main[] = '';
|
||||||
$oc = $this->getHashSubdomain('oc');
|
$oc = $this->getHashSubdomain('oc');
|
||||||
@@ -4047,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'),
|
||||||
@@ -4094,15 +4287,25 @@ DNS-over-HTTPS with IP:
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
|
[
|
||||||
|
'text' => $this->i18n('sh_title'),
|
||||||
|
'callback_data' => "/menu ss",
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'text' => $this->i18n('pac'),
|
'text' => $this->i18n('pac'),
|
||||||
'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'),
|
||||||
@@ -4350,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),
|
||||||
];
|
];
|
||||||
@@ -4362,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;
|
||||||
}
|
}
|
||||||
@@ -4823,6 +5034,12 @@ DNS-over-HTTPS with IP:
|
|||||||
$text[] = "Menu -> NaiveProxy";
|
$text[] = "Menu -> NaiveProxy";
|
||||||
$np = $this->getHashSubdomain('np');
|
$np = $this->getHashSubdomain('np');
|
||||||
$text[] = "<code>https://{$pac['naive']['user']}:{$pac['naive']['pass']}@$np.$domain</code>";
|
$text[] = "<code>https://{$pac['naive']['user']}:{$pac['naive']['pass']}@$np.$domain</code>";
|
||||||
|
$data[] = [
|
||||||
|
[
|
||||||
|
'text' => $this->i18n('change subdomain'),
|
||||||
|
'callback_data' => "/changeNaiveSubdomain",
|
||||||
|
],
|
||||||
|
];
|
||||||
$data[] = [
|
$data[] = [
|
||||||
[
|
[
|
||||||
'text' => $this->i18n('change login'),
|
'text' => $this->i18n('change login'),
|
||||||
@@ -4926,6 +5143,12 @@ DNS-over-HTTPS with IP:
|
|||||||
$text[] = "<code>https://$oc.$domain/?$cs</code>";
|
$text[] = "<code>https://$oc.$domain/?$cs</code>";
|
||||||
}
|
}
|
||||||
$text[] = "password: <span class='tg-spoiler'>$pass</span>";
|
$text[] = "password: <span class='tg-spoiler'>$pass</span>";
|
||||||
|
$data[] = [
|
||||||
|
[
|
||||||
|
'text' => $this->i18n('change subdomain'),
|
||||||
|
'callback_data' => "/changeOcDomain",
|
||||||
|
],
|
||||||
|
];
|
||||||
$data[] = [
|
$data[] = [
|
||||||
[
|
[
|
||||||
'text' => $this->i18n('change secret'),
|
'text' => $this->i18n('change secret'),
|
||||||
@@ -5049,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();
|
||||||
@@ -5094,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();
|
||||||
@@ -5226,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5267,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>
|
||||||
@@ -5275,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>
|
||||||
@@ -5368,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')) {
|
||||||
@@ -5450,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",
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@@ -5503,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'),
|
||||||
@@ -5519,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",
|
||||||
@@ -5797,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'),
|
||||||
@@ -6037,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,
|
||||||
@@ -6063,11 +6324,11 @@ DNS-over-HTTPS with IP:
|
|||||||
$c['route'] = $this->addRuleSet($c['route']);
|
$c['route'] = $this->addRuleSet($c['route']);
|
||||||
$c['route'] = $this->createRuleSet($c['route'], $uid, $domain);
|
$c['route'] = $this->createRuleSet($c['route'], $uid, $domain);
|
||||||
if (!empty($c['route']['rules'])) {
|
if (!empty($c['route']['rules'])) {
|
||||||
foreach ($c['route']['rules'] as $k => $v) {
|
/* foreach ($c['route']['rules'] as $k => $v) {
|
||||||
if (count($v) < 2) {
|
if (count($v) < 2) {
|
||||||
unset($c['route']['rules'][$k]);
|
unset($c['route']['rules'][$k]);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
$c['route']['rules'] = array_values($c['route']['rules']);
|
$c['route']['rules'] = array_values($c['route']['rules']);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -6146,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'])]);
|
||||||
@@ -6373,7 +6637,7 @@ DNS-over-HTTPS with IP:
|
|||||||
location
|
location
|
||||||
CONF;
|
CONF;
|
||||||
$template = preg_replace('~(location /adguard.+?})\s*location~s', $r, $template);
|
$template = preg_replace('~(location /adguard.+?})\s*location~s', $r, $template);
|
||||||
$template = preg_replace('~(/webapp|/pac|/adguard|/ws|location /dns-query)~', '${1}' . $h, $template);
|
$template = preg_replace('~(/webapp|/pac|/adguard|/ws|/v2ray|location /dns-query)~', '${1}' . $h, $template);
|
||||||
file_put_contents('/config/nginx.conf', $template);
|
file_put_contents('/config/nginx.conf', $template);
|
||||||
$x = $this->getXray();
|
$x = $this->getXray();
|
||||||
if (!empty($x['inbounds'][0]['streamSettings']['wsSettings']['path'])) {
|
if (!empty($x['inbounds'][0]['streamSettings']['wsSettings']['path'])) {
|
||||||
@@ -6386,7 +6650,7 @@ DNS-over-HTTPS with IP:
|
|||||||
|
|
||||||
public function getHashSubdomain($subdomain)
|
public function getHashSubdomain($subdomain)
|
||||||
{
|
{
|
||||||
return substr(hash('sha256', "$subdomain{$this->key}"), 0, 8);
|
return $this->getPacConf()["{$subdomain}_domain"] ?: substr(hash('sha256', "$subdomain{$this->key}"), 0, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addWg($page)
|
public function addWg($page)
|
||||||
@@ -6741,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",
|
||||||
@@ -6831,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',
|
||||||
@@ -6848,7 +7115,19 @@ DNS-over-HTTPS with IP:
|
|||||||
'text' => $this->i18n($c['ad'] ? 'on' : 'off') . ' 853 AdguardHome DoT',
|
'text' => $this->i18n($c['ad'] ? 'on' : 'off') . ' 853 AdguardHome DoT',
|
||||||
'callback_data' => "/hidePort ad",
|
'callback_data' => "/hidePort ad",
|
||||||
]],
|
]],
|
||||||
|
[[
|
||||||
|
'text' => $this->i18n($c['ss'] ? 'on' : 'off') . ' 8388 Shadowsocks',
|
||||||
|
'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'),
|
||||||
@@ -6870,6 +7149,7 @@ DNS-over-HTTPS with IP:
|
|||||||
'wg1' => getenv('WG1PORT') . ':' . getenv('WG1PORT') . '/udp',
|
'wg1' => getenv('WG1PORT') . ':' . getenv('WG1PORT') . '/udp',
|
||||||
'tg' => getenv('TGPORT') . ':' . getenv('TGPORT'),
|
'tg' => getenv('TGPORT') . ':' . getenv('TGPORT'),
|
||||||
'ad' => '853:853',
|
'ad' => '853:853',
|
||||||
|
'ss' => '8388:8388',
|
||||||
];
|
];
|
||||||
$f = '/docker/compose';
|
$f = '/docker/compose';
|
||||||
$c = yaml_parse_file($f);
|
$c = yaml_parse_file($f);
|
||||||
@@ -6883,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()
|
||||||
@@ -7020,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
@@ -30,7 +30,7 @@ $i = [
|
|||||||
'ru' => 'PAC',
|
'ru' => 'PAC',
|
||||||
],
|
],
|
||||||
'chat' => [
|
'chat' => [
|
||||||
'en' => 'discussion group',
|
'en' => 'chat',
|
||||||
'ru' => 'чат поддержки',
|
'ru' => 'чат поддержки',
|
||||||
],
|
],
|
||||||
'back' => [
|
'back' => [
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ if ($c['debug']) {
|
|||||||
$bot = new Bot($c['key'], $i);
|
$bot = new Bot($c['key'], $i);
|
||||||
|
|
||||||
$bot->selfUpdate();
|
$bot->selfUpdate();
|
||||||
|
$bot->ssPswdCheck();
|
||||||
$bot->restartTG();
|
$bot->restartTG();
|
||||||
if (!empty($bot->selfupdate)) {
|
if (!empty($bot->selfupdate)) {
|
||||||
$bot->offWarp();
|
$bot->offWarp();
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -97,6 +97,18 @@ http {
|
|||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_read_timeout 5d;
|
proxy_read_timeout 5d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /v2ray {
|
||||||
|
access_log /logs/nginx_v2ray_access;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_pass http://ss:8388/;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
location /dns-query {
|
location /dns-query {
|
||||||
access_log /logs/nginx_doh_access;
|
access_log /logs/nginx_doh_access;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
@@ -162,6 +174,17 @@ http {
|
|||||||
# proxy_pass http://php;
|
# proxy_pass http://php;
|
||||||
# }
|
# }
|
||||||
|
|
||||||
|
# location /v2ray {
|
||||||
|
# access_log /logs/nginx_v2ray_access;
|
||||||
|
# proxy_redirect off;
|
||||||
|
# proxy_buffering off;
|
||||||
|
# proxy_http_version 1.1;
|
||||||
|
# proxy_pass http://ss:8388/;
|
||||||
|
# proxy_set_header Host $http_host;
|
||||||
|
# proxy_set_header Upgrade $http_upgrade;
|
||||||
|
# proxy_set_header Connection "upgrade";
|
||||||
|
# }
|
||||||
|
|
||||||
# location /ws {
|
# location /ws {
|
||||||
# proxy_pass http://xr:443;
|
# proxy_pass http://xr:443;
|
||||||
# proxy_redirect off;
|
# proxy_redirect off;
|
||||||
@@ -173,6 +196,7 @@ http {
|
|||||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
# proxy_read_timeout 5d;
|
# proxy_read_timeout 5d;
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# location /dns-query {
|
# location /dns-query {
|
||||||
# access_log /logs/nginx_doh_access;
|
# access_log /logs/nginx_doh_access;
|
||||||
# proxy_http_version 1.1;
|
# proxy_http_version 1.1;
|
||||||
|
|||||||
@@ -97,6 +97,18 @@ http {
|
|||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_read_timeout 5d;
|
proxy_read_timeout 5d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /v2ray {
|
||||||
|
access_log /logs/nginx_v2ray_access;
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_buffering off;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_pass http://ss:8388/;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
|
||||||
location /dns-query {
|
location /dns-query {
|
||||||
access_log /logs/nginx_doh_access;
|
access_log /logs/nginx_doh_access;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
@@ -162,6 +174,17 @@ http {
|
|||||||
# proxy_pass http://php;
|
# proxy_pass http://php;
|
||||||
# }
|
# }
|
||||||
|
|
||||||
|
# location /v2ray {
|
||||||
|
# access_log /logs/nginx_v2ray_access;
|
||||||
|
# proxy_redirect off;
|
||||||
|
# proxy_buffering off;
|
||||||
|
# proxy_http_version 1.1;
|
||||||
|
# proxy_pass http://ss:8388/;
|
||||||
|
# proxy_set_header Host $http_host;
|
||||||
|
# proxy_set_header Upgrade $http_upgrade;
|
||||||
|
# proxy_set_header Connection "upgrade";
|
||||||
|
# }
|
||||||
|
|
||||||
# location /ws {
|
# location /ws {
|
||||||
# proxy_pass http://xr:443;
|
# proxy_pass http://xr:443;
|
||||||
# proxy_redirect off;
|
# proxy_redirect off;
|
||||||
@@ -173,6 +196,7 @@ http {
|
|||||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
# proxy_read_timeout 5d;
|
# proxy_read_timeout 5d;
|
||||||
# }
|
# }
|
||||||
|
|
||||||
# location /dns-query {
|
# location /dns-query {
|
||||||
# access_log /logs/nginx_doh_access;
|
# access_log /logs/nginx_doh_access;
|
||||||
# proxy_http_version 1.1;
|
# proxy_http_version 1.1;
|
||||||
|
|||||||
+27
-16
@@ -9,9 +9,10 @@
|
|||||||
"tag": "tun-in",
|
"tag": "tun-in",
|
||||||
"domain_strategy": "prefer_ipv4",
|
"domain_strategy": "prefer_ipv4",
|
||||||
"interface_name": "sing-tun",
|
"interface_name": "sing-tun",
|
||||||
"inet4_address": "172.19.0.1\/30",
|
"address": [
|
||||||
|
"172.19.0.1/30"
|
||||||
|
],
|
||||||
"mtu": 1400,
|
"mtu": 1400,
|
||||||
"gso": true,
|
|
||||||
"auto_route": true,
|
"auto_route": true,
|
||||||
"strict_route": true,
|
"strict_route": true,
|
||||||
"sniff": true,
|
"sniff": true,
|
||||||
@@ -48,7 +49,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tag": "dns-remote",
|
"tag": "dns-remote",
|
||||||
"address": "tcp:\/\/8.8.8.8",
|
"address": "tcp://8.8.8.8",
|
||||||
"address_strategy": "prefer_ipv4",
|
"address_strategy": "prefer_ipv4",
|
||||||
"strategy": "prefer_ipv4",
|
"strategy": "prefer_ipv4",
|
||||||
"detour": "direct"
|
"detour": "direct"
|
||||||
@@ -92,28 +93,23 @@
|
|||||||
{
|
{
|
||||||
"type": "direct",
|
"type": "direct",
|
||||||
"tag": "direct"
|
"tag": "direct"
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "block",
|
|
||||||
"tag": "block"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "dns",
|
|
||||||
"tag": "dns-out"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"route": {
|
"route": {
|
||||||
"auto_detect_interface": true,
|
"auto_detect_interface": true,
|
||||||
"override_android_vpn": true,
|
"override_android_vpn": true,
|
||||||
"rules": [
|
"rules": [
|
||||||
{
|
|
||||||
"protocol": "dns",
|
|
||||||
"outbound": "dns-out"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"addruleset": true,
|
"addruleset": true,
|
||||||
"outbound": "direct"
|
"outbound": "direct"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"action": "sniff"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"protocol": "dns",
|
||||||
|
"action": "hijack-dns"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"addruleset": true,
|
"addruleset": true,
|
||||||
"createruleset": [
|
"createruleset": [
|
||||||
@@ -129,6 +125,21 @@
|
|||||||
],
|
],
|
||||||
"outbound": "~outbound~"
|
"outbound": "~outbound~"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"addruleset": true,
|
||||||
|
"createruleset": [
|
||||||
|
{
|
||||||
|
"name": "subnet",
|
||||||
|
"interval": "30s",
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"ip_cidr": "~subnet~"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outbound": "~outbound~"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"addruleset": true,
|
"addruleset": true,
|
||||||
"createruleset": [
|
"createruleset": [
|
||||||
@@ -172,7 +183,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"outbound": "block"
|
"action": "reject"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"addruleset": true,
|
"addruleset": true,
|
||||||
|
|||||||
+111
-81
@@ -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
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,6 +44,8 @@ services:
|
|||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
ad:
|
ad:
|
||||||
condition: service_started
|
condition: service_started
|
||||||
|
ss:
|
||||||
|
condition: service_started
|
||||||
env_file:
|
env_file:
|
||||||
- path: ./.env
|
- path: ./.env
|
||||||
required: true # default
|
required: true # default
|
||||||
@@ -162,6 +164,7 @@ services:
|
|||||||
- ./update:/update
|
- ./update:/update
|
||||||
- ./.git:/.git
|
- ./.git:/.git
|
||||||
- ./scripts/start_service.sh:/start_service.sh
|
- ./scripts/start_service.sh:/start_service.sh
|
||||||
|
- ./docker-compose.override.yml:/docker/compose
|
||||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||||
environment:
|
environment:
|
||||||
IP: ${IP}
|
IP: ${IP}
|
||||||
@@ -192,6 +195,8 @@ services:
|
|||||||
- xr
|
- xr
|
||||||
- oc
|
- oc
|
||||||
- np
|
- np
|
||||||
|
- proxy
|
||||||
|
- ss
|
||||||
wg:
|
wg:
|
||||||
image: mercurykd/vpnbot-wg:1.1
|
image: mercurykd/vpnbot-wg:1.1
|
||||||
build:
|
build:
|
||||||
@@ -460,3 +465,61 @@ services:
|
|||||||
default:
|
default:
|
||||||
ipv4_address: 10.10.0.13
|
ipv4_address: 10.10.0.13
|
||||||
logging: *default-logging
|
logging: *default-logging
|
||||||
|
proxy:
|
||||||
|
image: mercurykd/vpnbot-ss:1.2
|
||||||
|
build:
|
||||||
|
dockerfile: dockerfile/shadowsocks.dockerfile
|
||||||
|
args:
|
||||||
|
image: ${IMAGE}
|
||||||
|
volumes:
|
||||||
|
- ./config/.profile:/root/.ashrc:ro
|
||||||
|
- ./config/sslocal.json:/config.json
|
||||||
|
- ./ssh:/ssh
|
||||||
|
- ./config/sshd_config:/etc/ssh/sshd_config
|
||||||
|
- ./scripts/start_proxy.sh:/start_proxy.sh
|
||||||
|
hostname: proxy
|
||||||
|
container_name: proxy-${VER}
|
||||||
|
depends_on:
|
||||||
|
php:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
ipv4_address: 10.10.0.3
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
env_file:
|
||||||
|
- path: ./.env
|
||||||
|
required: true # default
|
||||||
|
- path: ./override.env
|
||||||
|
required: false
|
||||||
|
stop_grace_period: 1s
|
||||||
|
command: ["/bin/sh", "/start_proxy.sh"]
|
||||||
|
logging: *default-logging
|
||||||
|
ss:
|
||||||
|
image: mercurykd/vpnbot-ss:1.2
|
||||||
|
build:
|
||||||
|
dockerfile: dockerfile/shadowsocks.dockerfile
|
||||||
|
args:
|
||||||
|
image: ${IMAGE}
|
||||||
|
volumes:
|
||||||
|
- ./config/.profile:/root/.ashrc:ro
|
||||||
|
- ./config/ssserver.json:/config.json
|
||||||
|
- ./ssh:/ssh
|
||||||
|
- ./config/sshd_config:/etc/ssh/sshd_config
|
||||||
|
- ./scripts/start_ss.sh:/start_ss.sh
|
||||||
|
hostname: shadowsocks
|
||||||
|
container_name: shadowsocks-${VER}
|
||||||
|
depends_on:
|
||||||
|
php:
|
||||||
|
condition: service_healthy
|
||||||
|
env_file:
|
||||||
|
- path: ./.env
|
||||||
|
required: true # default
|
||||||
|
- path: ./override.env
|
||||||
|
required: false
|
||||||
|
stop_grace_period: 1s
|
||||||
|
command: ["/bin/sh", "/start_ss.sh"]
|
||||||
|
networks:
|
||||||
|
default:
|
||||||
|
ipv4_address: 10.10.0.6
|
||||||
|
logging: *default-logging
|
||||||
|
|||||||
@@ -1,100 +1,29 @@
|
|||||||
telegram bot to manage servers (inside the bot)
|
telegram bot to manage servers (inside the bot)
|
||||||
|
|
||||||
<img src="https://github.com/user-attachments/assets/ec5faa51-987c-461a-a973-d94c7edf7115" width="300">
|
- VLESS (Reality OR Websocket)
|
||||||
|
- NaiveProxy
|
||||||
### VLESS (Reality OR Websocket)
|
- OpenConnect
|
||||||
- change secret
|
- Wireguard
|
||||||
- qr/config
|
- Amnezia
|
||||||
- change fake domain
|
- AdguardHome
|
||||||
- multiple users
|
- MTProto
|
||||||
- subscriptions with routing (xray, sing-box, mihomo)
|
- PAC
|
||||||
- routing templates per user
|
- automatic ssl
|
||||||
- routing via rulesets (sing-box, mihomo)
|
|
||||||
- steal from yourself
|
|
||||||
- add domains to warp
|
|
||||||
|
|
||||||
### Main menu VLESS:
|
|
||||||
<img src="https://github.com/user-attachments/assets/80d2f671-fade-4819-a96a-efa253741ffd" width="300">
|
|
||||||
|
|
||||||
### User menu VLESS:
|
|
||||||
<img src="https://github.com/user-attachments/assets/5c3c5b5e-1931-4e98-a472-d303bac61a4e" width="300">
|
|
||||||
|
|
||||||
### NaiveProxy
|
|
||||||
- change login
|
|
||||||
- change password
|
|
||||||
<img src="https://github.com/mercurykd/vpnbot/assets/30900414/2127a4af-0436-452c-bfe2-c750dd5dbc06" width="300">
|
|
||||||
|
|
||||||
### OpenConnect
|
|
||||||
- change secret
|
|
||||||
- change password
|
|
||||||
- change dns
|
|
||||||
- add user
|
|
||||||
- add ip subnet
|
|
||||||
- expose-iroutes (lan between users)
|
|
||||||
<img src="https://github.com/user-attachments/assets/c3a8a78e-fe99-423c-a626-610b333a2a56" width="300">
|
|
||||||
|
|
||||||
### Wireguard / Amnezia
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- rename
|
|
||||||
- timer
|
|
||||||
- torrent blocking
|
|
||||||
- qr/config
|
|
||||||
- AmneziaVPN vpn:// link
|
|
||||||
- statistics
|
|
||||||
<img src="https://github.com/mercurykd/vpnbot/assets/30900414/51a79c93-8083-40ba-a14b-a6ef19f00531" width="300">
|
|
||||||
<img src="https://github.com/mercurykd/vpnbot/assets/30900414/fd6ffd9f-bd75-479c-8dca-ea6c0b938b6c" width="300">
|
|
||||||
|
|
||||||
### Shadowsocks + v2ray
|
|
||||||
- change password
|
|
||||||
- on/off v2ray
|
|
||||||
- qr
|
|
||||||
- short link
|
|
||||||
<img src="https://github.com/mercurykd/vpnbot/assets/30900414/fbe39617-63ae-4536-8ab0-e4269ed8784a" width="300">
|
|
||||||
|
|
||||||
### AdguardHome
|
|
||||||
- change password
|
|
||||||
- change upstream dns
|
|
||||||
- check dns
|
|
||||||
- check safesearch
|
|
||||||
- add custom clientID for DNSoverTLS (DOT)
|
|
||||||
- fill allowed clients (WG/AWG + OpenConnect + VLESS)
|
|
||||||
- custom ID for each user VLESS
|
|
||||||
<img src="https://github.com/user-attachments/assets/1dcdd9f9-f781-4ec2-8e32-01ce6095e0a3" width="300">
|
|
||||||
|
|
||||||
### PAC
|
|
||||||
- the ability to create your own PAC available by url with the ability to substitute the final ip and port
|
|
||||||
- Shadowsocks Android PAC
|
|
||||||
- add [antifilter-community](https://community.antifilter.download/) or [ru-bundle](https://github.com/legiz-ru/sb-rule-sets/blob/main/ru-bundle.lst) domain lists
|
|
||||||
<img src="https://github.com/user-attachments/assets/8d039dbb-6478-43a8-811a-4279e766c884" width="300">
|
|
||||||
|
|
||||||
### MTProto
|
|
||||||
- change secret
|
|
||||||
- qr/config
|
|
||||||
<img src="https://github.com/user-attachments/assets/d37b2e1c-f991-4e1c-8060-1b547eea8fe2" width="300">
|
|
||||||
|
|
||||||
### Settings
|
|
||||||
- add/change admin
|
|
||||||
- change language (en/ru)
|
|
||||||
- import/export all settings
|
|
||||||
- domain binding
|
|
||||||
- obtain ssl for domain
|
|
||||||
- fake html for domain
|
|
||||||
- ports block
|
|
||||||
<img src="https://github.com/user-attachments/assets/82b78014-eaa2-4b4c-bc90-77f58d03d57c" width="300">
|
|
||||||
|
|
||||||
---
|
---
|
||||||
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
|
wget -O- https://raw.githubusercontent.com/mercurykd/vpnbot/master/scripts/init.sh | sh -s YOUR_TELEGRAM_BOT_KEY master
|
||||||
```
|
```
|
||||||
|
#### Restart:
|
||||||
### Install as service (autoload on start):
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
cd /root/vpnbot
|
make r
|
||||||
bash scripts/install_as_service.sh
|
|
||||||
```
|
```
|
||||||
|
#### autoload:
|
||||||
|
```shell
|
||||||
|
crontab -e
|
||||||
|
```
|
||||||
|
add `@reboot cd /root/vpnbot && make r` and save
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
TAG="${2:-master}"
|
||||||
apt update
|
apt update
|
||||||
apt install -y \
|
apt install -y \
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
@@ -13,6 +14,7 @@ apt install -y \
|
|||||||
curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
|
curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
|
||||||
git clone https://github.com/mercurykd/vpnbot.git
|
git clone https://github.com/mercurykd/vpnbot.git
|
||||||
cd ./vpnbot
|
cd ./vpnbot
|
||||||
|
git checkout $TAG
|
||||||
echo "<?php
|
echo "<?php
|
||||||
|
|
||||||
\$c = ['key' => '$1'];" > ./app/config.php
|
\$c = ['key' => '$1'];" > ./app/config.php
|
||||||
|
|||||||
Binary file not shown.
+11
-2
@@ -1,5 +1,14 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
pwd=`pwd`
|
pwd=`pwd`
|
||||||
|
process_name="$pwd/update/update.sh"
|
||||||
|
current_pid=$$
|
||||||
|
pids=$(pgrep -f $process_name)
|
||||||
|
for pid in $pids; do
|
||||||
|
if [ $pid -ne $current_pid ]; then
|
||||||
|
kill -9 $pid
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
> $pwd/update/pipe
|
> $pwd/update/pipe
|
||||||
echo "$$" > $pwd/update/update_pid
|
echo "$$" > $pwd/update/update_pid
|
||||||
|
|
||||||
@@ -27,10 +36,10 @@ do
|
|||||||
git pull > ./update/message
|
git pull > ./update/message
|
||||||
fi
|
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": "launching the bot"/')"
|
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": "launching the bot"/')"
|
||||||
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 &
|
|
||||||
> $pwd/update/key
|
> $pwd/update/key
|
||||||
> $pwd/update/curl
|
> $pwd/update/curl
|
||||||
|
IP=$(curl -s -t 1 2ip.io || curl -s -t 1 ipinfo.io/ip || curl -s -t 1 ifconfig.me) VER=$(git describe --tags) docker compose --env-file ./.env --env-file ./override.env up -d --force-recreate
|
||||||
|
bash $pwd/update/update.sh &
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|||||||
@@ -1,3 +1,26 @@
|
|||||||
|
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
|
||||||
|
- возможность установить нужную версию с нуля
|
||||||
|
- корректировка автосканера под новую версию
|
||||||
|
- улучшение основного меню
|
||||||
|
26.12.2024 v2.2
|
||||||
|
- возможность менять поддомен для naive/openconnect
|
||||||
|
26.12.2024 v2.1
|
||||||
|
- обновление версии singbox и конфига под него
|
||||||
22.12.2024 v2.0
|
22.12.2024 v2.0
|
||||||
!!! версия не совместима с предыдущими, возможно прийдется накатывать руками. старые конфиги (кроме вг) не будут работать! перед обновлением:
|
!!! версия не совместима с предыдущими, возможно прийдется накатывать руками. старые конфиги (кроме вг) не будут работать! перед обновлением:
|
||||||
- включить все порты или удалить docker-compose.override.yml
|
- включить все порты или удалить docker-compose.override.yml
|
||||||
|
|||||||
Reference in New Issue
Block a user