Files
nixos/.agent/decisions/0003-3x-ui-reality-chain.md
T
oqyude 31f13ae365 docs(3x-ui): ADR-0003 — record immutable parts of the otreca REALITY chain
T10 removal of reality443Forwarding killed REALITY for 1.5h and looked like a total server outage. Records the 16:25->19:19 timeline, the failure signature (panel answers, 15380 refused), and rejects 3 alternatives: raising worker_connections, banning the retry storm, pinning the image.
2026-10-10 21:38:40 +03:00

99 lines
7.5 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.
# ADR-0003: цепочка 3x-ui REALITY на otreca — что нельзя менять
**Статус:** accepted
**Дата:** 2026-10-10
**Контекст:**
10 октября 2026 владелец сообщил: «по прежнему не работает xray inbound через
3x-ui на otreca. Не знаю, в какой момент после правок агента всё пошло не туда».
Разбор занял ~1.5 часа и дал неочевидный результат: **сервер был полностью
работоспособен**, а «поломка» читалась как системная катастрофа.
Хронология по коммитам и журналам:
| Время (MSK) | Событие |
|---|---|
| 16:25:52 | `0df9688` (задача T10) — удалён `reality443Forwarding` |
| 17:05:27 | первый `Connection refused` к `127.0.0.1:15380` в журнале nginx |
| 17:07:33 | первое `worker_connections are not enough` (с 37.128.246.126) |
| ~17:15 | клиенты уходят в ретрай-петлю: ~1668 ошибок за ~40 мин |
| 17:30:58 | `37b4956` — revert nftables (T3) |
| 17:54:18 | `07a0437` — `reality443Forwarding` восстановлен |
| 17:55:38 | контейнер `3xui_app` пересоздан с `127.0.0.1:15380:443/tcp` |
| ~18:05+ | флуд прекращается, ошибок 0 за 36 мин |
| 19:16–19:19 | живые REALITY-сессии, `oqyude` и `snity` online |
Два вывода, которые неочевидны и потому требуют фиксации:
1. **Отказ `reality443Forwarding` не выглядит как отказ Xray.** Контейнер
здоров (`restarts=0`), ядро 26.7.28 на месте, SSH жив, панель по SNI
`pubray1.zeroq.su` отвечает валидным сертификатом. Умер только маршрут
`443 → 15380`. Диагностировать «панель/Xray» по симптому бесполезно —
надо проверять порт и `podman inspect .NetworkSettings.Ports`.
2. **`worker_connections are not enough` — вторичный симптом, а не причина.**
nginx имеет пустой `events {}` → `worker_connections` = 512 (дефолт). Пока
маршрут на 443 был мёртв, реальные клиенты (37.128.246.126 — lanta-me,
Тамбов; 213.135.154.225 — Ростелеком, Тамбов) слали 517-байтные
ClientHello в цикле и выедали 512 соединений. Из-за этого «не работало
всё» даже там, где конкретная причина уже была устранена, и создавался
флуд в логах, уводящий от настоящей причины.
Отдельно: `x-ui.db.bak.1787862834` (2026-08-27) при поверхностном взгляде
выглядит как «бэкап, который можно откатить». Это **другая конфигурационная
эпоха** — инбаунды на портах 14380/14480/14910/14920, 7 клиентов, без
`dest media.mediavitrina.ru`. Откат заменил бы рабочие 443/8443 и обесценил
все 11 клиентских конфигов.
**Рассматриваемые альтернативы:**
1. **A. Оставить как есть, зафиксировать инвариантами (выбрано).** R1.10–R1.13
+ ловушки + порядок диагностики. Минимум правок в коде.
2. **B. Поднять `worker_connections` в `modules/vds/nginx.nix`.** Убирает
вторичный симптом, но **не первопричину**, а файл в AGENTS.md помечен как
мёртвый (T13: `networking.firewall.allowedTCPPorts` не применяется).
Отложено до отдельной задачи — не смешивать с починкой.
3. **C. Бан ретрай-флуда (fail2ban/rate-limit на 443).** Отклонено: флуд
создавали легитимные клиенты, а не атака. Jail `3x-ipl` в контейнере
(`maxRetry=1`) за инцидент не забанил никого — 0 банов. Любое усиление
должно отличать «шторм переподключений» от «злоупотребления».
4. **D. Пин версии образа 3x-ui вместо `:latest`.** Отклонено: противоречит
R1.5 (панель намеренно `:latest`). Схема БД мигрирует на месте при
обновлении — это отдельный риск, не решается версией образа.
**Решение:** вариант **A**. Зафиксированы R1.10 (уже был) и новые
R1.11–R1.13, две новые ловушки, порядок диагностики из 5 шагов и команды
проверки в раздел «Проверки».
**Обоснование:**
- **Стоимость ошибки асимметрична.** Удаление одной опции уронило прокси на
1.5 часа и выглядело как «сломался весь сервер». Повторение должно быть
видно в правилах, а не восстанавливаться снова.
- **Правило без сигнатуры бесполезно.** «Не удалять `reality443Forwarding`»
без описания симптома не помогает — агент видит «панель отвечает» и
concludes «3x-ui работает». Поэтому R1.10 дополнирован сигнатурой отказа
и порядком диагностики.
- **Нумерация R1 была сломана.** В `project-rules.md` два пункта были
помечены «8», из-за чего `reality443Forwarding` был девятым по счёту, но
AGENTS.md, ловушки и `f2e70bb` уже ссылались на него как на **R1.10**.
Порядок исправлен (R1.8 ядро, R1.9 бэкапы, R1.10 reality) — иначе
перекрёстные ссылки расходятся.
- **Откат БД — ловушка с высоким потенциалом.** Файл называется
`x-ui.db.bak.*` и выглядит как безопасный откат; на деле — снимок
другой эпохи. Запрет зафиксирован явно (R1.12).
**Последствия:**
- Любая правка `ports` в `modules/containers/3x-ui.nix` требует
`nixos-rebuild switch` **и** проверки `podman inspect .NetworkSettings.Ports` (R1.11).
- Деплой, пересоздающий `3xui_app`, = окно недоступности REALITY с
ретрай-флудом. Планировать такие деплои в нерабочее время.
- `worker_connections = 512` остаётся известным пробелом — отдельная задача,
файла в манифесте пока нет.
- Панель живёт по адресу `https://pubray1.zeroq.su/pubray/`; запрос к `/`
даёт 404 и это норма (ловушка в `project-rules.md`).
**Связанное:** R1.10–R1.13, R1.5, R1.8, T10, T3, `.agent/rules/project-rules.md`.