v1.2.17: меню маскировки первым (меню автора не перебивает) + исправление ask_yes
This commit is contained in:
@@ -1,3 +1,15 @@
|
|||||||
|
## v1.2.17: меню маскировки идёт ПЕРВЫМ (меню автора больше не перебивает)
|
||||||
|
|
||||||
|
* Причина, по которой меню не было видно: **меню спрашивал сам установщик** («Свой домен / Сосед /
|
||||||
|
Свой сайт») — и до нашего скана подсети дело не доходило. Теперь, когда включено наше меню,
|
||||||
|
меню автора не показывается вообще: сразу скан, список найденных доменов и выбор — из найденных,
|
||||||
|
автовыбор, общедоступный или свой домен. Отключить и вернуть поведение автора: `--auto-sni`.
|
||||||
|
* Ответ меню помечается: если вы ввели домен, который указывает на этот сервер, маскировка идёт
|
||||||
|
«под свой домен» (сертификат Let's Encrypt выпустит установщик); если не указывает — маскируюсь
|
||||||
|
под него как под чужой сайт и прямо об этом сообщаю.
|
||||||
|
* Входит исправление 1.2.16: возвращён `ask_yes` (в 1.2.13–1.2.15 при установке печаталось
|
||||||
|
`ask_yes: command not found`, и значения брались по умолчанию) + гейт «определение раньше вызова».
|
||||||
|
|
||||||
## v1.2.16: возвращён ask_yes (вылезало «command not found» при установке)
|
## v1.2.16: возвращён ask_yes (вылезало «command not found» при установке)
|
||||||
|
|
||||||
* При переносе вопросов наверх (v1.2.13) потерялось определение функции `ask_yes` — установщик
|
* При переносе вопросов наверх (v1.2.13) потерялось определение функции `ask_yes` — установщик
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
KIT_VERSION="1.2.16" # версия сборки форка; должна совпадать с VERSION релиза
|
KIT_VERSION="1.2.17" # версия сборки форка; должна совпадать с VERSION релиза
|
||||||
GITEA="${KIT_FORK_BASE:-https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS}"
|
GITEA="${KIT_FORK_BASE:-https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS}"
|
||||||
NS="3x-ui-kit-release"
|
NS="3x-ui-kit-release"
|
||||||
SIG_ID="releases@3x-ui-kit"
|
SIG_ID="releases@3x-ui-kit"
|
||||||
|
|||||||
+20
-5
@@ -30,7 +30,7 @@ wait_apt_idle() {
|
|||||||
XUI_VERSION="v3.9.0"
|
XUI_VERSION="v3.9.0"
|
||||||
# SHA256 установщика 3X-UI этой версии: тег могут передвинуть, а хеш – нет (проверено 2026-09-30).
|
# SHA256 установщика 3X-UI этой версии: тег могут передвинуть, а хеш – нет (проверено 2026-09-30).
|
||||||
XUI_INSTALL_SHA256="18616fe26c8f6c92db6daa2dcd7cd53c5143ee69ecfd26d8ea6dc9b2c78607a6"
|
XUI_INSTALL_SHA256="18616fe26c8f6c92db6daa2dcd7cd53c5143ee69ecfd26d8ea6dc9b2c78607a6"
|
||||||
KIT_VERSION="1.2.16"
|
KIT_VERSION="1.2.17"
|
||||||
# kit и kit-sub берём из того же релиза, что и этот скрипт, а не из меняющейся ветки main.
|
# kit и kit-sub берём из того же релиза, что и этот скрипт, а не из меняющейся ветки main.
|
||||||
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$KIT_VERSION"
|
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$KIT_VERSION"
|
||||||
# Ядро Xray для панели. С 26.7.x клиенты на Mihomo и sing-box (Hiddify, FlClash,
|
# Ядро Xray для панели. С 26.7.x клиенты на Mihomo и sing-box (Hiddify, FlClash,
|
||||||
@@ -576,7 +576,7 @@ kl_sni_menu() {
|
|||||||
[[ -z $ans ]] && return 0
|
[[ -z $ans ]] && return 0
|
||||||
[[ $ans =~ ^[0-9]+$ ]] || { printf ' введите номер из списка\n' >&2; continue; }
|
[[ $ans =~ ^[0-9]+$ ]] || { printf ' введите номер из списка\n' >&2; continue; }
|
||||||
i=$((10#$ans))
|
i=$((10#$ans))
|
||||||
if ((n)) && ((i >= 1 && i <= n)); then printf '%s' "${found[i - 1]}"; return 0; fi
|
if ((n)) && ((i >= 1 && i <= n)); then printf 'sni:%s' "${found[i - 1]}"; return 0; fi
|
||||||
((i == auto_idx)) && return 0
|
((i == auto_idx)) && return 0
|
||||||
if ((i == known_idx)); then
|
if ((i == known_idx)); then
|
||||||
printf '\nОбщедоступные сайты:\n' >&2
|
printf '\nОбщедоступные сайты:\n' >&2
|
||||||
@@ -586,7 +586,7 @@ kl_sni_menu() {
|
|||||||
read -r -t 300 ans <"$src" 2>/dev/null || true
|
read -r -t 300 ans <"$src" 2>/dev/null || true
|
||||||
ans=${ans//[[:space:]]/}
|
ans=${ans//[[:space:]]/}
|
||||||
if [[ $ans =~ ^[0-9]+$ ]] && ((10#$ans >= 1 && 10#$ans <= ${#known[@]})); then
|
if [[ $ans =~ ^[0-9]+$ ]] && ((10#$ans >= 1 && 10#$ans <= ${#known[@]})); then
|
||||||
printf '%s' "${known[10#$ans - 1]}"; return 0
|
printf 'sni:%s' "${known[10#$ans - 1]}"; return 0
|
||||||
fi
|
fi
|
||||||
printf ' ничего не выбрано — оставляю автовыбор\n' >&2
|
printf ' ничего не выбрано — оставляю автовыбор\n' >&2
|
||||||
return 0
|
return 0
|
||||||
@@ -596,7 +596,7 @@ kl_sni_menu() {
|
|||||||
ans=""
|
ans=""
|
||||||
read -r -t 300 ans <"$src" 2>/dev/null || true
|
read -r -t 300 ans <"$src" 2>/dev/null || true
|
||||||
ans=${ans//[[:space:]]/}
|
ans=${ans//[[:space:]]/}
|
||||||
[[ $ans =~ ^[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]] && { printf '%s' "$ans"; return 0; }
|
[[ $ans =~ ^[A-Za-z0-9.-]+\.[A-Za-z]{2,}$ ]] && { printf 'own:%s' "$ans"; return 0; }
|
||||||
printf ' не похоже на адрес сайта — оставляю автовыбор\n' >&2
|
printf ' не похоже на адрес сайта — оставляю автовыбор\n' >&2
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
@@ -609,7 +609,9 @@ kl_sni_menu() {
|
|||||||
if [[ -n $DOMAIN ]]; then
|
if [[ -n $DOMAIN ]]; then
|
||||||
[[ $PANEL_SSL == ip ]] || die "Свой домен работает с сертификатом панели Let's Encrypt на IP: освободите порт 80 и не указывайте --cert, --key и --panel-ssl none (сертификат для домена установщик получит сам)."
|
[[ $PANEL_SSL == ip ]] || die "Свой домен работает с сертификатом панели Let's Encrypt на IP: освободите порт 80 и не указывайте --cert, --key и --panel-ssl none (сертификат для домена установщик получит сам)."
|
||||||
domain_points_here "$DOMAIN" || die "Исправьте A-запись домена и запустите скрипт снова (DNS обновляется от нескольких минут до нескольких часов)."
|
domain_points_here "$DOMAIN" || die "Исправьте A-запись домена и запустите скрипт снова (DNS обновляется от нескольких минут до нескольких часов)."
|
||||||
elif [[ -z $SNI && $yes == no && $PANEL_SSL == ip && $multi == no && ! -f $XUI_ENV && -t 1 ]] && { : </dev/tty; } 2>/dev/null; then
|
# Наш шов: когда выбор сайта делает наше меню (KL_PICK_SNI=1), меню автора не показываем — иначе
|
||||||
|
# человек отвечает на «Свой домен / Сосед / Свой сайт», и до скана подсети дело не доходит.
|
||||||
|
elif [[ -z $SNI && $yes == no && $PANEL_SSL == ip && $multi == no && ! -f $XUI_ENV && -t 1 && ${KL_PICK_SNI:-0} != 1 ]] && { : </dev/tty; } 2>/dev/null; then
|
||||||
choose_masking
|
choose_masking
|
||||||
fi
|
fi
|
||||||
if [[ -n $DOMAIN ]]; then
|
if [[ -n $DOMAIN ]]; then
|
||||||
@@ -625,6 +627,17 @@ kl_sni_menu() {
|
|||||||
if [[ ${KL_PICK_SNI:-} == 1 && $yes == no ]] && { : </dev/tty; } 2>/dev/null; then
|
if [[ ${KL_PICK_SNI:-} == 1 && $yes == no ]] && { : </dev/tty; } 2>/dev/null; then
|
||||||
local pick pick2
|
local pick pick2
|
||||||
pick=$(kl_sni_menu "REALITY (TCP 443) — под какой сайт маскировать" ${nb[@]+"${nb[@]}"})
|
pick=$(kl_sni_menu "REALITY (TCP 443) — под какой сайт маскировать" ${nb[@]+"${nb[@]}"})
|
||||||
|
case $pick in
|
||||||
|
own:*)
|
||||||
|
DOMAIN=${pick#own:}
|
||||||
|
if domain_points_here "$DOMAIN" 2>/dev/null; then
|
||||||
|
SNI=$DOMAIN; ok "маскировка под свой домен: ${B}$DOMAIN${N} (сертификат Let's Encrypt выпустит установщик)"
|
||||||
|
else
|
||||||
|
SNI=$DOMAIN; later "домен $DOMAIN не указывает на этот сервер — маскируюсь под него как под чужой сайт"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
sni:*) SNI=${pick#sni:} ;;
|
||||||
|
esac
|
||||||
if ((${#nb[@]})); then
|
if ((${#nb[@]})); then
|
||||||
[[ -n $pick ]] && SNI=$pick || SNI=${nb[0]}
|
[[ -n $pick ]] && SNI=$pick || SNI=${nb[0]}
|
||||||
elif [[ -n $pick ]]; then
|
elif [[ -n $pick ]]; then
|
||||||
@@ -639,6 +652,8 @@ kl_sni_menu() {
|
|||||||
fi
|
fi
|
||||||
if [[ " ${PROTOS[*]} " == *" xhttp "* || " ${PROTOS[*]} " == *" mtproto "* ]]; then
|
if [[ " ${PROTOS[*]} " == *" xhttp "* || " ${PROTOS[*]} " == *" mtproto "* ]]; then
|
||||||
pick2=$(kl_sni_menu "XHTTP и MTProto (различаются по имени сайта) — какой сайт взять" ${nb[@]+"${nb[@]}"})
|
pick2=$(kl_sni_menu "XHTTP и MTProto (различаются по имени сайта) — какой сайт взять" ${nb[@]+"${nb[@]}"})
|
||||||
|
[[ $pick2 == sni:* ]] && pick2=${pick2#sni:}
|
||||||
|
[[ $pick2 == own:* ]] && pick2=${pick2#own:}
|
||||||
[[ -n $pick2 ]] && SNI2=$pick2
|
[[ -n $pick2 ]] && SNI2=$pick2
|
||||||
[[ -n $SNI2 ]] && ok "маскировка XHTTP/MTProto: ${B}$SNI2${N}"
|
[[ -n $SNI2 ]] && ok "маскировка XHTTP/MTProto: ${B}$SNI2${N}"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
# Код выхода 1 при любом запуске (и при `__update_binary`) – старый `hy2 update` на нём
|
# Код выхода 1 при любом запуске (и при `__update_binary`) – старый `hy2 update` на нём
|
||||||
# останавливается и не заменяет команду hy2.
|
# останавливается и не заменяет команду hy2.
|
||||||
|
|
||||||
KIT_VERSION="1.2.16"
|
KIT_VERSION="1.2.17"
|
||||||
|
|
||||||
cat >&2 <<'MSG'
|
cat >&2 <<'MSG'
|
||||||
Отдельный установщик Hysteria2 больше не поддерживается.
|
Отдельный установщик Hysteria2 больше не поддерживается.
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@
|
|||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
export LC_ALL=C.UTF-8 # ширина колонок по символам, а не байтам
|
export LC_ALL=C.UTF-8 # ширина колонок по символам, а не байтам
|
||||||
|
|
||||||
KIT_VERSION="1.2.16"
|
KIT_VERSION="1.2.17"
|
||||||
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/branch/main"
|
KIT_RAW="https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/branch/main"
|
||||||
# Файлы новой версии берём из её тега, а не из меняющейся ветки main.
|
# Файлы новой версии берём из её тега, а не из меняющейся ветки main.
|
||||||
kit_ref_raw() { echo "https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$1"; }
|
kit_ref_raw() { echo "https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/tag/v$1"; }
|
||||||
|
|||||||
+9
-2
@@ -300,9 +300,16 @@ def main():
|
|||||||
'scripts/3x-ui.sh',
|
'scripts/3x-ui.sh',
|
||||||
' later "Адрес $HOST не найден на сетевых интерфейсах сервера (бывает за NAT). Если ссылки не работают – запустите с --host и верным IP."\n fi\n\n',
|
' later "Адрес $HOST не найден на сетевых интерфейсах сервера (бывает за NAT). Если ссылки не работают – запустите с --host и верным IP."\n fi\n\n',
|
||||||
False,
|
False,
|
||||||
' later "Адрес $HOST не найден на сетевых интерфейсах сервера (бывает за NAT). Если ссылки не работают – запустите с --host и верным IP."\n fi\n\n# ---------------------------------------------------------------------------\n# Наш шов: выбор сайта маскировки по результатам скана подсети.\n# Печатает выбранное имя в stdout (пусто — оставляем автоподбор автора).\n# role — подпись для человека: REALITY или XHTTP/MTProto.\nkl_sni_menu() {\n local role=$1; shift\n local -a found=("$@")\n local -a known=("${SNI_CANDIDATES[@]}")\n local src=${KL_ASK_SRC:-/dev/tty} ans i k n auto_idx known_idx own_idx try\n n=${#found[@]}\n printf \'\\n%s%s%s\\n\' "$B" "$role" "$N" >&2\n if ((n)); then\n printf \'Найдено в подсети:\\n\\n\' >&2\n for i in "${!found[@]}"; do printf \' %d - %s\\n\' "$((i + 1))" "${found[i]}" >&2; done\n auto_idx=$((n + 1)); known_idx=$((n + 2)); own_idx=$((n + 3))\n printf \' %d - автовыбор из списка\\n\' "$auto_idx" >&2\n printf \' %d - выбрать общедоступный (например %s, %s)\\n\' "$known_idx" "${known[0]}" "${known[1]}" >&2\n printf \' %d - ввести свой домен\\n\\n\' "$own_idx" >&2\n else\n auto_idx=0; known_idx=1; own_idx=2\n printf \'В подсети доменов не найдено, выберите:\\n\\n\' >&2\n printf \' 1 - общедоступный (например %s, %s)\\n\' "${known[0]}" "${known[1]}" >&2\n printf \' 2 - ввести свой домен\\n\\n\' >&2\n fi\n printf \'Ваш выбор (Enter — автовыбор): \' >&2\n for try in 1 2 3; do\n ans=""\n read -r -t 300 ans <"$src" 2>/dev/null || true\n ans=${ans//[[:space:]]/}\n [[ -z $ans ]] && return 0\n [[ $ans =~ ^[0-9]+$ ]] || { printf \' введите номер из списка\\n\' >&2; continue; }\n i=$((10#$ans))\n if ((n)) && ((i >= 1 && i <= n)); then printf \'%s\' "${found[i - 1]}"; return 0; fi\n ((i == auto_idx)) && return 0\n if ((i == known_idx)); then\n printf \'\\nОбщедоступные сайты:\\n\' >&2\n for k in "${!known[@]}"; do printf \' %d - %s\\n\' "$((k + 1))" "${known[k]}" >&2; done\n printf \' 0 - назад\\nВаш выбор: \' >&2\n ans=""\n read -r -t 300 ans <"$src" 2>/dev/null || true\n ans=${ans//[[:space:]]/}\n if [[ $ans =~ ^[0-9]+$ ]] && ((10#$ans >= 1 && 10#$ans <= ${#known[@]})); then\n printf \'%s\' "${known[10#$ans - 1]}"; return 0\n fi\n printf \' ничего не выбрано — оставляю автовыбор\\n\' >&2\n return 0\n fi\n if ((i == own_idx)); then\n printf \' адрес сайта (например vpn.example.com): \' >&2\n ans=""\n read -r -t 300 ans <"$src" 2>/dev/null || true\n ans=${ans//[[:space:]]/}\n [[ $ans =~ ^[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$ ]] && { printf \'%s\' "$ans"; return 0; }\n printf \' не похоже на адрес сайта — оставляю автовыбор\\n\' >&2\n return 0\n fi\n printf \' такого номера нет\\n\' >&2\n done\n return 0\n}\n\n',
|
' later "Адрес $HOST не найден на сетевых интерфейсах сервера (бывает за NAT). Если ссылки не работают – запустите с --host и верным IP."\n fi\n\n# ---------------------------------------------------------------------------\n# Наш шов: выбор сайта маскировки по результатам скана подсети.\n# Печатает выбранное имя в stdout (пусто — оставляем автоподбор автора).\n# role — подпись для человека: REALITY или XHTTP/MTProto.\nkl_sni_menu() {\n local role=$1; shift\n local -a found=("$@")\n local -a known=("${SNI_CANDIDATES[@]}")\n local src=${KL_ASK_SRC:-/dev/tty} ans i k n auto_idx known_idx own_idx try\n n=${#found[@]}\n printf \'\\n%s%s%s\\n\' "$B" "$role" "$N" >&2\n if ((n)); then\n printf \'Найдено в подсети:\\n\\n\' >&2\n for i in "${!found[@]}"; do printf \' %d - %s\\n\' "$((i + 1))" "${found[i]}" >&2; done\n auto_idx=$((n + 1)); known_idx=$((n + 2)); own_idx=$((n + 3))\n printf \' %d - автовыбор из списка\\n\' "$auto_idx" >&2\n printf \' %d - выбрать общедоступный (например %s, %s)\\n\' "$known_idx" "${known[0]}" "${known[1]}" >&2\n printf \' %d - ввести свой домен\\n\\n\' "$own_idx" >&2\n else\n auto_idx=0; known_idx=1; own_idx=2\n printf \'В подсети доменов не найдено, выберите:\\n\\n\' >&2\n printf \' 1 - общедоступный (например %s, %s)\\n\' "${known[0]}" "${known[1]}" >&2\n printf \' 2 - ввести свой домен\\n\\n\' >&2\n fi\n printf \'Ваш выбор (Enter — автовыбор): \' >&2\n for try in 1 2 3; do\n ans=""\n read -r -t 300 ans <"$src" 2>/dev/null || true\n ans=${ans//[[:space:]]/}\n [[ -z $ans ]] && return 0\n [[ $ans =~ ^[0-9]+$ ]] || { printf \' введите номер из списка\\n\' >&2; continue; }\n i=$((10#$ans))\n if ((n)) && ((i >= 1 && i <= n)); then printf \'sni:%s\' "${found[i - 1]}"; return 0; fi\n ((i == auto_idx)) && return 0\n if ((i == known_idx)); then\n printf \'\\nОбщедоступные сайты:\\n\' >&2\n for k in "${!known[@]}"; do printf \' %d - %s\\n\' "$((k + 1))" "${known[k]}" >&2; done\n printf \' 0 - назад\\nВаш выбор: \' >&2\n ans=""\n read -r -t 300 ans <"$src" 2>/dev/null || true\n ans=${ans//[[:space:]]/}\n if [[ $ans =~ ^[0-9]+$ ]] && ((10#$ans >= 1 && 10#$ans <= ${#known[@]})); then\n printf \'sni:%s\' "${known[10#$ans - 1]}"; return 0\n fi\n printf \' ничего не выбрано — оставляю автовыбор\\n\' >&2\n return 0\n fi\n if ((i == own_idx)); then\n printf \' адрес сайта (например vpn.example.com): \' >&2\n ans=""\n read -r -t 300 ans <"$src" 2>/dev/null || true\n ans=${ans//[[:space:]]/}\n [[ $ans =~ ^[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$ ]] && { printf \'own:%s\' "$ans"; return 0; }\n printf \' не похоже на адрес сайта — оставляю автовыбор\\n\' >&2\n return 0\n fi\n printf \' такого номера нет\\n\' >&2\n done\n return 0\n}\n\n',
|
||||||
'авто-шов: insert, строк 3',
|
'авто-шов: insert, строк 3',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
'scripts/3x-ui.sh',
|
||||||
|
' elif [[ -z $SNI && $yes == no && $PANEL_SSL == ip && $multi == no && ! -f $XUI_ENV && -t 1 ]] && { : </dev/tty; } 2>/dev/null; then\n',
|
||||||
|
False,
|
||||||
|
' # Наш шов: когда выбор сайта делает наше меню (KL_PICK_SNI=1), меню автора не показываем — иначе\n # человек отвечает на «Свой домен / Сосед / Свой сайт», и до скана подсети дело не доходит.\n elif [[ -z $SNI && $yes == no && $PANEL_SSL == ip && $multi == no && ! -f $XUI_ENV && -t 1 && ${KL_PICK_SNI:-0} != 1 ]] && { : </dev/tty; } 2>/dev/null; then\n',
|
||||||
|
'авто-шов: replace, строк 1',
|
||||||
|
),
|
||||||
(
|
(
|
||||||
'scripts/3x-ui.sh',
|
'scripts/3x-ui.sh',
|
||||||
' echo "Подбираю сайт для маскировки среди соседей по подсети… (около 250 коротких обращений к порту 443 соседних адресов, около минуты; не нужно – запустите с --sni или --domain)"\n',
|
' echo "Подбираю сайт для маскировки среди соседей по подсети… (около 250 коротких обращений к порту 443 соседних адресов, около минуты; не нужно – запустите с --sni или --domain)"\n',
|
||||||
@@ -314,7 +321,7 @@ def main():
|
|||||||
'scripts/3x-ui.sh',
|
'scripts/3x-ui.sh',
|
||||||
' if ((${#nb[@]})); then\n SNI=${nb[0]}; SNI2=${nb[1]:-}; SNI3=${nb[2]:-}\n',
|
' if ((${#nb[@]})); then\n SNI=${nb[0]}; SNI2=${nb[1]:-}; SNI3=${nb[2]:-}\n',
|
||||||
False,
|
False,
|
||||||
' # Наш шов: показываем найденное и даём выбрать — отдельно для REALITY и для XHTTP/MTProto.\n if [[ ${KL_PICK_SNI:-} == 1 && $yes == no ]] && { : </dev/tty; } 2>/dev/null; then\n local pick pick2\n pick=$(kl_sni_menu "REALITY (TCP 443) — под какой сайт маскировать" ${nb[@]+"${nb[@]}"})\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 [[ -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/tty; } 2>/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',
|
||||||
'авто-шов: replace, строк 2',
|
'авто-шов: replace, строк 2',
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user