18 KiB
Форк 3X-UI KIT (hacker07) — своя сборка и свой канал обновлений
Коротко: это 3X-UI KIT со своими доработками. Наш код живёт рядом с кодом автора и не ломается, когда автор выпускает новую версию, а серверы ставятся и обновляются из этого репозитория — релизы подписываются нашим ключом.
С чего начать: новый VPS
- Если нужен свой домен для маскировки — заранее направьте его A-запись на IP сервера и освободите порт 80 (иначе Let's Encrypt не выпустит сертификат). Без домена этот шаг пропускается.
- Одна команда на сервере (от root) — дальше скрипт спросит сам: какие протоколы ставить (Enter — REALITY + AmneziaWG-3.1, «все» — набор автора), какую маскировку и домен, закрывать ли ответ на ping, включать ли автообновления, менять ли порт SSH (Enter — оставить текущий, число — перевести на него), менять ли пароль root:
bash <(curl -fsSL https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/branch/main/scripts/3x-ui-local.sh)
Те же ответы можно задать флагами — тогда вопросов не будет:
bash <(curl -fsSL …/scripts/3x-ui-local.sh) --protocols reality,hy2,awg,mtproto --domain vpn.example.com
- Скрипт делает всё сам: проверяет сервер → скачивает наш релиз и проверяет подпись
SHA256SUMSи SHA256 установщика → запускает установщик автора (панель 3X-UI, только выбранные протоколы, сайт-заглушка, маскировка, сертификат, подписка, ufw) → наши вопросы и правки (ping, автообновления, второй порт SSH, пароль root) →kit fix→ в конце показываетkit checkи сводкуkit local hardening. - Забрать ссылки и подписку:
kit user link admin(или адрес подписки из вывода установки).
Сомневаетесь в канале — сначала ничего не меняющие режимы:
bash <(curl -fsSL …/scripts/3x-ui-local.sh) --verify-only # только проверка подписи релиза
bash <(curl -fsSL …/scripts/3x-ui-local.sh) --dry-run --domain vpn.example.com # план установки
Флаги установки
| Флаг | Что делает |
|---|---|
--protocols список |
какие протоколы ставить: all, minimal или через запятую — reality,reality2,hy2,xhttp,ws,trojan,vmess,ss,tuic,wg,awg,awg3,mtproto. Невыбранные не создаются вообще. Без флага — вопрос, по умолчанию предлагаются REALITY + AmneziaWG-3.1 (ответ «все» — набор автора) |
--site N|random|off |
сайт-заглушка: конкретный из нашего набора (10 ИТ-сайтов), случайный (по умолчанию) или не трогать авторскую страницу (то же — --no-site) |
--yes |
не задавать вопросы (ping закрывается, автообновления включаются, порт SSH и пароль не трогаются) |
--harden |
закрыть ответ на ping и включить автообновления без вопросов |
--domain домен |
свой домен для маскировки: сайт и REALITY маскируются под него (A-запись на сервер, свободный 80) |
--sni сайт.com |
маскировка под чужой сайт вместо домена |
--panel-on domain|ip |
где открывать панель и подписку |
--ssh-port N |
перевести SSH на порт N (число 1024–65535). Прежний порт сам не закрывается: сначала проверьте вход во втором окне, потом kit local ssh --close-old N |
--no-harden |
не закрывать ответ на ping и не включать автообновления безопасности |
--no-time / --no-check |
не запускать kit fix / kit check |
--verify-only / --dry-run |
проверить релиз / показать план и ничего не менять |
| остальные | передаются установщику автора как есть: --host, --user, --port, --protocols, --restore, --multi-port, --cert/--key, --panel-ssl |
Чего скрипт не делает (сознательно): apt full-upgrade (тянет систему вперёд и может сломать
закреплённые панель 3X-UI 3.9.0 и ядро Xray 26.6.27 — вместо него обновления безопасности),
автоматическую перезагрузку и смену пароля root (в однострочник пароль не подставляем, он попал бы
в список процессов — для этого есть kit local passwd).
Как проверить, что установка удалась
kit check # без ❌: службы, порт 443 (nginx), подписка, маскировка, сертификат
kit local hardening # сводка: порты SSH, ответ на ping: deny, ufw активен, автообновления: включены
kit local channel # источник — этот репозиторий, ключей в KIT_SIGNERS: 1 (наш)
kit local version # версия сборки: 1.2.5 или новее
ping <IP сервера> # с домашней машины — таймаут: ответ на ping закрыт, это ожидаемо
kit user link admin # ссылка подписки; откройте её в браузере
Если ставили с доменом, в kit check должны быть строки «свой домен … указывает на этот сервер» и
«сайт маскировки … отвечает по TLS 1.3 и HTTP/2»; предупреждения про известный сайт на чужом IP
быть не должно (это касалось бы вспомогательного XHTTP, у REALITY должен быть ваш домен).
Команды форка (kit local)
kit local help # справка по всем командам форка
kit local version # версия, источник обновлений, дата сборки нашего файла
kit local channel # откуда берутся обновления и чем проверяется подпись
kit local seams # какие швы форка сейчас в установленном /usr/local/bin/kit
kit local masking # состояние маскировки (у REALITY должен быть свой домен)
kit local hardening # сводка по защите сервера
Защита сервера (поведение взято из проекта StressOzz/vps-setup, реализация своя и безопаснее):
| Команда | Что делает |
|---|---|
kit local site |
поставить случайный сайт-заглушку из нашего набора (10 ИТ-сайтов) и синхронизировать ответ Hysteria2 |
kit local site --list / kit local site 7 / --show |
список сайтов с номерами / поставить конкретный / какой стоит сейчас |
kit local ssh 2222 |
добавить порт SSH (прежние продолжают работать; порт сначала открывается в ufw, конфиг проверяется через sshd -t) |
kit local ssh --status |
какие порты SSH слушаются сейчас |
kit local ssh --close-old 2222 |
закрыть прежние порты после того, как новый проверен из второго окна |
kit local ping off|on|status |
ответ на ICMP echo: закрыть/вернуть/показать (правилом ufw, видно в ufw status) |
kit local passwd [юзер] |
сменить пароль (спросит дважды, в историю команд не попадёт) |
kit local passwd --generate |
сгенерировать пароль и показать один раз |
kit local upgrades on|off|status |
автообновления безопасности (только security, без перезагрузки) |
К любой правке можно добавить --dry-run — покажет план и ничего не изменит. Копии изменённых
файлов складываются в /root/kit-local-backup-<дата>/ (не в /tmp).
Что ping off затрагивает: только ICMP echo. Подписка (HTTPS), панель, REALITY/XHTTP (TCP 443),
Hysteria2 (UDP 443) работают как работали; исходящий ping с самого сервера тоже остаётся. Если
сервер есть в вашем мониторинге — пробу до него делайте по HTTPS/TCP, а не по ICMP.
Что где лежит
| Что | Где | Правит |
|---|---|---|
| Наши доработки (команды, хуки) | scripts/kit-local.sh |
только мы |
| Установка одной командой (обёртка) | scripts/3x-ui-local.sh |
только мы |
| Описание «швов» в коде автора | tools/fork_apply.py |
только мы |
| Синхронизация с автором и проверки | tools/fork-sync.sh |
только мы |
| Записи о наших версиях | FORK-CHANGELOG.md |
только мы |
Предупреждение в шапке README.md |
первые строки README.md |
только мы (шов) |
Файлы автора (scripts/kit.sh, scripts/3x-ui.sh, …) |
как есть | только автор |
Ключевая идея: в файлах автора мы правим только «швы» — несколько констант, одну строку подключения
и нормализацию сумм в релизном скрипте. Всё, что мы дописываем по существу, лежит в наших файлах.
Швы описаны в одном месте (tools/fork_apply.py) и накатываются только на чистое дерево автора;
если автор изменил нужную строку — инструмент останавливается и говорит об этом, а не делает
полу-патч.
Ветки и релизы
upstream— точная копия ветки автора (main), только вперёд.dev— наша сборка:upstream+ швы + наши файлы; из неё делаются релизы.main— то же состояние плюс документация после релиза (по нему считается «последняя версия»).- релизы — теги
v<номера>; номер =<версия автора>.<наш уровень>(автор 1.2 → наш 1.2.1; после релиза автора 1.3 → 1.3.1). Номер обязан строго расти:kit updateне принимает откат назад.
Обновление сервера и канал
kit update --force && kit check # тянет наш релиз из этого репозитория, проверяет нашу подпись
Источник файлов — KIT_RAW / kit_ref_raw() в scripts/kit.sh (наш Gitea и наш тег), подпись
проверяется ключом из KIT_SIGNERS (там только ключ форка). Ночной kit-update.timer (03:00) делает
то же автоматически — поэтому сервер и должен смотреть в этот репозиторий: иначе наши доработки
исчезнут в первую же ночь.
Вернуться на канал автора: скачать scripts/kit.sh из релиза автора с GitHub в /usr/local/bin/kit,
затем kit update --force.
Обновление от автора (с рабочей станции)
cd H:/My_Proj/Fork_3X-UI_KIT
bash tools/fork-sync.sh # подтянуть автора, перенести наши правки, прогнать проверки
# при конфликте — разобрать вручную: инструмент сам ничего не публикует
bash tools/release.sh ~/.ssh/3x-ui-kit-fork/release_key # SHA256SUMS + подпись нашим ключом
git add -A && git commit -m "Релиз v$(cat VERSION): …" && git tag v$(cat VERSION)
git push origin dev v$(cat VERSION) upstream
Подпись релизов
- Открытая часть ключа —
tools/fork-signer.pubи вKIT_SIGNERS(вscripts/kit.sh); она же вшита вscripts/3x-ui-local.sh, чтобы проверять подпись до запуска установщика. - Закрытая часть — только на рабочей станции владельца (
~/.ssh/3x-ui-kit-fork/release_key). В репозиторий, CI и на серверы не попадает: кто получит ключ — получит root на всех серверах, которые обновляются из этого репозитория. Пароль на ключ пока не установлен (ssh-keygen -p -f ~/.ssh/3x-ui-kit-fork/release_key). - Смена ключа: новый релиз подписывается старым ключом, иначе серверы его не примут.
Грабли, о которых стоит помнить
- Ночное автообновление (
kit-update.timer, 03:00) перезаписывает/usr/local/bin/kitтем, что лежит в настроенном репозитории. Канал и наши правки — один шаг, а не два. - Переводы строк. Релиз подписывается по суммам рабочей копии, а сервер сверяет их с файлами из
Gitea: при
core.autocrlf=trueсуммы не сойдутся (CRLF против LF). В клоне должно бытьgit config core.autocrlf false(и.gitattributes), проверка есть вtools/fork-sync.sh. - Наш файл обязан быть в двух списках —
FILES=(…)вtools/release.shи список загрузкиfetch_release()вscripts/kit.sh, иначе после обновленияkit-local.shостанется старым. - Панель 3X-UI ставится с GitHub по закреплённой версии и SHA256 — это шаг автора; для установки с нуля серверу нужен доступ к GitHub.
- Формат контрольных сумм.
kitсверяет имя файла вSHA256SUMSстрого ($2 == "путь"). На Windowssha256sumпишетhash *путь, и такие релизыkit updateотклоняет («в подписанном списке нет такого файла»), хотяsha256sum -cих принимает. Поэтомуtools/release.shприводит список к POSIX-виду до подписи, а релизы v1.2.1–v1.2.4 ставить нельзя — только v1.2.5+. Проверять релиз надо логикой самогоkit, а не однойsha256sum -c. - Сборка релиза обращается к GitHub (сверка закреплённых версий панели и ядра). Из домашней сети
TLS до GitHub иногда рвётся (
schannel: failed to receive handshake) — просто повторить запуск. - Шапка
README.md— наш шов. Человек, открывший репозиторий, читает README автора и видит там команду установки его сборки: поставив по ней, он получит авторский канал обновлений, и ночное автообновление вернёт авторскую сборку. Поэтому сверху вставлен наш блок. Если при обновлении автора здесь конфликт — оставляем наш блок вверху, остальное берём авторское.
Что проверено на сегодня
- Релиз
v1.2.5: подпись сходится с ключом из опубликованногоkit.sh, строгая сверка сумм$2 == путьдляkit.sh,kit-sub.py,kit-local.sh— как это делаетkitна сервере. - Публичный однострочник в режиме
--verify-onlyотвечает «подпись сошлась, SHA256 установщика совпал» — проверено снаружи, из домашней сети. - Установка «в бою» на живом сервере пока не прогонялась: сначала её стоит выполнить на новом VPS,
посмотрев
--verify-onlyи--dry-run.