diff --git a/app/bot.php b/app/bot.php
index 337adbc..9c38995 100644
--- a/app/bot.php
+++ b/app/bot.php
@@ -3966,10 +3966,10 @@ DNS-over-HTTPS with IP:
$text[] = "{$this->linkXray($i)}\n";
$text[] = "import subscribe:";
- $text[] = "v2rayng";
- $text[] = "sing-box";
- $text[] = "streisand";
- $text[] = "hiddify";
+ $text[] = "v2rayng";
+ $text[] = "sing-box";
+ $text[] = "streisand";
+ $text[] = "hiddify";
$text[] = "\nv2ray config: $scheme://{$domain}/pac?h=$hash&t=s&s={$c['id']}";
$text[] = "sing-box config: $scheme://{$domain}/pac?h=$hash&t=si&s={$c['id']}";
@@ -4116,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);
@@ -4185,6 +4186,7 @@ DNS-over-HTTPS with IP:
}
}
$c['route']['rules'] = array_values($c['route']['rules']);
+ $c['route'] = $this->createRuleSet($c['route'], $uid);
break;
}
@@ -4192,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);
diff --git a/config/sing.json b/config/sing.json
index b8fa4f8..319568c 100644
--- a/config/sing.json
+++ b/config/sing.json
@@ -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"
}
}
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index e17be96..0600311 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -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:
diff --git a/dockerfile/php.dockerfile b/dockerfile/php.dockerfile
index c3e50ee..711aa43 100644
--- a/dockerfile/php.dockerfile
+++ b/dockerfile/php.dockerfile
@@ -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"
diff --git a/singbox_windows/update.cmd b/singbox_windows/update.cmd
deleted file mode 100644
index df8ddda..0000000
--- a/singbox_windows/update.cmd
+++ /dev/null
@@ -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
diff --git a/singbox_windows/winsw3.xml b/singbox_windows/winsw3.xml
index 54beacc..5dddc87 100644
--- a/singbox_windows/winsw3.xml
+++ b/singbox_windows/winsw3.xml
@@ -2,7 +2,8 @@
singbox
singbox
singbox
- %BASE%\update.cmd
+ %BASE%\sing-box.exe
+ run -c %BASE%\config.json
rotate
@@ -12,4 +13,5 @@
+
\ No newline at end of file
diff --git a/version b/version
index 36f8b3e..6e8486e 100644
--- a/version
+++ b/version
@@ -1,3 +1,5 @@
+19.04.2024 v1.34
+- формирование rule_set из шаблона singbox
18.04.2024 v1.33
- вывод статуса warp в меню
18.04.2024 v1.32