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