Тексты: нейтральные формулировки

This commit is contained in:
maxdmitrov
2026-10-05 16:28:55 +03:00
parent 26019b39f4
commit f22e043902
5 changed files with 22 additions and 22 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
* `kit` без аргументов открывает меню, как у x-ui: нажали цифру – готово. Всё про сеть собрано в `kit net`: порты, протоколы, сайт маскировки, отпечаток. Команды остались для скриптов, команд стало меньше, а умеет `kit` больше. * `kit` без аргументов открывает меню, как у x-ui: нажали цифру – готово. Всё про сеть собрано в `kit net`: порты, протоколы, сайт маскировки, отпечаток. Команды остались для скриптов, команд стало меньше, а умеет `kit` больше.
* Установка теперь по шагам, а все ссылки разложены по полочкам: основные и запасные. Раньше они сыпались потоком, как лента новостей. * Установка теперь по шагам, а все ссылки разложены по полочкам: основные и запасные. Раньше они сыпались потоком, как лента новостей.
* Сайт-прикрытие подбирается среди соседей по подсети, а не «у всех один». Свой домен по-прежнему лучший вариант. REALITY теперь с `xtls-rprx-vision`, Hysteria2 отвечает на чужой запрос страницей сайта. * Сайт-прикрытие подбирается среди соседей по подсети, а не «у всех один». Свой домен по-прежнему лучший вариант. REALITY теперь с `xtls-rprx-vision`, Hysteria2 отвечает на чужой запрос страницей сайта.
* `kit check --deep` подключается к серверу настоящим клиентом, `--fix` лечит безопасное. Общий лимит трафика считается по всем подключениям пользователя, а в подписке Clash есть «Авто»: клиент сам выбирает быстрейший протокол. DNS в подписках теперь по DoH через прокси, чтобы имена сайтов не бегали к провайдеру на экскурсию. * `kit check --deep` подключается к серверу настоящим клиентом, `--fix` лечит безопасное. Общий лимит трафика считается по всем подключениям пользователя, а в подписке Clash есть «Авто»: клиент сам выбирает быстрейший протокол. DNS в подписках теперь по DoH через прокси: запросы имён не гуляют где попало.
* Вернулся `--restore`: чистый сервер поднимается из `kit backup`, как из резервной копии настроек телефона. Ссылки `kit user link --amnezia` и `--telegram` для AmneziaVPN и Telegram теперь одной командой, а исправление времени на Debian 13 прислал [xlok1e](https://github.com/xlok1e), спасибо. * Вернулся `--restore`: чистый сервер поднимается из `kit backup`, как из резервной копии настроек телефона. Ссылки `kit user link --amnezia` и `--telegram` для AmneziaVPN и Telegram теперь одной командой, а исправление времени на Debian 13 прислал [xlok1e](https://github.com/xlok1e), спасибо.
Сервер обновится сам этой ночью, нетерпеливым – `kit update`. Сервер обновится сам этой ночью, нетерпеливым – `kit update`.
+2 -2
View File
@@ -281,8 +281,8 @@ sh -c "$(curl -sSL https://raw.githubusercontent.com/jameszeroX/XKeen/main/insta
1. `kit check --deep` – проверит сервер и подключится к нему клиентом: так видно, виноват сервер или сеть. 1. `kit check --deep` – проверит сервер и подключится к нему клиентом: так видно, виноват сервер или сеть.
2. `kit net fp firefox` – другой отпечаток клиента, иногда помогает одной командой (вернуть: `kit net fp chrome`). 2. `kit net fp firefox` – другой отпечаток клиента, иногда помогает одной командой (вернуть: `kit net fp chrome`).
3. `kit net site` – новый сайт-прикрытие; `kit net on reality2` – второй REALITY на другом порту (помогает не у всех операторов). 3. `kit net site` – новый сайт-прикрытие; `kit net on reality2` – дополнительный REALITY на другом порту.
Если в вашей сети не проходит TCP, а UDP проходит (так бывает на мобильном интернете) – пользуйтесь Hysteria2: в подписке Clash «Авто» выберет её сама, в остальных приложениях – вручную. Один протокол не подключается – попробуйте соседний: у каждого свои сильные стороны (Hysteria2 работает по UDP, остальные по TCP). В подписке Clash «Авто» выбирает сама, в остальных приложениях – вручную.
4. Не помогло – перенесите сервер на другой адрес: `kit backup`, на новом сервере `bash 3x-ui.sh --restore файл`. 4. Не помогло – перенесите сервер на другой адрес: `kit backup`, на новом сервере `bash 3x-ui.sh --restore файл`.
Если подписка выдавалась на домене, а не на IP, клиентам достаточно сменить адрес в DNS. Если подписка выдавалась на домене, а не на IP, клиентам достаточно сменить адрес в DNS.
+2 -2
View File
@@ -159,7 +159,7 @@ kit check --fix # исправить безопасное
`kit check` проверяет службы, версии, срок сертификата, что панель не торчит наружу, права на файлы с `kit check` проверяет службы, версии, срок сертификата, что панель не торчит наружу, права на файлы с
паролями и ключами, ответ подписки для Happ, Hiddify, v2rayN и Clash, а также что сайт маскировки отвечает по паролями и ключами, ответ подписки для Happ, Hiddify, v2rayN и Clash, а также что сайт маскировки отвечает по
TLS 1.3 и HTTP/2, и подсказывает, что сделать заметнее (известный сайт на чужом IP, лишние порты). Вывод можно просто прислать в чат, если нужна помощь. TLS 1.3 и HTTP/2, и подсказывает, что улучшить (сайт маскировки, лишние порты). Вывод можно просто прислать в чат, если нужна помощь.
`kit check --fix` лечит только безопасное: перезапускает упавшие службы, возвращает права `600`, включает `kit check --fix` лечит только безопасное: перезапускает упавшие службы, возвращает права `600`, включает
автообновление, перечитывает сертификат и снимает TLS у встроенной подписки 3X-UI (его включает команда автообновление, перечитывает сертификат и снимает TLS у встроенной подписки 3X-UI (его включает команда
@@ -182,7 +182,7 @@ kit net masq on # Hysteria2 отвечает на чужой зап
``` ```
Лучший сайт маскировки – ваш собственный домен (`--domain` при установке): сервер изображает ваш сайт, а сертификат Лучший сайт маскировки – ваш собственный домен (`--domain` при установке): сервер изображает ваш сайт, а сертификат
и имя совпадают. Без домена установщик ищет сайт среди соседей по подсети сервера: это незаметнее, чем известный и имя совпадают. Без домена установщик ищет сайт среди соседей по подсети сервера: он естественнее, чем известный
сайт на чужом IP. Основные протоколы – REALITY, XHTTP и Hysteria2; остальные запасные, их можно выключить командой сайт на чужом IP. Основные протоколы – REALITY, XHTTP и Hysteria2; остальные запасные, их можно выключить командой
`kit net off`. `kit net off`.
+6 -6
View File
@@ -116,12 +116,12 @@ sni_alive() { sni_ok "$1"; }
SNI_RE='^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$' SNI_RE='^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$'
# Бесплатные и динамические имена (sslip.io, work.gd и т. п.) любят чужие прокси-серверы: под них маскироваться не стоит. # Бесплатные и динамические имена (sslip.io, work.gd и т. п.) часто используют чужие прокси-серверы: под них маскироваться не стоит.
SNI_DYN_RE='(^|\.)(sslip\.io|nip\.io|xip\.io|traefik\.me|work\.gd|duckdns\.org|ddns\.net|hopto\.org|zapto\.org|myftp\.biz|dynu\.net|freeddns\.org|no-ip\.(org|biz|info)|nom\.za|tk|ml|ga|cf|gq)$' SNI_DYN_RE='(^|\.)(sslip\.io|nip\.io|xip\.io|traefik\.me|work\.gd|duckdns\.org|ddns\.net|hopto\.org|zapto\.org|myftp\.biz|dynu\.net|freeddns\.org|no-ip\.(org|biz|info)|nom\.za|tk|ml|ga|cf|gq)$'
# Известные сайты на чужом IP заметны: сайт-прикрытие должен быть «своим» для подсети сервера. # Известные сайты на чужом IP не подходят: сайт-прикрытие должен быть «своим» для подсети сервера.
SNI_BRAND_RE='(^|\.)(google|googleapis|gstatic|youtube|microsoft|windows|apple|icloud|amazon|amazonaws|samsung|yahoo|cloudflare|facebook|instagram|netflix|github|telegram)\.[a-z.]+$' SNI_BRAND_RE='(^|\.)(google|googleapis|gstatic|youtube|microsoft|windows|apple|icloud|amazon|amazonaws|samsung|yahoo|cloudflare|facebook|instagram|netflix|github|telegram)\.[a-z.]+$'
# Имена с «сомнительными» словами не берём: маскироваться под такой сайт неприятно и небезопасно для вас. # Имена с «сомнительными» словами не берём: брать такой сайт для маскировки неприятно и небезопасно для вас.
SNI_BAD_RE='(probiv|porn|xxx|sex|adult|casino|bet|vpn|proxy|torrent|crack|hack|warez|drug|weapon|leak|escort|gambl|poker)' SNI_BAD_RE='(probiv|porn|xxx|sex|adult|casino|bet|vpn|proxy|torrent|crack|hack|warez|drug|weapon|leak|escort|gambl|poker)'
# У сайта настоящий сертификат: цепочка проходит проверку, имя совпадает. # У сайта настоящий сертификат: цепочка проходит проверку, имя совпадает.
@@ -1002,7 +1002,7 @@ proto_reality() {
} }
# Второй REALITY на высоком свободном порту, напрямую (без nginx). Где-то 443 и привычные порты # Второй REALITY на высоком свободном порту, напрямую (без nginx). Где-то 443 и привычные порты
# проходят хуже, чем высокий случайный; ключи, shortId и порт у него свои, сайт маскировки тот же. # бывает удобнее высокий случайный порт; ключи, shortId и порт у него свои, сайт маскировки тот же.
proto_reality2() { proto_reality2() {
local keys stream settings port local keys stream settings port
keys=$(api GET server/getNewX25519Cert) keys=$(api GET server/getNewX25519Cert)
@@ -1080,7 +1080,7 @@ proto_ss() {
proto_hy2() { proto_hy2() {
local settings stream local settings stream
settings=$(jq -nc --arg a "$(rand_str 16)" --argjson c "$(client_base hy2)" '{version: 2, clients: [$c + {auth: $a}]}') settings=$(jq -nc --arg a "$(rand_str 16)" --argjson c "$(client_base hy2)" '{version: 2, clients: [$c + {auth: $a}]}')
# На чужой HTTP/3-запрос сервер отвечает страницей сайта (masquerade), а не молчанием или ошибкой. # На посторонний HTTP/3-запрос сервер отвечает страницей сайта (masquerade), а не молчанием или ошибкой.
stream=$(jq -nc --argjson t "$(tls_json '["h3"]')" --arg page "${STUB_HTML:-}" '{network: "hysteria", security: "tls", tlsSettings: $t, stream=$(jq -nc --argjson t "$(tls_json '["h3"]')" --arg page "${STUB_HTML:-}" '{network: "hysteria", security: "tls", tlsSettings: $t,
hysteriaSettings: ({version: 2} + (if $page != "" then {masquerade: {type: "string", content: $page, statusCode: 200, headers: {"content-type": "text/html; charset=utf-8"}}} else {} end))}') hysteriaSettings: ({version: 2} + (if $page != "" then {masquerade: {type: "string", content: $page, statusCode: 200, headers: {"content-type": "text/html; charset=utf-8"}}} else {} end))}')
add_inbound "Hysteria2" "$PORT" udp hysteria "$settings" "$stream" add_inbound "Hysteria2" "$PORT" udp hysteria "$settings" "$stream"
@@ -1815,7 +1815,7 @@ PY
warn "IP сервера сменился: $old_ip → $HOST." warn "IP сервера сменился: $old_ip → $HOST."
echo "Старые подписки указывают на старый IP, поэтому клиентам нужно один раз добавить" echo "Старые подписки указывают на старый IP, поэтому клиентам нужно один раз добавить"
echo "подписку заново: ${B}kit user list${N}, затем ${B}kit user link имя${N}." echo "подписку заново: ${B}kit user list${N}, затем ${B}kit user link имя${N}."
echo "${D}Чтобы в следующий раз переезд прошёл незаметно для клиентов, ставьте сервер на домен (--cert, --key, --host).${N}" echo "${D}Чтобы в следующий раз переезд прошёл без хлопот для клиентов, ставьте сервер на домен (--cert, --key, --host).${N}"
else else
echo "Клиентам ничего менять не нужно: ключи, ссылки и подписки те же." echo "Клиентам ничего менять не нужно: ключи, ссылки и подписки те же."
fi fi
+11 -11
View File
@@ -837,22 +837,22 @@ check_system() {
if ((${used:-0} >= 95)); then c_warn "диск заполнен на ${used}%"; else c_ok "место на диске: занято ${used:-?}%"; fi if ((${used:-0} >= 95)); then c_warn "диск заполнен на ${used}%"; else c_ok "место на диске: занято ${used:-?}%"; fi
} }
# Заметность: известный сайт на чужом IP и запасные порты, которые на чужой заход отвечают пустой страницей. # Маскировка: известный сайт на чужом IP и запасные порты, которые на посторонний запрос отвечают пустой страницей.
check_stealth() { check_stealth() {
local id kind remark sni names list local id kind remark sni names list
while IFS=$'\t' read -r id kind remark sni; do while IFS=$'\t' read -r id kind remark sni; do
[[ $kind == reality && -n $sni && $sni =~ $SNI_BRAND_RE ]] || continue [[ $kind == reality && -n $sni && $sni =~ $SNI_BRAND_RE ]] || continue
same_net "$sni" || c_warn "$remark: $sni – известный сайт на чужом IP, это заметно. Надёжнее сосед по подсети: kit net site" same_net "$sni" || c_warn "$remark: $sni – известный сайт на чужом IP не годится для маскировки. Лучше сосед по подсети: kit net site"
done < <(sni_targets 2>/dev/null || true) done < <(sni_targets 2>/dev/null || true)
list=$(api GET inbounds/list 2>/dev/null) || return 0 list=$(api GET inbounds/list 2>/dev/null) || return 0
if jq -e 'any(.[]; .protocol == "hysteria" and .enable == true)' <<<"$list" >/dev/null && [[ -z $(hy_masq_state) ]]; then if jq -e 'any(.[]; .protocol == "hysteria" and .enable == true)' <<<"$list" >/dev/null && [[ -z $(hy_masq_state) ]]; then
c_warn "Hysteria2 на чужой HTTP/3-запрос отвечает не как сайт. Включить: kit net masq on" c_warn "Hysteria2 на посторонний HTTP/3-запрос отвечает не как сайт. Включить: kit net masq on"
fi fi
if [[ -z $(jq -r '.subJsonDns // ""' <<<"$(api POST setting/all '{}' 2>/dev/null)" 2>/dev/null) ]]; then if [[ -z $(jq -r '.subJsonDns // ""' <<<"$(api POST setting/all '{}' 2>/dev/null)" 2>/dev/null) ]]; then
c_warn "DNS в подписке Xray JSON обычный (UDP 8.8.8.8). Включить DoH через прокси: kit net dns on" c_warn "DNS в подписке Xray JSON обычный (UDP 8.8.8.8). Включить DoH через прокси: kit net dns on"
fi fi
names=$(jq -r '[.[] | select(.enable == true and .listen != "127.0.0.1" and (.remark == "VLESS-WS" or .remark == "Trojan-gRPC" or .remark == "VMess-WS")) | .remark] | join(", ")' <<<"$list") names=$(jq -r '[.[] | select(.enable == true and .listen != "127.0.0.1" and (.remark == "VLESS-WS" or .remark == "Trojan-gRPC" or .remark == "VMess-WS")) | .remark] | join(", ")' <<<"$list")
[[ -z $names ]] || c_warn "$names открыты на своих портах и на чужой заход отвечают пустой страницей. Не нужны? kit net off имя (режим «всё на 443» их прячет за сайтом)" [[ -z $names ]] || c_warn "$names открыты на своих портах и на посторонний запрос отвечают пустой страницей. Не нужны? kit net off имя (режим «всё на 443» прячет их за сайтом)"
} }
run_checks() { run_checks() {
@@ -1229,12 +1229,12 @@ SNI_POOL=(dl.google.com www.amazon.com www.samsung.com www.yahoo.com www.microso
SNI_RE='^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$' SNI_RE='^[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)+$'
# Бесплатные и динамические имена (sslip.io, work.gd и т. п.) любят чужие прокси-серверы: под них маскироваться не стоит. # Бесплатные и динамические имена (sslip.io, work.gd и т. п.) часто используют чужие прокси-серверы: под них маскироваться не стоит.
SNI_DYN_RE='(^|\.)(sslip\.io|nip\.io|xip\.io|traefik\.me|work\.gd|duckdns\.org|ddns\.net|hopto\.org|zapto\.org|myftp\.biz|dynu\.net|freeddns\.org|no-ip\.(org|biz|info)|nom\.za|tk|ml|ga|cf|gq)$' SNI_DYN_RE='(^|\.)(sslip\.io|nip\.io|xip\.io|traefik\.me|work\.gd|duckdns\.org|ddns\.net|hopto\.org|zapto\.org|myftp\.biz|dynu\.net|freeddns\.org|no-ip\.(org|biz|info)|nom\.za|tk|ml|ga|cf|gq)$'
# Известные сайты на чужом IP заметны: сайт-прикрытие должен быть «своим» для подсети сервера. # Известные сайты на чужом IP не подходят: сайт-прикрытие должен быть «своим» для подсети сервера.
SNI_BRAND_RE='(^|\.)(google|googleapis|gstatic|youtube|microsoft|windows|apple|icloud|amazon|amazonaws|samsung|yahoo|cloudflare|facebook|instagram|netflix|github|telegram)\.[a-z.]+$' SNI_BRAND_RE='(^|\.)(google|googleapis|gstatic|youtube|microsoft|windows|apple|icloud|amazon|amazonaws|samsung|yahoo|cloudflare|facebook|instagram|netflix|github|telegram)\.[a-z.]+$'
# Имена с «сомнительными» словами не берём: маскироваться под такой сайт неприятно и небезопасно для вас. # Имена с «сомнительными» словами не берём: брать такой сайт для маскировки неприятно и небезопасно для вас.
SNI_BAD_RE='(probiv|porn|xxx|sex|adult|casino|bet|vpn|proxy|torrent|crack|hack|warez|drug|weapon|leak|escort|gambl|poker)' SNI_BAD_RE='(probiv|porn|xxx|sex|adult|casino|bet|vpn|proxy|torrent|crack|hack|warez|drug|weapon|leak|escort|gambl|poker)'
# У сайта настоящий сертификат: цепочка проходит проверку, имя совпадает. # У сайта настоящий сертификат: цепочка проходит проверку, имя совпадает.
@@ -1358,7 +1358,7 @@ sni_rotate() { # [--nearby] [--dry-run] [сайт]
say "Ищу сайты в подсети сервера (около 250 коротких подключений к порту 443 соседних адресов)" say "Ищу сайты в подсети сервера (около 250 коротких подключений к порту 443 соседних адресов)"
while read -r a; do [[ -n $a ]] && pool+=("$a"); done < <(nearby_sites) while read -r a; do [[ -n $a ]] && pool+=("$a"); done < <(nearby_sites)
if ((${#pool[@]} == 0)); then if ((${#pool[@]} == 0)); then
warn "В подсети подходящего сайта не нашёл. Известный сайт на чужом IP заметнее остальных." warn "В подсети подходящего сайта не нашёл. Известный сайт на чужом IP подходит хуже остальных."
echo " Лучший выход – свой домен (установка с --domain) или свой сайт: kit net site сайт.com" echo " Лучший выход – свой домен (установка с --domain) или свой сайт: kit net site сайт.com"
if [[ -t 0 ]]; then if [[ -t 0 ]]; then
ask_tty " Взять запасной сайт из списка? [y/N] " ask_tty " Взять запасной сайт из списка? [y/N] "
@@ -1386,7 +1386,7 @@ sni_rotate() { # [--nearby] [--dry-run] [сайт]
done done
for i in "${!ids[@]}"; do for i in "${!ids[@]}"; do
if [[ ${news[$i]} =~ $SNI_BRAND_RE ]] && ! same_net "${news[$i]}"; then if [[ ${news[$i]} =~ $SNI_BRAND_RE ]] && ! same_net "${news[$i]}"; then
warn "Для ${remarks[$i]} в подсети не хватило сайтов – взят известный сайт из общего списка, он заметнее соседа. Лучше свой сайт: kit net site сайт.com" warn "Для ${remarks[$i]} в подсети не хватило сайтов – взят известный сайт из общего списка, он подходит хуже соседа. Лучше свой сайт: kit net site сайт.com"
break break
fi fi
done done
@@ -1645,7 +1645,7 @@ hy_masq() { # on|off
[[ -n $page ]] || page='<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Cumulo Cloud</title></head><body style="font-family:sans-serif;text-align:center;margin-top:20vh"><h1>Cumulo Cloud</h1><p>Service status: all systems operational.</p></body></html>' [[ -n $page ]] || page='<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Cumulo Cloud</title></head><body style="font-family:sans-serif;text-align:center;margin-top:20vh"><h1>Cumulo Cloud</h1><p>Service status: all systems operational.</p></body></html>'
inbound_patch "$id" '.streamSettings |= ((if type == "string" then fromjson else . end) | .hysteriaSettings.masquerade = {type: "string", content: $c, statusCode: 200, headers: {"content-type": "text/html; charset=utf-8"}})' --arg c "$page" \ inbound_patch "$id" '.streamSettings |= ((if type == "string" then fromjson else . end) | .hysteriaSettings.masquerade = {type: "string", content: $c, statusCode: 200, headers: {"content-type": "text/html; charset=utf-8"}})' --arg c "$page" \
|| die "Панель не приняла изменение. Ничего не изменилось." || die "Панель не приняла изменение. Ничего не изменилось."
say "Hysteria2 теперь отвечает на чужой HTTP/3-запрос страницей сайта." say "Hysteria2 теперь отвечает на посторонний HTTP/3-запрос страницей сайта."
else else
inbound_patch "$id" '.streamSettings |= ((if type == "string" then fromjson else . end) | del(.hysteriaSettings.masquerade))' || die "Панель не приняла изменение." inbound_patch "$id" '.streamSettings |= ((if type == "string" then fromjson else . end) | del(.hysteriaSettings.masquerade))' || die "Панель не приняла изменение."
say "Маскировка Hysteria2 выключена." say "Маскировка Hysteria2 выключена."
@@ -1732,7 +1732,7 @@ net_show() {
echo echo
echo "Отпечаток клиента: ${fpl:-?} (сменить: kit net fp firefox)" echo "Отпечаток клиента: ${fpl:-?} (сменить: kit net fp firefox)"
if jq -e 'any(.[]; .protocol == "hysteria")' <<<"$list" >/dev/null; then if jq -e 'any(.[]; .protocol == "hysteria")' <<<"$list" >/dev/null; then
if [[ -n $(hy_masq_state) ]]; then echo "Hysteria2 отвечает на чужой запрос страницей сайта (выключить: kit net masq off)" if [[ -n $(hy_masq_state) ]]; then echo "Hysteria2 отвечает на посторонний запрос страницей сайта (выключить: kit net masq off)"
else echo "Hysteria2 без маскировки под сайт (включить: kit net masq on)"; fi else echo "Hysteria2 без маскировки под сайт (включить: kit net masq on)"; fi
fi fi
} }