gekata/README.md
g00dvin 35b0ff1cd5
Some checks failed
Build and Push Docker Image / build-and-push (push) Has been cancelled
Udpate README.md
2025-09-13 13:26:58 +00:00

117 lines
12 KiB
Markdown
Raw Permalink 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.

**Gekata** — это легковесный сервис на Node.js для извлечения «связных доменов» с веб-страниц, запускаемый в контейнере Debian с Chromium; он сначала делает предзапросы с ручным следованием редиректам, затем при необходимости поднимает безголовый браузер, ограничивает глубину редиректов и кэширует результаты в SQLite через better-sqlite3. Сервис предоставляет HTTP API /domains, возвращающее финальный URL, цепочку редиректов и список связанных доменов, а также /health для проверки готовности.
### Назначение
Gekata сканирует заданный домен, разрешает маркетинговые и другие редиректы до целевой HTML-страницы, загружает её в безголовом Chromium и собирает множество доменных имён из всех сетевых запросов страницы, формируя список «связных доменов» для анализа интеграций, трекинга и CDN. Такой подход работает и для динамических сайтов с клиентским рендерингом.
### Архитектура
- Веб-сервер на Express предоставляет RESTмаршруты, принимает домен, валидирует его и инициирует сканирование, обрабатывая таймауты и коды ошибок.
- Предпроверка делает GET с ручным управлением редиректами, классифицируя сценарии: форс‑редиректы «маркетинга», запреты 403, скачивания и неHTML контент, чтобы экономить запуск браузера.
- Эскалация в безголовый Chromium (через Playwright) выполняет навигацию, применяя ограничение глубины редиректов только для документных переходов и ожидая «тихое окно» сети для стабильного сбора доменов.
- Кэширование результатов в SQLite с TTL ускоряет повторные запросы; используется лучшее для продакшна подключение better-sqlite3 и WALжурналирование для устойчивости.
### Потоки данных
- Вход: GET /domains?domain=<host> — принимает хост или URL, нормализует до ASCII/Punycode и формирует стартовый https:// URL.
- Предобработка: ручной обход 3xx с ограничением шагов; детекция «похожих на файл» ссылок и контента nonHTML; маркетинговый редирект помечается и может быть целевой.
- Сканирование браузером: навигация на целевой URL, слежение за запросами/ответами страницы, сбор доменов из всех сетевых событий, исключая шум (google/doubleclick по эвристике), построение цепочки редиректов для документной навигации.
- Выход: JSON с finalUrl, relatedDomains[], redirectChain[], статусами ok/skipped/blocked и служебными пометками (cached, ttl).
### API
- GET /domains
Параметры: domain — доменное имя или URL.
Ответ 200 ok:
- domain: нормализованный запрошенный домен.
- finalUrl: конечный URL после редиректов/навигации.
- relatedDomains: уникальные домены, замеченные при загрузке страницы.
- redirectChain: массив { from, to, status } для документных 3xx.
- cached: true/false, cachedAt, ttlAt.
- status: ok | skipped | blocked; дополнительные note/reason при skip/blocked.
- GET /health — простой JSON { ok: true } для readiness/liveness.
### Обработка редиректов
- На этапе предпроверки ограничение PRECHECK_MAX_REDIRECTS предотвращает бесконечные цепочки до запуска браузера; 403 заставляет эскалировать в браузер, nonHTML/attachment возвращают немедленный ответ.
- В браузере включён маршрут‑ограничитель только для документной навигации: запросы навигации обрабатываются с maxRedirects, ассеты идут без ограничений, чтобы не ломать рендеринг.
- Если лимит превышен, навигация завершается контролируемо и возвращается ошибка «Too many redirects», переводимая в понятный статус ответа API.
### Кэш и TTL
- SQLite таблица domain_cache хранит: домен, JSON списка доменов, финальный URL, цепочку редиректов, время обновления и ttl_at.
- Повторные обращения до истечения TTL возвращают сохранённый результат без запуска браузера, снижая задержки и нагрузку.
### Контейнеризация
- Образ состоит из двух стадий: builder и runtime, обе на debian:bookworm-slim.
- Стадия builder устанавливает Node.js, компилятор и заголовки SQLite для сборки nativeмодуля bettersqlite3, затем выполняет npm ci с пропуском devзависимостей и копирует исходники.
- Стадия runtime устанавливает tini как корректный PID 1, Node.js runtime, системный Chromium и минимальный набор X/GTK/NSS/GBM/шрифтов, необходимых для безголового режима; копируются node_modules и исходники из builder.
- Создаётся непривилегированный пользователь nodeuser; директория приложения принадлежит ему; сервис запускается не от root.
### Переменные окружения
- PORT — порт HTTP сервера (по умолчанию 3000).
- CHROMIUM_PATH — путь к системному Chromium (/usr/bin/chromium в контейнере).
- CACHE_TTL_SECONDS — срок жизни кэша (по умолчанию 6 часов).
- HARD_TIMEOUT_MS — жёсткий таймаут обработки HTTPзапроса (по умолчанию 70 секунд).
- MAX_REDIRECT_STEPS — максимальная глубина редиректов для документной навигации (по умолчанию 20).
- NAV_TIMEOUT_MS, QUIET_WINDOW_MS — таймауты навигации и «тихого окна» сети.
- DEBUG — включает подробные логи страницы/сетевых событий при значении 1.
### Безопасность и устойчивость
- tini как init обрабатывает сигналы и «зомби» процессы; контейнер корректно завершает Chromium по SIGTERM/SIGINT, предотвращая утечки.
- Запуск под непривилегированным пользователем снижает риск компрометации; Chromium стартует с флагами nosandbox/disablesetuid-sandbox, что совместимо с безпривилегированным окружением контейнеров.
- Ограничение редиректов для документных переходов устраняет зацикливание «маркетинговых» и неверных конфигураций, не влияя на загрузку ассетов.
### Производительность
- npm ci в builderстадии плюс копирование package*.json до исходников задействуют кэш слоёв Docker, ускоряя сборки.
- bettersqlite3 с синхронными подготовленными выражениями обеспечивает быстрый локальный кэш без отдельного сервиса БД.
- Предпроверка HTTP избавляет от лишних подъёмов браузера для неHTML или «прикреплённых» ответов.
### Сборка и запуск
- Сборка образа:
- docker build -t gekata:latest .
- Запуск контейнера:
- docker run --rm -p 3000:3000 -e CACHE_TTL_SECONDS=21600 -e MAX_REDIRECT_STEPS=20 gekata:latest
- Примеры запросов:
- curl -s "http://localhost:3000/health"
- curl -s "http://localhost:3000/domains?domain=forum.xda-developers.com"
### Журналирование и диагностика
- Лог‑метки [BOOT], [HTTP], [SCAN], [BROWSER], [CACHE], [SIGNAL] позволяют быстро локализовать этап и тип события.
- При включённом DEBUG=1 логируются консоль страницы, ошибки, неудавшиеся запросы и сетевые эвенты, что помогает анализировать блокировки, CORS, антибот‑защиту и таймауты.
### Ограничения
- Сайты с жёсткими антибот‑мерами (403/JSчелленджи) могут быть помечены как blocked или потребовать дополнительной эмуляции (например, иные useragent/locale/timezone/proxy).
- Сбор связанных доменов базируется на фактически выполненных сетевых запросах и может меняться при A/B тестах, гео‑таргетинге или различиях по useragent.
### Расширения и доработки
- Добавить белый/чёрный список доменов, тонкую фильтрацию трекеров и интеграций.
- Вынести кэш в внешний SQLiteфайл через volume для сохранения между рестартами, настроить резервное копирование.
- Параметризовать useragent/locale/timezone и добавить поддержку прокси для региональных сценариев.
- Экспортировать полный сетевой журнал и тайминги (HARподобный формат) как опциональную выгрузку.
### Файлы проекта
- server.js — основной сервис, логика API, предобработка, сканирование браузером, кэш, ограничения редиректов, завершение по сигналам.
- Dockerfile — двухстадийная сборка, системный Chromium в рантайме, tini, непривилегированный пользователь, переменные окружения и запуск службы.