Table of Contents

Unknown Discovering — распознавание QUIC/HTTPS 0-RTT без SNI

Точка входа для LLM при анализе выгрузок неопознанного трафика без видимого SNI. Метод не завязан на QUIC: он применим к любому трафику, где в ClientHello нет SNI — QUIC 0-RTT (quic_unknown), HTTPS/TLS 1.3 с 0-RTT (early data), session resumption, ECH. Здесь описан метод классификации IP-узлов CDN по их роли в инфраструктуре провайдера сервисов. Наборы признаков (сеты хостов) по провайдерам — в пространстве имён :services.

Когда применять

Общие принципы анализа

Алгоритм классификации IP → сервис

Метод строит «землю» (ground truth) из флоу, где SNI виден, и применяет её к тому же IP там, где SNI отсутствует.

Шаг 1. Кандидаты

Из агрегированного netflow получить top host IP by traffic за период, отфильтровав неопознанный трафик без SNI, сортировка по суммарному объёму в обе стороны. Фильтр зависит от того, что разбираем: для QUIC это application protocol = “quic_unknown …”, для HTTPS 0-RTT — соответствующий неопознанный HTTPS/TLS-протокол. Это IP-кандидаты на классификацию.

Шаг 2. Земля по SNI

По каждому IP-кандидату выгрузить сырой netflow, где поле host (SNI) не пустое. Это выборка: какие SNI реально жили на этом IP.

Схема raw flow (важно):

Шаг 3. Оценка попадания в сет

Для каждого IP посчитать долю записей, чей host попадает по маске в набор сервиса. Если доля превышает порог сервиса — присвоить метку узлу IP:443.

Правила матчинга

Выделение и дополнение сетов

Отдельная задача: не проверить IP против готового набора, а построить набор масок для нового сервиса или дополнить существующий. Это обратный ход алгоритма.

Что запросить

Сырой netflow для изучаемого Host IP, где поле Host не пустое (та же схема, что на шаге 2: Host IP, Host, Source/Destination IPv4 + порт). Инструмента автоматической выгрузки пока нет — запросить выгрузку у аналитика (ручной ввод xlsx/csv).

Процедура

  1. Сгруппировать по Host IP; взять записи с непустым Host; серверный порт вывести как на шаге 2.
  2. Построить распределение FQDN: число записей на каждый Host (при необходимости — по eTLD+1). Отдельно посмотреть распределение по объёму (Octet delta) и отметить, если оно расходится с распределением по числу записей.
  3. Определить доминирующее семейство сервиса на IP. Проверить, что это не сторонний контент на общей инфраструктуре (см. мультитенантность).
  4. Обобщить FQDN в маски: свернуть случайные лейблы в wildcard (rr1—sn-xxx.googlevideo.com*.googlevideo.com); предпочитать суффиксные маски / eTLD+1; * по fnmatch (подстрока с точками). Маски держать достаточно узкими, чтобы не пересекались с наборами других сервисов.
  5. Выбрать порог: высокий (напр. 80%) для сервисов с высоким риском загрязнения общими фронтами (как youtube среди GFE), 50% для более «чистых» выделенных семейств. Обосновать выбор.
  6. Валидировать: прогнать маски по этой же выгрузке и, желательно, по выгрузкам из других временных диапазонов — набор стабилен, если те же IP/FQDN проходят порог в разных окнах.
  7. Зафиксировать на странице провайдера в :services в стандартном формате (метка, порог, маски) + заметка о причине порога и о рискованных масках.

Предостережения

Важные предостережения

Маршрутизация к наборам сервисов

Наборы масок по провайдерам — в :services:

DSL декларация

Формальная нотация для описания правил классификации. Основные конструкции: SELECT (выборка кандидатов, шаг 1), SET (декларация набора), RULE (правило классификации, шаг 3); плюс DISCOVER — обратный ход (выделение набора).

Общие соглашения:

SELECT — выборка кандидатов (шаг 1)

Отбор IP-кандидатов из агрегированного netflow. Здесь же задаётся фильтр по AS — он применяется ко всей выборке.

CANDIDATES =
  SELECT host_ip, total_volume
  FROM   top_ip_host_agg
  WHERE  application_protocol = "quic_unknown 49293"
     AND host_as IN (28917)            // Fiord
  ORDER BY total_volume DESC
  LIMIT  30

SET — декларация набора

Именованный набор: маски + порог. Фильтр — опционально.

SET instagram {
  masks:
    instagram.*.fbcdn.net
    *.cdninstagram.com
  threshold: 90%
}

Пример с фильтром на уровне набора (наборы Google):

SET google_play {
  masks:
    play.googleapis.com
  filter: host_as IN (15169)          // основная AS Google
  threshold: 50%
}

RULE — правило классификации (шаг 3)

Развёрнутая форма: ссылается на объявленный SET, порог берётся из набора.

RULE instagram {
  for ip in RAW
  match SET instagram
  if match_share_by_records > instagram.threshold
  then LABEL (ip:443) -> instagram
}

DISCOVER — выделение набора (обратный ход)

Не присваивает метку; возвращает распределение FQDN на IP, из которого строятся masks. Соответствует разделу «Выделение и дополнение сетов».

DISCOVER SET candidate
  FROM  RAW where host_ip = "35.241.31.20" and host is not null
  GROUP BY host
  RANK  BY records                     // по числу записей

Планируемое

Не актуально (нет инструмента для выгрузки)