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

12 KiB
Raw Permalink Blame History

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= — принимает хост или 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 или «прикреплённых» ответов.

Сборка и запуск

Журналирование и диагностика

  • Лог‑метки [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, непривилегированный пользователь, переменные окружения и запуск службы.