Files
3X-UI_autoVPS/FORK.md
T

187 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Форк 3X-UI KIT (hacker07) — своя сборка и свой канал обновлений
Коротко: это [3X-UI KIT](https://github.com/itsnotkubrick/3X-UI_KIT) со своими доработками. Наш код
живёт рядом с кодом автора и не ломается, когда автор выпускает новую версию, а серверы ставятся и
обновляются **из этого репозитория** — релизы подписываются нашим ключом.
## С чего начать: новый VPS
1. Если нужен свой домен для маскировки — заранее направьте его A-запись на IP сервера и освободите
порт 80 (иначе Let's Encrypt не выпустит сертификат). Без домена этот шаг пропускается.
2. Одна команда на сервере (от root):
```bash
bash <(curl -fsSL https://git.rukavishnikoff.ru/hacker07/3X-UI_autoVPS/raw/branch/main/scripts/3x-ui-local.sh) --domain vpn.example.com
```
3. Скрипт делает всё сам: проверяет сервер → скачивает наш релиз и **проверяет подпись `SHA256SUMS`
и SHA256 установщика** → запускает установщик автора (панель 3X-UI, протоколы на 443,
сайт-заглушка, маскировка, сертификат, подписка, ufw) → закрывает ответ на ping, включает
обновления безопасности, делает `kit fix` → в конце показывает `kit check` и сводку
`kit local hardening`.
4. Забрать ссылки и подписку: `kit user link admin` (или адрес подписки из вывода установки).
Сомневаетесь в канале — сначала ничего не меняющие режимы:
```bash
bash <(curl -fsSL …/scripts/3x-ui-local.sh) --verify-only # только проверка подписи релиза
bash <(curl -fsSL …/scripts/3x-ui-local.sh) --dry-run --domain vpn.example.com # план установки
```
### Флаги установки
| Флаг | Что делает |
|---|---|
| `--domain домен` | свой домен для маскировки: сайт и REALITY маскируются под него (A-запись на сервер, свободный 80) |
| `--sni сайт.com` | маскировка под чужой сайт вместо домена |
| `--panel-on domain\|ip` | где открывать панель и подписку |
| `--ssh-port N` | добавить второй порт SSH (прежний продолжает работать; закрытие — отдельным шагом) |
| `--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`).
### Как проверить, что установка удалась
```bash
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`)
```bash
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 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` не принимает откат назад.
## Обновление сервера и канал
```bash
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`.
## Обновление от автора (с рабочей станции)
```bash
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`).
- Смена ключа: новый релиз подписывается **старым** ключом, иначе серверы его не примут.
## Грабли, о которых стоит помнить
1. **Ночное автообновление** (`kit-update.timer`, 03:00) перезаписывает `/usr/local/bin/kit` тем, что
лежит в настроенном репозитории. Канал и наши правки — один шаг, а не два.
2. **Переводы строк.** Релиз подписывается по суммам рабочей копии, а сервер сверяет их с файлами из
Gitea: при `core.autocrlf=true` суммы не сойдутся (CRLF против LF). В клоне должно быть
`git config core.autocrlf false` (и `.gitattributes`), проверка есть в `tools/fork-sync.sh`.
3. **Наш файл обязан быть в двух списках** — `FILES=(…)` в `tools/release.sh` и список загрузки
`fetch_release()` в `scripts/kit.sh`, иначе после обновления `kit-local.sh` останется старым.
4. **Панель 3X-UI ставится с GitHub** по закреплённой версии и SHA256 — это шаг автора; для установки
с нуля серверу нужен доступ к GitHub.
5. **Формат контрольных сумм.** `kit` сверяет имя файла в `SHA256SUMS` строго (`$2 == "путь"`).
На Windows `sha256sum` пишет `hash *путь`, и такие релизы `kit update` отклоняет («в подписанном
списке нет такого файла»), хотя `sha256sum -c` их принимает. Поэтому `tools/release.sh` приводит
список к POSIX-виду **до** подписи, а релизы **v1.2.1–v1.2.4 ставить нельзя** — только v1.2.5+.
Проверять релиз надо логикой самого `kit`, а не одной `sha256sum -c`.
6. **Сборка релиза обращается к GitHub** (сверка закреплённых версий панели и ядра). Из домашней сети
TLS до GitHub иногда рвётся (`schannel: failed to receive handshake`) — просто повторить запуск.
7. **Шапка `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`.