From d0bfb2dc38dd1f359d6b9b081e22ce55dfbe085d Mon Sep 17 00:00:00 2001 From: hacker07 Date: Tue, 13 Oct 2026 23:52:02 +0300 Subject: [PATCH] =?UTF-8?q?v1.2.18:=20=D1=81=D0=B2=D0=BE=D0=B9=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BC=D0=B5=D0=BD=20=D0=B8=D0=B7=20=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=8E=20=D0=BD=D0=B5=20=D0=BF=D0=BE=D0=B4=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=8F=D0=B5=D1=82=D1=81=D1=8F=20=D0=B7=D0=B0=D0=BF=D0=B0=D1=81?= =?UTF-8?q?=D0=BD=D1=8B=D0=BC=20=D1=81=D0=B0=D0=B9=D1=82=D0=BE=D0=BC=20(?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=B7=D0=B0=D0=BF=D0=B8?= =?UTF-8?q?=D1=81=D1=8B=D0=B2=D0=B0=D1=82=D1=8C=20=D0=B2=D1=8B=D0=B1=D0=BE?= =?UTF-8?q?=D1=80,=20=D0=BD=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D1=8F=D1=82=D1=8C=20TLS=20=D1=81=D0=B2=D0=BE=D0=B5=D0=B3=D0=BE?= =?UTF-8?q?=20=D0=B4=D0=BE=D0=BC=D0=B5=D0=BD=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FORK-CHANGELOG.md | 10 ++++++++++ VERSION | 2 +- scripts/3x-ui-local.sh | 2 +- scripts/3x-ui.sh | 14 +++++--------- scripts/hysteria2.sh | 2 +- scripts/kit.sh | 2 +- tools/fork_apply.py | 9 ++++++++- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/FORK-CHANGELOG.md b/FORK-CHANGELOG.md index 6943f8e..7e7d05a 100644 --- a/FORK-CHANGELOG.md +++ b/FORK-CHANGELOG.md @@ -1,3 +1,13 @@ +## v1.2.18: выбранный «свой домен» больше не подменяется соседом + +* Что было: после выбора «ввести свой домен» установщик всё равно брал запасной сайт из подсети. + Две причины, обе в моём коде: (1) выбор перезаписывался сырым значением меню (`own:домен`) + вместо самого домена; (2) домен проверялся на «TLS 1.3 + HTTP/2» — а до установки на нём ещё нет + сертификата, поэтому проверка честно не проходила и срабатывал откат на соседа. Теперь для своего + домена проверка TLS не делается (он указывает на этот сервер — установщик сам выпустит + сертификат Let's Encrypt), а автоподбор и запасной сайт включаются только если вы НЕ выбрали + ничего (автовыбор). + ## v1.2.17: меню маскировки идёт ПЕРВЫМ (меню автора больше не перебивает) * Причина, по которой меню не было видно: **меню спрашивал сам установщик** («Свой домен / Сосед / diff --git a/VERSION b/VERSION index b66183a..591bdbc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.2.17 +1.2.18 diff --git a/scripts/3x-ui-local.sh b/scripts/3x-ui-local.sh index 720cbd5..3c22bcc 100644 --- a/scripts/3x-ui-local.sh +++ b/scripts/3x-ui-local.sh @@ -44,7 +44,7 @@ set -Eeuo pipefail -KIT_VERSION="1.2.17" # версия сборки форка; должна совпадать с VERSION релиза +KIT_VERSION="1.2.18" # версия сборки форка; должна совпадать с VERSION релиза GITEA="${KIT_FORK_BASE:-https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS}" NS="3x-ui-kit-release" SIG_ID="releases@3x-ui-kit" diff --git a/scripts/3x-ui.sh b/scripts/3x-ui.sh index de36957..16ae0d4 100755 --- a/scripts/3x-ui.sh +++ b/scripts/3x-ui.sh @@ -30,7 +30,7 @@ wait_apt_idle() { XUI_VERSION="v3.9.0" # SHA256 установщика 3X-UI этой версии: тег могут передвинуть, а хеш – нет (проверено 2026-09-30). XUI_INSTALL_SHA256="18616fe26c8f6c92db6daa2dcd7cd53c5143ee69ecfd26d8ea6dc9b2c78607a6" -KIT_VERSION="1.2.17" +KIT_VERSION="1.2.18" # kit и kit-sub берём из того же релиза, что и этот скрипт, а не из меняющейся ветки main. KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$KIT_VERSION" # Ядро Xray для панели. С 26.7.x клиенты на Mihomo и sing-box (Hiddify, FlClash, @@ -625,10 +625,11 @@ kl_sni_menu() { NB_ALL=("${nb[@]}") # Наш шов: показываем найденное и даём выбрать — отдельно для REALITY и для XHTTP/MTProto. if [[ ${KL_PICK_SNI:-} == 1 && $yes == no ]] && { : /dev/null; then - local pick pick2 + local pick pick2 own_sni=no pick=$(kl_sni_menu "REALITY (TCP 443) — под какой сайт маскировать" ${nb[@]+"${nb[@]}"}) case $pick in own:*) + own_sni=yes DOMAIN=${pick#own:} if domain_points_here "$DOMAIN" 2>/dev/null; then SNI=$DOMAIN; ok "маскировка под свой домен: ${B}$DOMAIN${N} (сертификат Let's Encrypt выпустит установщик)" @@ -638,13 +639,8 @@ kl_sni_menu() { ;; sni:*) SNI=${pick#sni:} ;; esac - if ((${#nb[@]})); then - [[ -n $pick ]] && SNI=$pick || SNI=${nb[0]} - elif [[ -n $pick ]]; then - SNI=$pick - fi if [[ -n $SNI ]]; then - if ! sni_ok "$SNI"; then + if [[ $own_sni == no ]] && ! sni_ok "$SNI"; then warn "$SNI не отвечает по TLS 1.3 + HTTP/2 — беру найденное в подсети" SNI="${nb[0]:-$SNI}" fi @@ -663,7 +659,7 @@ kl_sni_menu() { if [[ -z $SNI ]] && ((${#nb[@]})); then SNI=${nb[0]}; SNI2=${SNI2:-${nb[1]:-}}; SNI3=${nb[2]:-} ok "найден: ${B}$SNI${N} · та же подсеть · TLS 1.3, h2, сертификат верный" - else + elif [[ -z $SNI ]]; then warn "В подсети подходящего сайта не нашёл." echo " Лучший выход – свой домен: запустите снова с --domain vpn.example.com" if [[ -n ${KL_PICK_SNI:-} && ${KL_PICK_SNI} == 1 && -z $SNI ]]; then diff --git a/scripts/hysteria2.sh b/scripts/hysteria2.sh index 1664f57..d11bca6 100755 --- a/scripts/hysteria2.sh +++ b/scripts/hysteria2.sh @@ -8,7 +8,7 @@ # Код выхода 1 при любом запуске (и при `__update_binary`) – старый `hy2 update` на нём # останавливается и не заменяет команду hy2. -KIT_VERSION="1.2.17" +KIT_VERSION="1.2.18" cat >&2 <<'MSG' Отдельный установщик Hysteria2 больше не поддерживается. diff --git a/scripts/kit.sh b/scripts/kit.sh index 6c8faac..5aed906 100644 --- a/scripts/kit.sh +++ b/scripts/kit.sh @@ -12,7 +12,7 @@ set -Eeuo pipefail export LC_ALL=C.UTF-8 # ширина колонок по символам, а не байтам -KIT_VERSION="1.2.17" +KIT_VERSION="1.2.18" KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/branch/main" # Файлы новой версии берём из её тега, а не из меняющейся ветки main. kit_ref_raw() { echo "https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$1"; } diff --git a/tools/fork_apply.py b/tools/fork_apply.py index bca4b97..603b46a 100644 --- a/tools/fork_apply.py +++ b/tools/fork_apply.py @@ -321,7 +321,14 @@ def main(): 'scripts/3x-ui.sh', ' if ((${#nb[@]})); then\n SNI=${nb[0]}; SNI2=${nb[1]:-}; SNI3=${nb[2]:-}\n', False, - ' # Наш шов: показываем найденное и даём выбрать — отдельно для REALITY и для XHTTP/MTProto.\n if [[ ${KL_PICK_SNI:-} == 1 && $yes == no ]] && { : /dev/null; then\n local pick pick2\n pick=$(kl_sni_menu "REALITY (TCP 443) — под какой сайт маскировать" ${nb[@]+"${nb[@]}"})\n case $pick in\n own:*)\n DOMAIN=${pick#own:}\n if domain_points_here "$DOMAIN" 2>/dev/null; then\n SNI=$DOMAIN; ok "маскировка под свой домен: ${B}$DOMAIN${N} (сертификат Let\'s Encrypt выпустит установщик)"\n else\n SNI=$DOMAIN; later "домен $DOMAIN не указывает на этот сервер — маскируюсь под него как под чужой сайт"\n fi\n ;;\n sni:*) SNI=${pick#sni:} ;;\n esac\n if ((${#nb[@]})); then\n [[ -n $pick ]] && SNI=$pick || SNI=${nb[0]}\n elif [[ -n $pick ]]; then\n SNI=$pick\n fi\n if [[ -n $SNI ]]; then\n if ! sni_ok "$SNI"; then\n warn "$SNI не отвечает по TLS 1.3 + HTTP/2 — беру найденное в подсети"\n SNI="${nb[0]:-$SNI}"\n fi\n ok "маскировка REALITY: ${B}$SNI${N}"\n fi\n if [[ " ${PROTOS[*]} " == *" xhttp "* || " ${PROTOS[*]} " == *" mtproto "* ]]; then\n pick2=$(kl_sni_menu "XHTTP и MTProto (различаются по имени сайта) — какой сайт взять" ${nb[@]+"${nb[@]}"})\n [[ $pick2 == sni:* ]] && pick2=${pick2#sni:}\n [[ $pick2 == own:* ]] && pick2=${pick2#own:}\n [[ -n $pick2 ]] && SNI2=$pick2\n [[ -n $SNI2 ]] && ok "маскировка XHTTP/MTProto: ${B}$SNI2${N}"\n fi\n fi\n if ((${#nb[@]})); then ok "подходящих соседей найдено: ${#nb[@]}"\n else warn "в подсети подходящих сайтов не нашлось (адреса проверены, откликов нет)"; fi\n if [[ -z $SNI ]] && ((${#nb[@]})); then\n SNI=${nb[0]}; SNI2=${SNI2:-${nb[1]:-}}; SNI3=${nb[2]:-}\n', + ' # Наш шов: показываем найденное и даём выбрать — отдельно для REALITY и для XHTTP/MTProto.\n if [[ ${KL_PICK_SNI:-} == 1 && $yes == no ]] && { : /dev/null; then\n local pick pick2 own_sni=no\n pick=$(kl_sni_menu "REALITY (TCP 443) — под какой сайт маскировать" ${nb[@]+"${nb[@]}"})\n case $pick in\n own:*)\n own_sni=yes\n DOMAIN=${pick#own:}\n if domain_points_here "$DOMAIN" 2>/dev/null; then\n SNI=$DOMAIN; ok "маскировка под свой домен: ${B}$DOMAIN${N} (сертификат Let\'s Encrypt выпустит установщик)"\n else\n SNI=$DOMAIN; later "домен $DOMAIN не указывает на этот сервер — маскируюсь под него как под чужой сайт"\n fi\n ;;\n sni:*) SNI=${pick#sni:} ;;\n esac\n if [[ -n $SNI ]]; then\n if [[ $own_sni == no ]] && ! sni_ok "$SNI"; then\n warn "$SNI не отвечает по TLS 1.3 + HTTP/2 — беру найденное в подсети"\n SNI="${nb[0]:-$SNI}"\n fi\n ok "маскировка REALITY: ${B}$SNI${N}"\n fi\n if [[ " ${PROTOS[*]} " == *" xhttp "* || " ${PROTOS[*]} " == *" mtproto "* ]]; then\n pick2=$(kl_sni_menu "XHTTP и MTProto (различаются по имени сайта) — какой сайт взять" ${nb[@]+"${nb[@]}"})\n [[ $pick2 == sni:* ]] && pick2=${pick2#sni:}\n [[ $pick2 == own:* ]] && pick2=${pick2#own:}\n [[ -n $pick2 ]] && SNI2=$pick2\n [[ -n $SNI2 ]] && ok "маскировка XHTTP/MTProto: ${B}$SNI2${N}"\n fi\n fi\n if ((${#nb[@]})); then ok "подходящих соседей найдено: ${#nb[@]}"\n else warn "в подсети подходящих сайтов не нашлось (адреса проверены, откликов нет)"; fi\n if [[ -z $SNI ]] && ((${#nb[@]})); then\n SNI=${nb[0]}; SNI2=${SNI2:-${nb[1]:-}}; SNI3=${nb[2]:-}\n', + 'авто-шов: replace, строк 2', + ), + ( + 'scripts/3x-ui.sh', + ' ok "найден: ${B}$SNI${N} · та же подсеть · TLS 1.3, h2, сертификат верный"\n else\n', + False, + ' ok "найден: ${B}$SNI${N} · та же подсеть · TLS 1.3, h2, сертификат верный"\n elif [[ -z $SNI ]]; then\n', 'авто-шов: replace, строк 2', ), (