Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| be227f6a33 | |||
| 37d392a240 | |||
| 565573cfc2 | |||
| 3813f43b92 | |||
| f34427c13c | |||
| c2219e3657 | |||
| 0d7426e785 | |||
| c56fe4ff78 | |||
| b0e6835ac9 | |||
| f29d366aef |
+303
-162
@@ -12,6 +12,7 @@ class Bot
|
||||
public $dns;
|
||||
public $mtu;
|
||||
public $logs;
|
||||
public $reg;
|
||||
|
||||
public function __construct($key, $i18n)
|
||||
{
|
||||
@@ -35,6 +36,22 @@ class Bot
|
||||
'upstream_access',
|
||||
'xray',
|
||||
];
|
||||
$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 /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',
|
||||
]) . '~';
|
||||
}
|
||||
|
||||
public function input()
|
||||
@@ -149,6 +166,12 @@ class Bot
|
||||
case preg_match('~^/switchBanIp$~', $this->input['callback'], $m):
|
||||
$this->switchBanIp();
|
||||
break;
|
||||
case preg_match('~^/searchLogs (.+)$~', $this->input['message'], $m):
|
||||
$this->searchLogs($m[1]);
|
||||
break;
|
||||
case preg_match('~^/searchLogs (.+?)(?:\s(.+?))?(?:\s(.+?))?(?:\s(.+?))?$~', $this->input['callback'], $m):
|
||||
$this->searchLogs($m[1], $m[2], $m[3], $m[4]);
|
||||
break;
|
||||
case preg_match('~^/switchSilence$~', $this->input['callback'], $m):
|
||||
$this->switchSilence();
|
||||
break;
|
||||
@@ -164,9 +187,8 @@ class Bot
|
||||
case preg_match('~^/ports$~', $this->input['callback'], $m):
|
||||
$this->ports();
|
||||
break;
|
||||
case preg_match('~^/ip$~', $this->input['message'], $m):
|
||||
case preg_match('~^/analysisIp$~', $this->input['callback'], $m):
|
||||
$this->analysisIp();
|
||||
case preg_match('~^/analysisIp(?:\s(\d+))?$~', $this->input['callback'], $m):
|
||||
$this->analysisIp($m[1] ?: 0);
|
||||
break;
|
||||
case preg_match('~^/ipMenu$~', $this->input['callback'], $m):
|
||||
$this->ipMenu();
|
||||
@@ -186,10 +208,13 @@ class Bot
|
||||
case preg_match('~^/searchIp (.+)$~', $this->input['callback'], $m):
|
||||
$this->searchIp($m[1]);
|
||||
break;
|
||||
case preg_match('~^/denyIp (.+?)(?:\s(\d)\s(\d+?)\s(\d))?$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/searchSuspiciousIp (.+)$~', $this->input['callback'], $m):
|
||||
$this->searchSuspiciousIp($m[1]);
|
||||
break;
|
||||
case preg_match('~^/denyIp (.+?)(?:\s(.+?)\s(\d+?)\s(\d))?$~', $this->input['callback'], $m):
|
||||
$this->denyIp($m[1], $m[2], $m[3], $m[4]);
|
||||
break;
|
||||
case preg_match('~^/whiteIp (.+?)(?:\s(\d)\s(\d+?)\s(\d))?$~', $this->input['callback'], $m):
|
||||
case preg_match('~^/whiteIp (.+?)(?:\s(.+?)\s(\d+?)\s(\d))?$~', $this->input['callback'], $m):
|
||||
$this->whiteIp($m[1], $m[2], $m[3], $m[4]);
|
||||
break;
|
||||
case preg_match('~^/adgFillAllowedClients(?: (\d+))?$~', $this->input['callback'], $m):
|
||||
@@ -240,6 +265,9 @@ class Bot
|
||||
case preg_match('~^/addCommunityFilter$~', $this->input['callback'], $m):
|
||||
$this->addCommunityFilter();
|
||||
break;
|
||||
case preg_match('~^/addLegizFilter$~', $this->input['callback'], $m):
|
||||
$this->addLegizFilter();
|
||||
break;
|
||||
case preg_match('~^/pacMenu (\d+)$~', $this->input['callback'], $m):
|
||||
$this->pacMenu($m[1]);
|
||||
break;
|
||||
@@ -572,7 +600,7 @@ class Bot
|
||||
$this->addOverrideHtml();
|
||||
break;
|
||||
case preg_match('~^/export$~', $this->input['callback'], $m):
|
||||
$this->exportManual();
|
||||
$this->pinBackup();
|
||||
break;
|
||||
case preg_match('~^/import$~', $this->input['callback'], $m):
|
||||
$this->import();
|
||||
@@ -1158,38 +1186,37 @@ class Bot
|
||||
try {
|
||||
$pac = $this->getPacConf();
|
||||
if (!empty($pac['autoscan'])) {
|
||||
$r = $this->analysisIp(1);
|
||||
$r = $this->analysisIp(return: 1);
|
||||
require __DIR__ . '/config.php';
|
||||
if (!empty($c['admin']) && (empty($this->time3) || ((time() - $this->time3) > $pac['autoscan_timeout']))) {
|
||||
$this->time3 = time();
|
||||
if (!empty($r)) {
|
||||
foreach ($r as $k => $v) {
|
||||
$tmp = array_unique($v);
|
||||
foreach ($tmp as $i) {
|
||||
$t[$i]++;
|
||||
foreach ($v as $i) {
|
||||
$t[$i['title']][$k] = 1;
|
||||
}
|
||||
}
|
||||
foreach ($t as $k => $v) {
|
||||
$text .= "\n$v $k";
|
||||
$text .= "\n" . count($v) . " $k";
|
||||
}
|
||||
if (!empty($pac['autodeny'])) {
|
||||
$this->denyIp(array_keys($r));
|
||||
$ban = count(array_keys($r));
|
||||
foreach (array_keys($r) as $v) {
|
||||
$ips[] = [[
|
||||
'text' => "logs $v",
|
||||
'callback_data' => "/searchIp $v",
|
||||
'text' => $v,
|
||||
'callback_data' => "/searchLogs $v",
|
||||
]];
|
||||
}
|
||||
}
|
||||
if (empty($pac['silence'])) {
|
||||
if ($pac['silence'] == 0 || $pac['silence'] == 1) {
|
||||
foreach ($c['admin'] as $k => $v) {
|
||||
$this->send($v, "suspicious ips found: $text" . ($ban ? "\nbanned:$ban" : ''), button: $ips ?: [[
|
||||
[
|
||||
'text' => $this->i18n('analyze'),
|
||||
'callback_data' => '/analysisIp',
|
||||
],
|
||||
]]);
|
||||
]], disable_notification: $pac['silence'] ? true : false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1201,7 +1228,7 @@ class Bot
|
||||
|
||||
public function checkBackup($delta)
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
$c = $this->getPacConf();
|
||||
if (!empty($c['backup'])) {
|
||||
$now = strtotime(date('Y-m-d H:i:s'));
|
||||
[$start, $period] = explode('/', $c['backup']);
|
||||
@@ -1214,9 +1241,6 @@ class Bot
|
||||
&& $now - $start >= 0
|
||||
&& (($now - $start) % $period < $delta)
|
||||
) {
|
||||
if (!empty($c['pinbackup'])) {
|
||||
$this->pinAdmin($c['pinbackup'], 1);
|
||||
}
|
||||
$this->pinBackup();
|
||||
}
|
||||
}
|
||||
@@ -1238,12 +1262,19 @@ class Bot
|
||||
}
|
||||
}
|
||||
|
||||
public function pinBackup()
|
||||
public function pinBackup($file = false)
|
||||
{
|
||||
require __DIR__ . '/config.php';
|
||||
$conf = $this->getPacConf();
|
||||
$bot = preg_replace('~[\W]~iu', '_', $this->request('getMyName', [])['result']['name']);
|
||||
$conf['pinbackup'] = $this->upload("{$bot}_export_" . date('d_m_Y_H_i') . '.json', $this->export(), $c['admin'][0])['result']['message_id'];
|
||||
$conf = $this->getPacConf();
|
||||
$bot = preg_replace('~[\W]~iu', '_', $this->request('getMyName', [])['result']['name']);
|
||||
$json = $this->export();
|
||||
if (!empty($file)) {
|
||||
file_put_contents($file, $json);
|
||||
}
|
||||
if (!empty($conf['pinbackup'])) {
|
||||
$this->pinAdmin($conf['pinbackup'], 1);
|
||||
}
|
||||
$conf['pinbackup'] = $this->upload("{$bot}_export_" . date('d_m_Y_H_i') . '.json', $json, $c['admin'][0])['result']['message_id'];
|
||||
$this->setPacConf($conf);
|
||||
$this->pinAdmin($conf['pinbackup']);
|
||||
}
|
||||
@@ -1266,9 +1297,13 @@ class Bot
|
||||
$this->send($v, implode("\n", $diff), 0, [
|
||||
[
|
||||
[
|
||||
'text' => 'changelog',
|
||||
'text' => 'changelog',
|
||||
'web_app' => ['url' => "https://raw.githubusercontent.com/mercurykd/vpnbot/$b/version"],
|
||||
]
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('update bot'),
|
||||
'callback_data' => "/applyupdatebot",
|
||||
],
|
||||
]
|
||||
]);
|
||||
}
|
||||
@@ -1427,16 +1462,6 @@ class Bot
|
||||
return json_encode($conf, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
}
|
||||
|
||||
public function exportManual($file = false)
|
||||
{
|
||||
$json = $this->export();
|
||||
if (!empty($file)) {
|
||||
file_put_contents($file, $json);
|
||||
}
|
||||
$bot = preg_replace('~[\W]~iu', '_', $this->request('getMyName', [])['result']['name']);
|
||||
return $this->upload("{$bot}_export_" . date('d_m_Y_H_i') . '.json', $json);
|
||||
}
|
||||
|
||||
public function import()
|
||||
{
|
||||
$r = $this->send(
|
||||
@@ -2557,9 +2582,9 @@ DNS-over-HTTPS with IP:
|
||||
default:
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
"@{$this->input['username']} list domains separated by commas",
|
||||
"@{$this->input['username']} list separated by commas",
|
||||
$this->input['message_id'],
|
||||
reply: 'list domains separated by commas',
|
||||
reply: 'list separated by commas',
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -2581,7 +2606,11 @@ DNS-over-HTTPS with IP:
|
||||
if (!empty($domains)) {
|
||||
$conf = $this->getPacConf();
|
||||
foreach ($domains as $k => $v) {
|
||||
$conf[$type][in_array($type, ['rulessetlist', 'packagelist', 'processlist']) ? trim($v) : idn_to_ascii(trim($v))] = true;
|
||||
if (in_array($type, ['white', 'deny'])) {
|
||||
$conf[$type][] = $v;
|
||||
} else {
|
||||
$conf[$type][in_array($type, ['rulessetlist', 'packagelist', 'processlist']) ? trim($v) : idn_to_ascii(trim($v))] = true;
|
||||
}
|
||||
}
|
||||
ksort($conf[$type]);
|
||||
$this->setPacConf($conf);
|
||||
@@ -2620,6 +2649,11 @@ DNS-over-HTTPS with IP:
|
||||
$this->xrayUpdateRules();
|
||||
$this->xtlsrulesset();
|
||||
break;
|
||||
case 'white':
|
||||
case 'deny':
|
||||
$this->syncDeny();
|
||||
$this->denyList(0, $type == 'white' ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3476,6 +3510,19 @@ DNS-over-HTTPS with IP:
|
||||
$this->pacUpdate();
|
||||
}
|
||||
|
||||
public function addLegizFilter()
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
$l = array_filter(array_map(fn($e) => trim($e), explode("\n", file_get_contents('https://github.com/legiz-ru/sb-rule-sets/raw/main/ru-bundle.lst'))));
|
||||
if (!empty($l)) {
|
||||
foreach ($l as $k => $v) {
|
||||
$pac['includelist'][$v] = true;
|
||||
}
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
$this->pacUpdate();
|
||||
}
|
||||
|
||||
public function pacMenu($page = 0)
|
||||
{
|
||||
unset($_SESSION['proxylistentry']);
|
||||
@@ -3559,6 +3606,12 @@ DNS-over-HTTPS with IP:
|
||||
'callback_data' => "/addCommunityFilter",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('add') . ' ru-bundle',
|
||||
'callback_data' => "/addLegizFilter",
|
||||
],
|
||||
];
|
||||
$data = array_merge($data, $this->listPac('includelist', $page, 'pacMenu')[0]);
|
||||
$data[] = [
|
||||
[
|
||||
@@ -4100,7 +4153,7 @@ DNS-over-HTTPS with IP:
|
||||
],
|
||||
[
|
||||
[
|
||||
'text' => $this->i18n('IP ban'),
|
||||
'text' => $this->i18n('IP ban & Logs'),
|
||||
'callback_data' => "/ipMenu",
|
||||
],
|
||||
],
|
||||
@@ -4181,7 +4234,7 @@ DNS-over-HTTPS with IP:
|
||||
public function switchSilence()
|
||||
{
|
||||
$c = $this->getPacConf();
|
||||
$c['silence'] = $c['silence'] ? 0 : 1;
|
||||
$c['silence'] = (($c['silence'] ?: 0) + 1) % 3;
|
||||
$this->setPacConf($c);
|
||||
$this->ipMenu();
|
||||
}
|
||||
@@ -4192,6 +4245,12 @@ DNS-over-HTTPS with IP:
|
||||
$pac = $this->getPacConf();
|
||||
$d = count($pac['deny'] ?: []);
|
||||
$w = count($pac['white'] ?: []);
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('logs'),
|
||||
'callback_data' => "/logs",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('autoscan') . ': ' . ($pac['autoscan'] ? $this->getTime(strtotime(($pac['autoscan_timeout'] ?: 3600) . ' seconds')) : $this->i18n('off')),
|
||||
@@ -4204,10 +4263,17 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $this->i18n('autoblock') . ': ' . $this->i18n($pac['autodeny'] ? 'on' : 'off'),
|
||||
'callback_data' => '/switchBanIp',
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('silence') . ': ' . $this->i18n($pac['silence'] ? 'on' : 'off'),
|
||||
'text' => $this->i18n('silence') . ': ' . ((function ($pac) {
|
||||
switch ($pac['silence']) {
|
||||
case 0:
|
||||
return $this->i18n('off');
|
||||
case 1:
|
||||
return '🟡';
|
||||
case 2:
|
||||
return $this->i18n('on');
|
||||
}
|
||||
})($pac)),
|
||||
'callback_data' => '/switchSilence',
|
||||
],
|
||||
];
|
||||
@@ -4217,8 +4283,6 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $this->i18n('ignorelist') . ": $w",
|
||||
'callback_data' => '/denyList 0 1',
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('blocklist') . ": $d",
|
||||
'callback_data' => '/denyList 0 0',
|
||||
@@ -4244,10 +4308,56 @@ DNS-over-HTTPS with IP:
|
||||
);
|
||||
}
|
||||
|
||||
public function analysisIp($return = false)
|
||||
public function suspicious($regexp, $file, $ip, $title, $reverse = false)
|
||||
{
|
||||
if ($r = fopen($file, 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+)~', $l, $m)) {
|
||||
if ($reverse xor preg_match($regexp, $l)) {
|
||||
if (is_array($ip)) {
|
||||
if (empty($ip[$m[1]])) {
|
||||
$ret[$m[1]][] = [
|
||||
'title' => $title,
|
||||
'log' => $l,
|
||||
];
|
||||
}
|
||||
} else {
|
||||
if ($ip == $m[1]) {
|
||||
$ret[$m[1]][] = [
|
||||
'title' => $title,
|
||||
'log' => $l,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
return $ret ?: [];
|
||||
}
|
||||
|
||||
public function analysisIp(int $page = 0, $return = false)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
foreach (array_merge($pac['white'] ?: [], $pac['deny'] ?: [], ['10.10.0.10']) as $v) {
|
||||
foreach (array_merge($pac['white'] ?: [], $pac['deny'] ?: [], [
|
||||
'10.10.0.1' ,'10.10.1.1' ,
|
||||
'10.10.0.2' ,'10.10.1.2' ,
|
||||
'10.10.0.3' ,'10.10.1.3' ,
|
||||
'10.10.0.4' ,'10.10.1.4' ,
|
||||
'10.10.0.5' ,'10.10.1.5' ,
|
||||
'10.10.0.6' ,'10.10.1.6' ,
|
||||
'10.10.0.7' ,'10.10.1.7' ,
|
||||
'10.10.0.8' ,'10.10.1.8' ,
|
||||
'10.10.0.9' ,'10.10.1.9' ,
|
||||
'10.10.0.10','10.10.1.10',
|
||||
'10.10.0.11','10.10.1.11',
|
||||
'10.10.0.12','10.10.1.12',
|
||||
'10.10.0.13','10.10.1.13',
|
||||
'10.10.0.14','10.10.1.14',
|
||||
'10.10.0.15','10.10.1.15',
|
||||
]) as $v) {
|
||||
$xr[$v] = true;
|
||||
}
|
||||
if ($r = fopen('/logs/nginx_tlgrm_access', 'r')) {
|
||||
@@ -4269,99 +4379,102 @@ DNS-over-HTTPS with IP:
|
||||
fclose($r);
|
||||
}
|
||||
|
||||
if ($r = fopen('/logs/upstream_access', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+).+200\s\d+\s0$~', $l, $m)) {
|
||||
if (empty($xr[$m[1]])) {
|
||||
$ip[$m[1]][] = 'possibly a Reality Degenerate';
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
|
||||
$reg = [
|
||||
'GET /ws.+ HTTP',
|
||||
'GET /adguard/.+ HTTP',
|
||||
'GET /webapp.+ HTTP',
|
||||
'GET /pac.+ HTTP',
|
||||
'GET \.well-known.+ HTTP',
|
||||
'GET /v2ray.+ HTTP',
|
||||
'GET /dns-query.+ HTTP',
|
||||
'GET / HTTP',
|
||||
'GET /tlgrm.+ HTTP',
|
||||
'GET /jsoneditor.min.css HTTP',
|
||||
'GET /jsoneditor.min.js HTTP',
|
||||
'GET /jquery-3.7.1.min.js HTTP',
|
||||
'GET /img/jsoneditor-icons.svg HTTP',
|
||||
'GET /favicon.ico HTTP',
|
||||
$t = [
|
||||
$this->suspicious('~\d+\.\d+\.\d+\.\d+.+200\s\d+\s0$~', '/logs/upstream_access', $xr, 'possibly a Reality Degenerate'),
|
||||
$this->suspicious($this->reg, '/logs/nginx_default_access', $xr, 'possibly a scanner', true),
|
||||
$this->suspicious($this->reg, '/logs/nginx_domain_access', $xr, 'possibly a scanner', true),
|
||||
];
|
||||
|
||||
if ($r = fopen('/logs/nginx_default_access', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (!preg_match('~' . implode('|', $reg) . '~', $l)) {
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+)~', $l, $m)) {
|
||||
if (empty($xr[$m[1]])) {
|
||||
$ip[$m[1]][] = 'possibly a scanner';
|
||||
}
|
||||
}
|
||||
}
|
||||
$ip = [];
|
||||
foreach ($t as $r) {
|
||||
foreach ($r as $k => $v) {
|
||||
$ip[$k] = $v;
|
||||
}
|
||||
fclose($r);
|
||||
}
|
||||
|
||||
if ($r = fopen('/logs/nginx_domain_access', 'r')) {
|
||||
while (feof($r) === false) {
|
||||
$l = fgets($r);
|
||||
if (!preg_match('~' . implode('|', $reg) . '~', $l)) {
|
||||
if (preg_match('~(\d+\.\d+\.\d+\.\d+)~', $l, $m)) {
|
||||
if (empty($xr[$m[1]])) {
|
||||
$ip[$m[1]][] = 'possibly a scanner';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose($r);
|
||||
if (!empty($return)) {
|
||||
return $ip;
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
if (!empty($ip)) {
|
||||
foreach ($ip as $k => $v) {
|
||||
if ($i > 10) {
|
||||
break;
|
||||
}
|
||||
$comment = implode(', ', array_unique($v));
|
||||
if (!empty($return)) {
|
||||
$ret[$k] = $v;
|
||||
} else {
|
||||
$this->send($this->input['from'], "$k $comment\n", button: [[
|
||||
[
|
||||
'text' => $this->i18n('block'),
|
||||
'callback_data' => "/denyIp $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('ignore'),
|
||||
'callback_data' => "/whiteIp $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('logs'),
|
||||
'callback_data' => "/searchIp $k",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('clean logs'),
|
||||
'callback_data' => "/cleanLogs $k",
|
||||
],
|
||||
]]);
|
||||
$i++;
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $k,
|
||||
'callback_data' => "/searchLogs $k analysisIp $page 0",
|
||||
]
|
||||
];
|
||||
}
|
||||
if (!empty($return)) {
|
||||
return $ret;
|
||||
$all = (int) ceil(count($data) / $this->limit);
|
||||
$page = min($page, $all - 1);
|
||||
$page = $page < 0 ? $all - 1 : $page;
|
||||
$data = array_slice($data ?: [], $page * $this->limit, $this->limit);
|
||||
if ($all > 1) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => '<<',
|
||||
'callback_data' => "/analysisIp " . ($page - 1 >= 0 ? $page - 1 : $all - 1),
|
||||
],
|
||||
[
|
||||
'text' => '>>',
|
||||
'callback_data' => "/analysisIp " . ($page < $all - 1 ? $page + 1 : 0),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/ipMenu",
|
||||
],
|
||||
];
|
||||
$this->update($this->input['from'], $this->input['message_id'], count($ip) ?: 'empty', $data);
|
||||
}
|
||||
|
||||
public function searchLogs($search, $fun = false, $page = 0, $white = 0)
|
||||
{
|
||||
if (preg_match('~^\d+\.\d+\.\d+\.\d+$~', $search)) {
|
||||
$info = file_get_contents("https://ipinfo.io/$search/json", context: stream_context_create(['http' => ['timeout' => 2]]));
|
||||
$text = "$search\n<pre>$info</pre>";
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('block'),
|
||||
'callback_data' => "/denyIp $search" . ($fun ? " $fun $page $white" : ''),
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('ignore'),
|
||||
'callback_data' => "/whiteIp $search" . ($fun ? " $fun $page $white" : ''),
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('all logs'),
|
||||
'callback_data' => "/searchIp $search",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('suspicious log'),
|
||||
'callback_data' => "/searchSuspiciousIp $search",
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n("clean logs $search"),
|
||||
'callback_data' => "/cleanLogs $search",
|
||||
],
|
||||
];
|
||||
if (!empty($fun)) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/$fun $page" . ($white ? " $white" : ''),
|
||||
],
|
||||
];
|
||||
$this->update($this->input['from'], $this->input['message_id'], $text, button: $data);
|
||||
} else {
|
||||
if (empty($this->input['callback_id'])) {
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
$this->send($this->input['from'], $text, button: $data);
|
||||
}
|
||||
} else {
|
||||
$this->answer($this->input['callback_id'], 'empty');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4396,6 +4509,40 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
}
|
||||
|
||||
public function searchSuspiciousIp($ip)
|
||||
{
|
||||
$t = [
|
||||
$this->suspicious('~\d+\.\d+\.\d+\.\d+.+200\s\d+\s0$~', '/logs/upstream_access', $ip, 'possibly a Reality Degenerate'),
|
||||
$this->suspicious($this->reg, '/logs/nginx_default_access', $ip, 'possibly a scanner', true),
|
||||
$this->suspicious($this->reg, '/logs/nginx_domain_access', $ip, 'possibly a scanner', true),
|
||||
];
|
||||
foreach ($t as $r) {
|
||||
if (!empty($r)) {
|
||||
foreach ($r as $v) {
|
||||
foreach ($v as $k) {
|
||||
$logs[$k['title']][] = $k['log'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($logs)) {
|
||||
foreach ($logs as $k => $v) {
|
||||
$head= "$k:\n";
|
||||
$t = array_chunk($v, 10);
|
||||
foreach ($t as $j) {
|
||||
$text = "$head<pre>";
|
||||
foreach ($j as $i) {
|
||||
$text .= htmlspecialchars($i, ENT_HTML5, 'UTF-8');
|
||||
}
|
||||
$text .= '</pre>';
|
||||
$this->send($this->input['from'], $text, $this->input['message_id']);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->answer($this->input['callback_id'], 'empty');
|
||||
}
|
||||
}
|
||||
|
||||
public function denyList($page = 0, $white = 0)
|
||||
{
|
||||
$text = 'Menu -> IP -> ' . ($white ? 'white' : 'deny') . ' list';
|
||||
@@ -4404,25 +4551,23 @@ DNS-over-HTTPS with IP:
|
||||
$page = min($page, $all - 1);
|
||||
$page = $page < 0 ? $all - 1 : $page;
|
||||
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('add'),
|
||||
'callback_data' => "/include " . ($white ? 'white' : 'deny'),
|
||||
],
|
||||
];
|
||||
if (!empty($domains)) {
|
||||
foreach (array_slice($domains, $page * $this->limit, $this->limit) as $v) {
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('delete') . " $v",
|
||||
'text' => $v,
|
||||
'callback_data' => "/searchLogs $v denyList $page $white",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('delete'),
|
||||
'callback_data' => "/allowIp $v $page" . ($white ? " 1" : ''),
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n($white ? 'block' : 'ignore'),
|
||||
'callback_data' => ($white ? "/denyIp" : "/whiteIp") . " $v 1 $page $white",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('logs'),
|
||||
'callback_data' => "/searchIp $v",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('clean logs'),
|
||||
'callback_data' => "/cleanLogs $v 1",
|
||||
],
|
||||
];
|
||||
}
|
||||
if ($all > 1) {
|
||||
@@ -4468,7 +4613,7 @@ DNS-over-HTTPS with IP:
|
||||
$this->ipMenu();
|
||||
}
|
||||
|
||||
public function denyIp($ip, $nodelete = false, $page = 0, $white = 0)
|
||||
public function denyIp($ip, $fun = false, $page = 0, $white = 0)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
if (is_array($ip)) {
|
||||
@@ -4485,16 +4630,16 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
if (empty($nodelete)) {
|
||||
if (empty($fun)) {
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
$this->syncDeny();
|
||||
if (!empty($nodelete)) {
|
||||
$this->denyList($page, $white);
|
||||
if (!empty($fun)) {
|
||||
$this->{$fun}($page, $white);
|
||||
}
|
||||
}
|
||||
|
||||
public function whiteIp($ip, $nodelete = false, $page = 0, $white = 0)
|
||||
public function whiteIp($ip, $fun = false, $page = 0, $white = 0)
|
||||
{
|
||||
$pac = $this->getPacConf();
|
||||
if (is_array($ip)) {
|
||||
@@ -4511,12 +4656,12 @@ DNS-over-HTTPS with IP:
|
||||
}
|
||||
}
|
||||
$this->setPacConf($pac);
|
||||
if (empty($nodelete)) {
|
||||
if (empty($fun)) {
|
||||
$this->delete($this->input['from'], $this->input['message_id']);
|
||||
}
|
||||
$this->syncDeny();
|
||||
if (!empty($nodelete)) {
|
||||
$this->denyList($page, $white);
|
||||
if (!empty($fun)) {
|
||||
$this->{$fun}($page, $white);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4935,9 +5080,9 @@ DNS-over-HTTPS with IP:
|
||||
{
|
||||
$r = $this->send(
|
||||
$this->input['chat'],
|
||||
"@{$this->input['username']} send time:",
|
||||
"@{$this->input['username']} send time like 1 hour or 1 day etc",
|
||||
$this->input['message_id'],
|
||||
reply: 'send time:',
|
||||
reply: 'send time like 1 hour or 1 day etc',
|
||||
);
|
||||
$_SESSION['reply'][$r['result']['message_id']] = [
|
||||
'start_message' => $this->input['message_id'],
|
||||
@@ -6221,7 +6366,7 @@ DNS-over-HTTPS with IP:
|
||||
|
||||
public function applyupdatebot()
|
||||
{
|
||||
$this->exportManual($this->update);
|
||||
$this->pinBackup($this->update);
|
||||
$r = $this->send($this->input['from'], 'update...');
|
||||
file_put_contents('/update/reload_message', "{$this->input['from']}:{$r['result']['message_id']}");
|
||||
file_put_contents('/update/key', $this->key);
|
||||
@@ -6381,10 +6526,6 @@ DNS-over-HTTPS with IP:
|
||||
],
|
||||
];
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('logs'),
|
||||
'callback_data' => "/logs",
|
||||
],
|
||||
[
|
||||
'text' => $this->i18n('debug') . ': ' . $this->i18n($c['debug'] ? 'on' : 'off'),
|
||||
'callback_data' => "/debug",
|
||||
@@ -6534,7 +6675,7 @@ DNS-over-HTTPS with IP:
|
||||
$data[] = [
|
||||
[
|
||||
'text' => $this->i18n('back'),
|
||||
'callback_data' => "/menu config",
|
||||
'callback_data' => "/ipMenu",
|
||||
],
|
||||
];
|
||||
$this->update(
|
||||
@@ -7146,7 +7287,7 @@ DNS-over-HTTPS with IP:
|
||||
var_dump($this->request('setMyCommands', json_encode($data), 1));
|
||||
}
|
||||
|
||||
public function send($chat, $text, ?int $to = 0, $button = false, $reply = false, $mode = 'HTML')
|
||||
public function send($chat, $text, ?int $to = 0, $button = false, $reply = false, $mode = 'HTML', $disable_notification = false)
|
||||
{
|
||||
if ($button) {
|
||||
$extra = ['inline_keyboard' => $button];
|
||||
@@ -7167,7 +7308,7 @@ DNS-over-HTTPS with IP:
|
||||
'text' => "$v\n",
|
||||
'parse_mode' => $mode,
|
||||
// 'disable_web_page_preview' => true,
|
||||
// 'disable_notification' => !empty($to) && 0 == $k,
|
||||
'disable_notification' => $disable_notification,
|
||||
'reply_to_message_id' => 0 == $k && $to > 0 ? $to : false,
|
||||
];
|
||||
if ($k == array_key_last($tails)) {
|
||||
@@ -7183,7 +7324,7 @@ DNS-over-HTTPS with IP:
|
||||
'text' => $text,
|
||||
'parse_mode' => $mode,
|
||||
// 'disable_web_page_preview' => true,
|
||||
// 'disable_notification' => !empty($to),
|
||||
'disable_notification' => $disable_notification,
|
||||
'reply_to_message_id' => $to,
|
||||
];
|
||||
if (!empty($extra)) {
|
||||
|
||||
@@ -160,7 +160,9 @@ services:
|
||||
- ./ssh:/ssh
|
||||
- ./app:/app
|
||||
- ./logs/:/logs/
|
||||
- ./version:/version
|
||||
- ./update:/update
|
||||
- ./.git:/.git
|
||||
- ./scripts/start_service.sh:/start_service.sh
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
environment:
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
make d
|
||||
rm /etc/systemd/resolved.conf.d/adguardhome.conf
|
||||
mv /etc/resolv.conf.backup /etc/resolv.conf
|
||||
systemctl reload-or-restart systemd-resolved
|
||||
make u
|
||||
@@ -1,8 +0,0 @@
|
||||
mkdir /etc/systemd/resolved.conf.d
|
||||
echo "[Resolve]
|
||||
DNS=127.0.0.1
|
||||
DNSStubListener=no" > /etc/systemd/resolved.conf.d/adguardhome.conf
|
||||
mv /etc/resolv.conf /etc/resolv.conf.backup
|
||||
ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
|
||||
systemctl reload-or-restart systemd-resolved
|
||||
make d u
|
||||
+6
-6
@@ -10,23 +10,23 @@ do
|
||||
if [[ -n "$cmd" ]]
|
||||
then
|
||||
key=$(cat $pwd/update/key)
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "останавливаю бота"/')"
|
||||
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": "stopping the bot"/')"
|
||||
docker compose down --remove-orphans
|
||||
if [[ "$cmd" == "1" ]]
|
||||
then
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "очищаю директорию"/')"
|
||||
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": "clearing the directory"/')"
|
||||
git reset --hard && git clean -fd
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "скачиваю обновление"/')"
|
||||
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": "downloading the update"/')"
|
||||
git fetch
|
||||
if [[ -n "$branch" ]]
|
||||
then
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "меняю ветку"/')"
|
||||
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": "changing branch"/')"
|
||||
git checkout -t origin/$branch || git checkout $branch
|
||||
fi
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "применяю обновления"/')"
|
||||
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": "applying updates"/')"
|
||||
git pull > ./update/message
|
||||
fi
|
||||
curl -H "Content-Type: application/json" -X POST https://api.telegram.org/bot$key/editMessageText -d "$(cat $pwd/update/curl | sed 's/"text":"~t~"/"text": "запускаю бота"/')"
|
||||
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
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
16.11.2024 v1.104
|
||||
- единая механика закрепления бэкапа
|
||||
- фикс текста уведомления о новой версии
|
||||
16.11.2024 v1.103
|
||||
- фикс уведомления о новой версии
|
||||
16.11.2024 v1.102
|
||||
- переделан раздел списка ip под управление кнопками
|
||||
- возможность добавить свои айпи в blocklist/whitelist
|
||||
15.11.2024 v1.101
|
||||
- кнопка добавления https://github.com/legiz-ru/sb-rule-sets/raw/main/ru-bundle.lst
|
||||
- переделан раздел списка ip для читаемости
|
||||
15.11.2024 v1.100
|
||||
- несколько режимов silence для сканера
|
||||
- анализ сканера скидывает файл всех найденных айпи
|
||||
- команда /searchLogs (пока только для айпи)
|
||||
- логи переехали в меню сканера
|
||||
- обновление текстов и подсказок
|
||||
14.11.2024 v1.99.1
|
||||
- анализ логов и бан айпишников, фиксы
|
||||
14.11.2024 v1.99
|
||||
|
||||
Reference in New Issue
Block a user