Compare commits

..

6 Commits

Author SHA1 Message Date
mercury b227431b7a singbox ruleset 2024-04-19 15:40:45 +04:00
mercury bb83ab0684 warp status on menu 2024-04-18 16:10:13 +04:00
mercury 05267f44be fix naming templates 2024-04-18 15:52:37 +04:00
mercury d1be532270 warp+ set key 2024-04-18 01:58:25 +04:00
mercury 48798c7e61 add restart for singbox window 2024-04-16 23:06:25 +04:00
mercury 84e71ab45b improve mtproto menu 2024-04-16 19:22:21 +04:00
14 changed files with 301 additions and 148 deletions
+145 -17
View File
@@ -368,6 +368,12 @@ class Bot
case preg_match('~^/domain$~', $this->input['callback'], $m):
$this->domain();
break;
case preg_match('~^/warp$~', $this->input['callback'], $m):
$this->warp();
break;
case preg_match('~^/warpPlus$~', $this->input['callback'], $m):
$this->warpPlus();
break;
case preg_match('~^/xray(?: (\d+))?$~', $this->input['callback'], $m):
$this->xray($m[1] ?: 0);
break;
@@ -455,9 +461,9 @@ class Bot
{
$r = $this->send(
$this->input['chat'],
"@{$this->input['username']} enter url",
"@{$this->input['username']} enter key or 0 for stop mtproto",
$this->input['message_id'],
reply: 'enter url',
reply: 'enter key or 0 for stop mtproto',
);
$_SESSION['reply'][$r['result']['message_id']] = [
'start_message' => $this->input['message_id'],
@@ -512,10 +518,7 @@ class Bot
public function mtproto()
{
$s = file_get_contents('/config/mtprotosecret');
$d = file_get_contents('/config/mtprotodomain') ?: 'vk.com';
$p = getenv('TGPORT');
$ip = $this->getPacConf()['domain'] ?: $this->ip;
$st = $this->ssh('pgrep mtproto-proxy', 'tg') ? 'on' : 'off';
$text[] = "Menu -> MTProto\n";
$text[] = "status: $st\n";
@@ -3278,8 +3281,8 @@ DNS-over-HTTPS with IP:
'callback_data' => "/menu ss",
],
[
'text' => $this->i18n('mirror'),
'callback_data' => "/menu mirror",
'text' => $this->i18n('warp') . ': ' . $this->warpStatus(),
'callback_data' => "/warp",
],
],
[
@@ -3696,7 +3699,7 @@ DNS-over-HTTPS with IP:
'web_app' => ['url' => "https://$domain/pac?h=$hash&t=te&ty=$type"],
],
[
'text' => $this->i18n($pac["default{$type}template"] ? 'off' : 'on'),
'text' => $this->i18n($pac["default{$type}template"] && !empty($pac["{$type}templates"][$pac["default{$type}template"]]) ? 'off' : 'on'),
'callback_data' => "/defaultTemplate $type",
],
];
@@ -3840,6 +3843,64 @@ DNS-over-HTTPS with IP:
);
}
public function warpPlus()
{
$r = $this->send(
$this->input['chat'],
"@{$this->input['username']} enter key",
$this->input['message_id'],
reply: 'enter key',
);
$_SESSION['reply'][$r['result']['message_id']] = [
'start_message' => $this->input['message_id'],
'start_callback' => $this->input['callback_id'],
'callback' => 'addWarpPlus',
'args' => [],
];
}
public function addWarpPlus($key)
{
$c = $this->getPacConf();
$c['warp'] = $key;
$this->setPacConf($c);
$this->send($this->input['chat'], 'Warp registration license: ' . $this->ssh("warp-cli --accept-tos registration license $key", 'wp'));
sleep(1);
$this->warp();
}
public function warpStatus()
{
$st = $this->ssh('curl -m 1 -x socks5://127.0.0.1:40000 https://cloudflare.com/cdn-cgi/trace', 'wp');
preg_match('~warp=(\w+)~', $st, $m);
return $m[1];
}
public function warp()
{
$text[] = "Menu -> " . $this->i18n('warp');
$text[] = "status: " . $this->warpStatus();
$data[] = [
[
'text' => $this->i18n('set key'),
'callback_data' => "/warpPlus",
],
];
$data[] = [
[
'text' => $this->i18n('back'),
'callback_data' => "/menu",
],
];
$this->update(
$this->input['chat'],
$this->input['message_id'],
implode("\n", $text ?: ['...']),
$data ?: false,
);
}
public function choiceTemplate($arg)
{
$arg = explode('_', $arg);
@@ -3905,10 +3966,10 @@ DNS-over-HTTPS with IP:
$text[] = "<code>{$this->linkXray($i)}</code>\n";
$text[] = "import subscribe:";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=v&s={$c['id']}'>v2rayng</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=si&s={$c['id']}'>sing-box</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=st&s={$c['id']}'>streisand</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=h&s={$c['id']}'>hiddify</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=v&s={$c['id']}#{$c['email']}'>v2rayng</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=si&s={$c['id']}#{$c['email']}'>sing-box</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=s&r=st&s={$c['id']}#{$c['email']}'>streisand</a>";
$text[] = "<a href='$scheme://{$domain}/pac?h=$hash&t=si&r=h&s={$c['id']}#{$c['email']}'>hiddify</a>";
$text[] = "\nv2ray config: <code>$scheme://{$domain}/pac?h=$hash&t=s&s={$c['id']}</code>";
$text[] = "sing-box config: <code>$scheme://{$domain}/pac?h=$hash&t=si&s={$c['id']}</code>";
@@ -3934,8 +3995,8 @@ DNS-over-HTTPS with IP:
'callback_data' => "/switchXr $i",
],
];
$singtemplate = $c['singtemplate'] ? base64_decode($c['singtemplate']) : 'default(' . ($pac['defaultsingtemplate'] ? base64_decode($pac['defaultsingtemplate']) : 'origin') . ')';
$v2raytemplate = $c['v2raytemplate'] ? base64_decode($c['v2raytemplate']) : 'default(' . ($pac['defaultv2raytemplate'] ? base64_decode($pac['defaultv2raytemplate']) : 'origin') . ')';
$singtemplate = $c['singtemplate'] ? base64_decode($c['singtemplate']) : 'default(' . ($pac['defaultsingtemplate'] && !empty($pac['singtemplates'][base64_decode($pac['defaultsingtemplate'])]) ? base64_decode($pac['defaultsingtemplate']) : 'origin') . ')';
$v2raytemplate = $c['v2raytemplate'] ? base64_decode($c['v2raytemplate']) : 'default(' . ($pac['defaultv2raytemplate'] && !empty($pac['v2raytemplates'][base64_decode($pac['defaultv2raytemplate'])]) ? base64_decode($pac['defaultv2raytemplate']) : 'origin') . ')';
$data[] = [
[
'text' => $this->i18n('v2ray') . ": $v2raytemplate",
@@ -4055,7 +4116,8 @@ DNS-over-HTTPS with IP:
header("Location: hiddify://install-config/?url=" . urlencode($si));
exit;
case 'w':
file_put_contents('/singbox/update.cmd', preg_replace('#~url~#', $si, file_get_contents('/singbox/update.cmd')));
$link = htmlspecialchars($si, ENT_XML1, 'UTF-8');
file_put_contents('/singbox/winsw3.xml', preg_replace('#~url~#', $link, file_get_contents('/singbox/winsw3.xml')));
$zip = new ZipArchive();
$n = "singbox_$uid.zip";
$zip->open($n, ZipArchive::CREATE | ZipArchive::OVERWRITE);
@@ -4075,6 +4137,7 @@ DNS-over-HTTPS with IP:
switch (true) {
case !empty($template) && $template == 'origin':
case empty($template) && empty($pac['default' . ($_GET['t'] == 's' ? 'v2ray' : 'sing') . 'template']):
case empty($template) && !empty($pac['default' . ($_GET['t'] == 's' ? 'v2ray' : 'sing') . 'template']) && empty($pac[($_GET['t'] == 's' ? 'v2ray' : 'sing') . 'templates'][$pac['default' . ($_GET['t'] == 's' ? 'v2ray' : 'sing') . 'template']]):
$c = json_decode(file_get_contents('/config/' . ($_GET['t'] == 's' ? 'v2ray' : 'sing') . '.json'), true);
break;
case !empty($template):
@@ -4123,6 +4186,7 @@ DNS-over-HTTPS with IP:
}
}
$c['route']['rules'] = array_values($c['route']['rules']);
$c['route'] = $this->createRuleSet($c['route'], $uid);
break;
}
@@ -4130,6 +4194,69 @@ DNS-over-HTTPS with IP:
echo json_encode($c);
}
public function createRuleSet($route, $uid)
{
$pac = $this->getPacConf();
$domain = $pac['domain'] ?: $this->ip;
$scheme = empty($this->nginxGetTypeCert()) ? 'http' : 'https';
$hash = substr(md5($this->key), 0, 8);
foreach ($route['rules'] as $k => $v) {
if (!empty($v['createruleset'])) {
foreach ($v['createruleset'] as $i => $r) {
foreach ($r['rules'] as $l => $n) {
if (array_key_exists('domain_suffix', $n) && $n['domain_suffix'] == '~pac~') {
$r['rules'][$l]['domain_suffix'] = array_keys(array_filter($pac['includelist'] ?: []));
if (empty($r['rules'][$l]['domain_suffix'])) {
unset($r['rules'][$l]);
}
}
}
if (!empty($_GET['r']) && $r['name'] == $_GET['r']) {
$f = "/tmp/{$r['name']}" . time() . rand(1, 100);
file_put_contents($f, json_encode([
'version' => 1,
'rules' => $r['rules'],
]));
exec("sing-box rule-set compile $f");
header("Content-Disposition: attachment; filename={$r['name']}.srs");
header('Content-Type: application/binary');
echo file_get_contents("$f.srs");
unlink($f);
unlink("$f.srs");
exit;
}
if (!empty($r['rules'])) {
$ruleset[] = [
"tag" => $r['name'],
"url" => "$scheme://{$domain}/pac?" . http_build_query([
'h' => $hash,
't' => 'si',
's' => $uid,
'r' => $r['name'],
]),
"update_interval" => $r['interval'],
"type" => "remote",
"format" => "binary",
"download_detour" => "direct",
];
$route['rules'][$k]['rule_set'][] = $r['name'];
}
}
unset($route['rules'][$k]['createruleset']);
if (empty($route['rules'][$k]['rule_set'])) {
unset($route['rules'][$k]);
}
}
}
$route['rules'] = array_values($route['rules']);
$route['rule_set'] = array_merge($route['rule_set'] ?: [], $ruleset ?: []);
if (empty($route['rule_set'])) {
unset($route['rule_set']);
}
return $route;
}
public function getXray()
{
return json_decode(file_get_contents('/config/xray.json'), true);
@@ -5062,8 +5189,9 @@ DNS-over-HTTPS with IP:
fclose($s);
ssh2_disconnect($c);
} catch (Exception | Error $e) {
$this->send($this->input['chat'], $e->getMessage(), $this->input['message_id']);
die();
if (!empty($GLOBALS['debug'])) {
$this->send($this->input['chat'], $e->getMessage(), $this->input['message_id']);
}
}
return $data;
}
+4
View File
@@ -1,6 +1,10 @@
<?php
$i = [
'warp' => [
'en' => 'Warp',
'ru' => 'Warp',
],
'wg_title' => [
'en' => 'Wireguard',
'ru' => 'Wireguard',
+1 -1
View File
@@ -36,7 +36,7 @@ if ($hash == substr(md5($c['key']), 0, 8)) {
case 'te':
if (!empty($_GET['te'])) {
$t = $bot->getPacConf()["{$_GET['ty']}templates"][urldecode($_GET['te'])];
$t = $bot->getPacConf()["{$_GET['ty']}templates"][$_GET['te']];
} else {
$t = json_decode(file_get_contents("/config/{$_GET['ty']}.json"), true);
}
+3 -1
View File
@@ -2,10 +2,12 @@
require __DIR__ . '/timezone.php';
// require __DIR__ . '/debug.php';
require __DIR__ . '/bot.php';
require __DIR__ . '/config.php';
require __DIR__ . '/i18n.php';
if ($c['debug']) {
require __DIR__ . '/debug.php';
}
$bot = new Bot($c['key'], $i);
$bot->adguardProtect();
+4 -1
View File
@@ -2,11 +2,14 @@
require __DIR__ . '/timezone.php';
// require __DIR__ . '/debug.php';
require __DIR__ . '/bot.php';
require __DIR__ . '/config.php';
require __DIR__ . '/i18n.php';
if ($c['debug']) {
require __DIR__ . '/debug.php';
}
$bot = new Bot($c['key'], $i);
if (!empty($c['admin'])) {
+111 -87
View File
@@ -3,104 +3,128 @@
"level": "error",
"timestamp": true
},
"inbounds": [{
"type": "tun",
"tag": "tun-in",
"domain_strategy": "prefer_ipv4",
"interface_name": "sing-tun",
"inet4_address": "172.19.0.1\/30",
"mtu": 1400,
"gso": true,
"auto_route": true,
"strict_route": true,
"sniff": true,
"endpoint_independent_nat": false,
"stack": "mixed",
"platform": {
"http_proxy": {
"enabled": false,
"server": "127.0.0.1",
"server_port": 2080
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"domain_strategy": "prefer_ipv4",
"interface_name": "sing-tun",
"inet4_address": "172.19.0.1\/30",
"mtu": 1400,
"gso": true,
"auto_route": true,
"strict_route": true,
"sniff": true,
"endpoint_independent_nat": false,
"stack": "mixed",
"platform": {
"http_proxy": {
"enabled": false,
"server": "127.0.0.1",
"server_port": 2080
}
}
},
{
"type": "mixed",
"tag": "mixed-in",
"domain_strategy": "prefer_ipv4",
"listen": "127.0.0.1",
"listen_port": 2080,
"tcp_fast_open": true,
"sniff": true,
"sniff_override_destination": false,
"users": []
}
}, {
"type": "mixed",
"tag": "mixed-in",
"domain_strategy": "prefer_ipv4",
"listen": "127.0.0.1",
"listen_port": 2080,
"tcp_fast_open": true,
"sniff": true,
"sniff_override_destination": false,
"users": []
}],
],
"dns": {
"servers": [{
"tag": "dns_direct",
"address": "~dns~",
"address_resolver": "dns-remote",
"strategy": "prefer_ipv4",
"detour": "direct"
}, {
"tag": "dns-remote",
"address": "tcp:\/\/8.8.8.8",
"address_strategy": "prefer_ipv4",
"strategy": "prefer_ipv4",
"detour": "direct"
}],
"rules": [{
"outbound": "any",
"server": "dns-direct",
"disable_cache": false
}],
"servers": [
{
"tag": "dns_direct",
"address": "~dns~",
"address_resolver": "dns-remote",
"strategy": "prefer_ipv4",
"detour": "direct"
},
{
"tag": "dns-remote",
"address": "tcp:\/\/8.8.8.8",
"address_strategy": "prefer_ipv4",
"strategy": "prefer_ipv4",
"detour": "direct"
}
],
"rules": [
{
"outbound": "any",
"server": "dns-direct",
"disable_cache": false
}
],
"strategy": "ipv4_only",
"independent_cache": true
},
"outbounds": [{
"flow": "xtls-rprx-vision",
"packet_encoding": "",
"server": "",
"server_port": 443,
"tls": {
"enabled": true,
"insecure": false,
"reality": {
"outbounds": [
{
"flow": "xtls-rprx-vision",
"packet_encoding": "",
"server": "",
"server_port": 443,
"tls": {
"enabled": true,
"public_key": "",
"short_id": ""
"insecure": false,
"reality": {
"enabled": true,
"public_key": "",
"short_id": ""
},
"server_name": "",
"utls": {
"enabled": true,
"fingerprint": "chrome"
}
},
"server_name": "",
"utls": {
"enabled": true,
"fingerprint": "chrome"
}
"uuid": "",
"type": "vless",
"domain_strategy": "ipv4_only",
"tag": "proxy"
},
"uuid": "",
"type": "vless",
"domain_strategy": "ipv4_only",
"tag": "proxy"
}, {
"type": "direct",
"tag": "direct"
}, {
"type": "block",
"tag": "block"
}, {
"type": "dns",
"tag": "dns-out"
}],
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
},
{
"type": "dns",
"tag": "dns-out"
}
],
"route": {
"auto_detect_interface": true,
"override_android_vpn": true,
"rules": [{
"protocol": "dns",
"outbound": "dns-out"
}, {
"domain_suffix": "~pac~",
"outbound": "proxy"
}, {
"ip_cidr": ["0.0.0.0\/0"],
"outbound": "direct"
}]
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"createruleset": [
{
"name": "selfpac",
"interval": "15s",
"rules": [
{
"domain_suffix": "~pac~"
}
]
}
],
"outbound": "proxy"
}
],
"final": "direct"
}
}
+2 -2
View File
@@ -93,7 +93,7 @@ services:
ipv4_address: 10.10.1.2
logging: *default-logging
php:
image: mercurykd/vpnbot-php:1.4
image: mercurykd/vpnbot-php:1.5
build:
dockerfile: dockerfile/php.dockerfile
args:
@@ -491,7 +491,7 @@ services:
ipv4_address: 10.10.0.12
logging: *default-logging
wp:
image: mercurykd/vpnbot-wp:1
image: mercurykd/vpnbot-wp:1.1
build:
dockerfile: dockerfile/warp.dockerfile
args:
+6 -1
View File
@@ -26,5 +26,10 @@ RUN apk add --no-cache --update php81 \
&& tar -xf dnslookup-linux-amd64-v1.9.1.tar.gz \
&& mv linux-amd64/dnslookup /usr/bin \
&& rm dnslookup-linux-amd64-v1.9.1.tar.gz \
&& rm -rf /linux-amd64
&& rm -rf /linux-amd64 \
&& wget https://github.com/SagerNet/sing-box/releases/download/v1.8.11/sing-box-1.8.11-linux-amd64.tar.gz \
&& tar -xf sing-box-1.8.11-linux-amd64.tar.gz \
&& mv sing-box-1.8.11-linux-amd64/sing-box /usr/bin \
&& rm sing-box-1.8.11-linux-amd64.tar.gz \
&& rm -rf /sing-box-1.8.11-linux-amd64
ENV ENV="/root/.ashrc"
+3 -2
View File
@@ -1,5 +1,6 @@
FROM ubuntu:22.04
RUN apt update && apt install -y curl gpg socat lsb-release \
RUN apt update && apt install -y curl gpg socat jq lsb-release openssh-server \
&& curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg \
&& echo "deb [signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/cloudflare-client.list \
&& apt update && apt install -y cloudflare-warp
&& apt update && apt install -y cloudflare-warp \
&& mkdir /root/.ssh
+9
View File
@@ -1,6 +1,15 @@
cat /ssh/key.pub > /root/.ssh/authorized_keys
echo 'HostKeyAlgorithms +ssh-rsa' >> /etc/ssh/sshd_config
echo 'PubkeyAcceptedKeyTypes +ssh-rsa' >> /etc/ssh/sshd_config
service ssh start
warp-svc > /dev/null &
sleep 3
warp-cli --accept-tos registration new
key=$(cat /config/pac.json | jq -r .warp)
if [ ! -z "$key" ]
then
warp-cli --accept-tos registration license $key
fi
warp-cli --accept-tos mode proxy
warp-cli --accept-tos connect
socat TCP-LISTEN:4000,fork TCP:127.0.0.1:40000
+2
View File
@@ -0,0 +1,2 @@
winsw3.exe stop
winsw3.exe start
-35
View File
@@ -1,35 +0,0 @@
@echo off
setlocal
set "exe_path=sing-box.exe"
set "URL=~url~"
set "FileName=config.json"
set "PreviousHash="
taskkill /IM "%exe_path%" /F
powershell -command "(New-Object System.Net.WebClient).DownloadFile('%URL%', '%FileName%')"
for /F "skip=1 delims=" %%H in ('2^>nul CertUtil -hashfile "%FileName%" SHA256') do (
if not defined PreviousHash set "PreviousHash=%%H"
)
start "" /B "%CD%\%exe_path%" run -c "%FileName%"
echo "%PreviousHash%"
:loop
powershell -command "(New-Object System.Net.WebClient).DownloadFile('%URL%', '%FileName%')"
for /F "skip=1 delims=" %%H in ('2^>nul CertUtil -hashfile "%FileName%" SHA256') do (
if not defined HASH set "HASH=%%H"
)
set "CurrentHash=%HASH%"
set "HASH="
echo "%CurrentHash%"
if "%CurrentHash%" NEQ "%PreviousHash%" (
echo "change"
set "PreviousHash=%CurrentHash%"
taskkill /IM "%exe_path%" /F
start "" /B "%CD%\%exe_path%" run -c "%FileName%"
) else (
echo "not change"
)
timeout /t 15 /nobreak
goto :loop
+3 -1
View File
@@ -2,7 +2,8 @@
<id>singbox</id>
<name>singbox</name>
<description>singbox</description>
<executable>%BASE%\update.cmd</executable>
<executable>%BASE%\sing-box.exe</executable>
<arguments>run -c %BASE%\config.json</arguments>
<logmode>rotate</logmode>
<onfailure action="restart" delay="10 sec" />
<onfailure action="restart" delay="20 sec" />
@@ -12,4 +13,5 @@
<onexit action="restart" />
<onexit action="restart" />
<onexit action="none" />
<download from="~url~" to="%BASE%\config.json"/>
</service>
+8
View File
@@ -1,3 +1,11 @@
19.04.2024 v1.34
- формирование rule_set из шаблона singbox
18.04.2024 v1.33
- вывод статуса warp в меню
18.04.2024 v1.32
- фиксы в названии и отображении выбранного шаблона xtls
18.04.2024 v1.31
- возможность устанавливать ключ для warp
16.04.2024 v1.30.1
- улучшение сообщения об обновлениях
16.04.2024 v1.30