Files
nixos/.agent/decisions/0003-3x-ui-reality-chain.md
T
oqyude 6a5b075039 docs(agent): R1.11-R1.13 — podman ports, x-ui.db rollback, panel TLS
Also fixes R1 numbering: two items were both labelled '8', so reality443Forwarding counted as ninth while AGENTS.md, traps and f2e70bb already referenced it as R1.10. Verification commands were executed against the live host: '{{json .Ports}}' and 'exec xray version' both fail, corrected to .NetworkSettings.Ports and /app/bin/xray-linux-amd64.
2026-10-10 21:43:00 +03:00

7.6 KiB
Raw Blame History

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 (адрес обезличен)
~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-сессии, клиенты 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 был мёртв, реальные клиенты слали 517-байтные ClientHello в цикле и выедали 512 соединений. Из-за этого «не работало всё» даже там, где конкретная причина уже была устранена, и создавался флуд в логах, уводящий от настоящей причины. Источники флуда — два адреса /24 из разных сетей; адреса и провайдеры обезличены (репозиторий публичный).

Отдельно: 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.