diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ddd927b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +checker/ diff --git a/debug.md b/debug.md new file mode 100644 index 0000000..378e86e --- /dev/null +++ b/debug.md @@ -0,0 +1,90 @@ +# Локальная отладка 3dp-manager + +## Порты локального стенда +- frontend: `http://localhost:8080` +- backend API: `http://localhost:3100/api` +- postgres: `localhost:15432` + +## Запуск/перезапуск +```powershell +# полный запуск +docker compose -f docker-compose.local.yml up -d --build + +# частичный перезапуск только фронта +docker compose -f docker-compose.local.yml up -d --build --no-deps frontend + +# частичный перезапуск только бэка +docker compose -f docker-compose.local.yml up -d --build --no-deps server + +# статус контейнеров +docker compose -f docker-compose.local.yml ps +``` + +## Что уже встроено +- Backend scanner (RealiTLScanner) собирается в `server/Dockerfile` и кладется в контейнер backend. +- Блок `Автопоиск SNI (backend scanner)` показывается только если бинарник сканера доступен в контейнере. +- Предварительный список сканера: + - ручная проверка ссылками, + - удаление позиций, + - очистка, + - экспорт в `.txt`, + - сохранение состояния после F5. +- Основной список: + - ссылки на домены, + - hover-подсветка строк, + - экспорт полного списка в `.txt`. + +## Нормализация доменов (импорт и ручное добавление) +- Единые правила применяются и для загрузки файла, и для добавления по одному. +- `*.domain.com` нормализуется в `domain.com`. +- Комментарии и мусор отбрасываются (`#`, `;`, `//`, URL/пути/порты и т.п.). +- Дубликаты убираются без учета регистра. +- Явно некорректные значения отклоняются. + +## Тестовый "больной" список +- Файл для проверки импорта: `checker/domains-import-fuzz.txt` + +## Быстрые проверки +```powershell +Invoke-WebRequest -UseBasicParsing http://localhost:8080 +Invoke-WebRequest -UseBasicParsing http://localhost:3100/api +``` + +## Остановка +```powershell +docker compose -f docker-compose.local.yml down +``` + +## Перед PR +```powershell +git status --short +git diff --name-only +``` + +Проверяем, что в PR идут только целевые изменения фичи. + +## Обновление production (кастомная ветка) +Для сервера, где `bash <(curl ...)` не работает из-за `/dev/fd`, используем пайп: + +```bash +curl -fsSL https://raw.githubusercontent.com/iqubik/3dp-manager/dp-fix/update-custom.sh | bash -s -- -r https://github.com/iqubik/3dp-manager.git -b dp-fix +``` + +Что делает команда: +- подтягивает исходники из `iqubik/3dp-manager` ветки `dp-fix` в `/opt/3dp-manager-src`, +- собирает `backend/frontend` из этих исходников, +- поднимает контейнеры через `docker-compose.custom.yml` поверх текущей установки в `/opt/3dp-manager`. + +Проверка после обновления: + +```bash +cd /opt/3dp-manager +docker compose -f docker-compose.yml -f docker-compose.custom.yml ps +docker compose -f docker-compose.yml -f docker-compose.custom.yml logs --tail 120 backend +docker compose -f docker-compose.yml -f docker-compose.custom.yml logs --tail 120 frontend +``` + +Ожидаемо и нормально в логах frontend: +- `can not modify /etc/nginx/conf.d/default.conf (read-only file system?)` + +Это штатно при `:ro`-монтировании nginx-конфига. diff --git a/pub.md b/pub.md new file mode 100644 index 0000000..a2dcdf0 --- /dev/null +++ b/pub.md @@ -0,0 +1,99 @@ +# PR: Интеграция backend-автопоиска SNI в страницу доменов + +## Контекст и цель +Этот PR объединяет рабочий SNI-checker с интерфейсом 3dp так, чтобы пользователь мог: + +- запускать поиск кандидатов SNI прямо из страницы `Домены`, +- просматривать найденные домены в предварительном списке, +- вручную отбраковывать лишние записи, +- импортировать только проверенный набор в основной whitelist. + +Ключевая идея: сетево- и CPU-нагруженный скан остаётся на backend (в контейнере), а frontend отвечает за удобный, безопасный и понятный пользовательский сценарий. + +## Почему это сделано именно так +- Полноценный low-level скан (TLS/socket-поведение) недоступен обычному веб-frontend в браузере из-за ограничений платформы. +- Backend-контур позволяет использовать нативный бинарник сканера и системные утилиты без усложнения пользовательской среды. +- Такой подход снимает необходимость в ручном внешнем пайплайне “запуск скрипта отдельно + ручной импорт”, и делает процесс единым внутри UI 3dp. + +## Что сделано + +## 1) Backend: подключен scanner-сервис и API +- Добавлен отдельный сервис для запуска сканера и парсинга результатов. +- Добавлены API-эндпоинты: + - `GET /api/domains/scan/capabilities` — проверка доступности сканера и `timeout` в контейнере. + - `POST /api/domains/scan/start` — запуск скана с параметрами (`addr`, `scanSeconds`, `thread`, `timeout`). +- Добавлена защита от параллельных запусков (одновременно разрешён только один активный скан на инстанс backend). +- Реализован корректный сбор доменов из потока логов сканера, включая обработку “разрезанных” строк между чанками stdout. +- Добавлена нормализация/фильтрация найденных доменов перед отдачей во frontend. + +## 2) Docker backend: сборка и доставка RealiTLScanner в контейнер +- Добавлен отдельный multi-stage этап сборки бинарника из репозитория RealiTLScanner. +- Сборка привязана к фиксированному commit hash (reproducible build). +- Готовый бинарник копируется в runtime-образ backend и делается исполняемым. +- В runtime-образ добавлены утилиты, необходимые для сценария сканирования и проверки (`bash`, `curl`, `python3`, `gawk`, `coreutils`, `procps`, `ca-certificates` и др.). + +## 3) Frontend `/domains`: полный UX-сценарий автопоиска +- Добавлен блок **«Автопоиск SNI (backend scanner)»** как аккордеон. +- Блок показывается только когда backend сообщает, что scanner реально доступен. +- Состояние аккордеона запоминается (по умолчанию при первом открытии — свернут). +- Добавлены параметры запуска скана: + - IP/домен VPS, + - время скана, + - число потоков, + - таймаут проверки. +- Добавлен предварительный список найденных доменов: + - домены кликабельны (можно открыть и проверить вручную), + - можно удалять отдельные записи из предварительного списка, + - можно импортировать в основной whitelist только финальный отобранный набор. +- Добавлены кнопки очистки и экспорта: + - экспорт найденного предварительного списка, + - экспорт основного whitelist. +- Сохранение scanner-state в `localStorage`: + - сохраняются введённые параметры, + - сохраняется предварительный список, + - сохраняется последний результат скана, + - после F5 пользователь продолжает с того же места. +- При первом запуске и после очистки добавлена попытка авто-подстановки адреса (из settings/runtime host) в поле `IP/домен VPS`. + +## 4) Улучшение валидации доменов (основной список) +- Усилен серверный normalize/validate для одиночного добавления и пакетного импорта. +- Поддержаны практические случаи входных данных: + - wildcard-формат (`*.domain.com`) нормализуется в `domain.com`, + - удаляются лишние кавычки/обрамления/схемы URL/пути/порты, + - обрабатываются комментарии и мусорные строки в файлах импорта, + - устранено дублирование с учётом регистра (`LOWER(...)`). +- В результате поведение ручного добавления и импорта приведено к единым правилам. + +## 5) UI-полировка существующего блока whitelist +- Основной авторский блок управления whitelist визуально оформлен в общей стилистике страницы. +- Элементы списка сделаны ссылками на `https://...` для быстрой ручной проверки. +- Добавлена подсветка строк по hover в стиле интерфейса. + +## Что это даёт пользователю +- Единый встроенный workflow “поиск → ручная проверка → импорт” без внешних скриптов и копипаста. +- Меньше ошибок за счёт предварительного списка и точечного удаления лишних доменов. +- Меньше потери контекста: состояние поиска сохраняется между перезагрузками страницы. +- Более предсказуемая и чистая загрузка доменов из файлов. + +## Ограничения и осознанные решения +- Скан выполняется на backend (в контейнере), а не в браузере клиента: это осознанный компромисс в пользу технической реализуемости и стабильности. +- Выход `timeout` в режиме ограниченного времени скана интерпретируется как нормальный сценарий поиска, а не как критическая ошибка. +- Для предотвращения перегрузки включено ограничение на параллельные запуски сканера. + +## Проверка и валидация +Локально проверены сценарии: + +- старт/остановка скана и получение кандидатов, +- удаление отдельных записей из предварительного списка, +- импорт найденных доменов в основной whitelist, +- очистка предварительного списка, +- восстановление состояния после F5, +- ручное добавление и импорт “сложного” списка с комментариями/wildcard/обрамлениями, +- экспорт предварительного и основного списков. + +Отдельно просмотрены логи контейнеров (`server`, `frontend`, `postgres`) — критичных ошибок не зафиксировано, стек работает штатно. + +## Совместимость и риск +- Изменения локализованы в модуле `domains` и соответствующей странице frontend. +- Обратная совместимость API базового управления доменами сохранена. +- Риски регрессии умеренные и в основном касаются UX/валидации в доменном модуле; критичных инфраструктурных изменений вне этих зон нет.