projects:qoe_analytics:unknown_discovering:start

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
projects:qoe_analytics:unknown_discovering:start [2026/07/28 14:08] – Инструкция для LLM: алгоритм классификации quic_unknown по SNI-земле claudeprojects:qoe_analytics:unknown_discovering:start [2026/07/28 15:24] (current) – [Маршрутизация к наборам сервисов] evgeniy
Line 1: Line 1:
 ====== Unknown Discovering — распознавание QUIC/HTTPS 0-RTT без SNI ====== ====== Unknown Discovering — распознавание QUIC/HTTPS 0-RTT без SNI ======
  
-Точка входа для LLM при анализе выгрузок неопознанного трафика (application protocol вида ''quic_unknown''). Здесь описан метод классификации IP-узлов CDN по их роли в инфраструктуре провайдера сервисов. Наборы признаков (сеты хостов) по провайдерам — в пространстве имён [[projects:qoe_analytics:unknown_discovering:services:start|:services]].+Точка входа для LLM при анализе выгрузок неопознанного трафика **без видимого SNI**. Метод не завязан на QUIC: он применим к любому трафику, где в ClientHello нет SNI — QUIC 0-RTT (''quic_unknown''), HTTPS/TLS 1.3 с 0-RTT (early data), session resumption, ECH. Здесь описан метод классификации IP-узлов CDN по их роли в инфраструктуре провайдера сервисов. Наборы признаков (сеты хостов) по провайдерам — в пространстве имён [[projects:qoe_analytics:unknown_discovering:services:start|:services]].
  
 ===== Когда применять ===== ===== Когда применять =====
Line 21: Line 21:
  
 ==== Шаг 1. Кандидаты ==== ==== Шаг 1. Кандидаты ====
-Из агрегированного netflow получить top host IP by traffic за период с фильтром ''application protocol = "quic_unknown …"'', сортировка по суммарному объёму в обе стороны. Это IP-кандидаты на классификацию.+Из агрегированного netflow получить top host IP by traffic за период, отфильтровав неопознанный трафик без SNI, сортировка по суммарному объёму в обе стороны. Фильтр зависит от того, что разбираем: для QUIC это ''application protocol = "quic_unknown …"'', для HTTPS 0-RTT — соответствующий неопознанный HTTPS/TLS-протокол. Это IP-кандидаты на классификацию.
  
 ==== Шаг 2. Земля по SNI ==== ==== Шаг 2. Земля по SNI ====
Line 41: Line 41:
   * **Регистр** — матчинг регистронезависимый.   * **Регистр** — матчинг регистронезависимый.
   * **Порог** — у каждого сервиса свой (см. страницы в :services). Если порог берут несколько сервисов на одном IP — метка по максимальной доле.   * **Порог** — у каждого сервиса свой (см. страницы в :services). Если порог берут несколько сервисов на одном IP — метка по максимальной доле.
 +  * **Доп. фильтры набора.** Помимо масок host, набор может нести дополнительные фильтры (например по ''Host AS'' — номеру автономной системы). Записи, не проходящие фильтр, не учитываются ни в числителе, ни в знаменателе набора. Фильтры смотри на странице провайдера; они могут задаваться индивидуально для каждого набора.
 +
 +===== Выделение и дополнение сетов =====
 +
 +Отдельная задача: не проверить IP против готового набора, а **построить набор** масок для нового сервиса или дополнить существующий. Это обратный ход алгоритма.
 +
 +==== Что запросить ====
 +Сырой netflow для изучаемого ''Host IP'', где поле ''Host'' **не пустое** (та же схема, что на шаге 2: ''Host IP'', ''Host'', ''Source/Destination IPv4'' + порт). Инструмента автоматической выгрузки пока нет — запросить выгрузку у аналитика (ручной ввод xlsx/csv).
 +
 +==== Процедура ====
 +  - Сгруппировать по ''Host IP''; взять записи с непустым ''Host''; серверный порт вывести как на шаге 2.
 +  - Построить распределение FQDN: число записей на каждый ''Host'' (при необходимости — по eTLD+1). Отдельно посмотреть распределение по объёму (''Octet delta'') и отметить, если оно расходится с распределением по числу записей.
 +  - Определить доминирующее семейство сервиса на IP. Проверить, что это не сторонний контент на общей инфраструктуре (см. мультитенантность).
 +  - Обобщить FQDN в маски: свернуть случайные лейблы в wildcard (''rr1---sn-xxx.googlevideo.com'' → ''*.googlevideo.com''); предпочитать суффиксные маски / eTLD+1; ''*'' по fnmatch (подстрока с точками). Маски держать достаточно узкими, чтобы не пересекались с наборами других сервисов.
 +  - Выбрать порог: высокий (напр. 80%) для сервисов с высоким риском загрязнения общими фронтами (как youtube среди GFE), 50% для более «чистых» выделенных семейств. Обосновать выбор.
 +  - Валидировать: прогнать маски по этой же выгрузке и, желательно, по выгрузкам из **других временных диапазонов** — набор стабилен, если те же IP/FQDN проходят порог в разных окнах.
 +  - Зафиксировать на странице провайдера в :services в стандартном формате (метка, порог, маски) + заметка о причине порога и о рискованных масках.
 +
 +==== Предостережения ====
 +  * Не строить наборы по netblock / AS / IPv6-сигнатурам — это только подсказки для discovery, проверять по SNI-«земле».
 +  * Одна выгрузка = одно временное окно; подтверждать набор по нескольким окнам до финализации.
 +  * Следить за update/ad-инфраструктурой (''gvt1'', ''2mdn'', ''doubleclick''), которая может завышать долю сервиса — решать таксономию явно.
  
 ===== Важные предостережения ===== ===== Важные предостережения =====
Line 52: Line 74:
  
 Наборы масок по провайдерам — в [[projects:qoe_analytics:unknown_discovering:services:start|:services]]: Наборы масок по провайдерам — в [[projects:qoe_analytics:unknown_discovering:services:start|:services]]:
-  * [[projects:qoe_analytics:unknown_discovering:services:google|google]] — youtubegoogle_playgoogle_mapsgoogle_cloud, google_cdn + 
-  * [[projects:qoe_analytics:unknown_discovering:services:facebook|facebook meta]] + 
-  * [[projects:qoe_analytics:unknown_discovering:services:tiktok|tiktok]] +===== DSL декларация ===== 
-  * [[projects:qoe_analytics:unknown_discovering:services:apple|apple]]+ 
 +Формальная нотация для описания правил классификации. Основные конструкции: ''SELECT'' (выборка кандидатов, шаг 1), ''SET'' (декларация набора), ''RULE'' (правило классификации, шаг 3); плюс ''DISCOVER'' — обратный ход (выделение набора). 
 + 
 +Общие соглашения: 
 +  * Маски host — семантика fnmatch: ''*'' = любая подстрока, включая точки. 
 +  * Доля совпадения считается **только по числу записей** (by records). Знаменатель — записи с непустым host на IP, прошедшие фильтры. 
 +  * Комментарии — ''//'' до конца строки. 
 +  * Строковые значения с пробелами/числами — в кавычках (напр. ''"quic_unknown 49293"''). 
 + 
 +==== SELECT — выборка кандидатов (шаг 1) ==== 
 +Отбор IP-кандидатов из агрегированного netflow. Здесь же задаётся фильтр по AS — он применяется ко всей выборке. 
 + 
 +<code> 
 +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 
 +</code> 
 + 
 +  ''WHERE'' — условия отбора; ''host_as IN (...)'' — список AS (под несколько значений). 
 +  * Фильтр по AS обычно живёт здесь, на шаге 1, и применяется ко всему пулу кандидатов. Примеркеш-сервер Instagram развёрнут в Fiord (''AS28917''), поэтому AS фильтруется на выборке, а не в наборе. 
 + 
 +==== SET — декларация набора ==== 
 +Именованный набормаски + порог. Фильтр — опционально. 
 + 
 +<code> 
 +SET instagram { 
 +  masks: 
 +    instagram.*.fbcdn.net 
 +    *.cdninstagram.com 
 +  threshold90% 
 +
 +</code> 
 + 
 +  * ''masks'' — многострочный список масок (fnmatch). 
 +  * ''threshold'' — порог на набор; единственный источник истины по порогу. 
 +  * ''ttl'' — необязательный срок годности метки (напр. ''30d''''60d''''90d''). По истечении узел требует повторной проверкит.к. IP в CDN ротируются. Задаётся на набор. 
 +  * ''filter'' — необязательное поле. Обычно опускается, потому что фильтр по AS задаётся на шаге 1 (в ''SELECT''). Указывается только когда конкретному набору нужен доп. фильтр, отличный от выборки шага 1 (см. наборы Google, где ''Host AS'' задан пофакторно). 
 + 
 +Пример с фильтром на уровне набора (наборы Google): 
 +<code> 
 +SET google_play { 
 +  masks: 
 +    play.googleapis.com 
 +  filterhost_as IN (15169)          /основная AS Google 
 +  threshold50% 
 +
 +</code> 
 + 
 +==== RULE — правило классификации (шаг 3) ==== 
 +Развёрнутая формассылается на объявленный ''SET'', порог берётся из набора. 
 + 
 +<code> 
 +RULE instagram { 
 +  for ip in RAW 
 +  match SET instagram 
 +  if match_share_by_records > instagram.threshold 
 +  then LABEL (ip:443) -> instagram 
 +
 +</code> 
 + 
 +  * ''for ip in RAW'' — перебор IP из сырого netflow (записи с непустым host). 
 +  * ''match SET instagram'' — сверка host каждой записи с масками набора. 
 +  * ''match_share_by_records'' — доля по числу записей (единственная метрика в этом алгоритме). 
 +  * ''LABEL (ip:443) -> instagram'' — присвоение метки узлу. 
 +  * Если у набора задан ''filter'', он применяется здесь жезаписи вне фильтра не идут ни в числитель, ни в знаменатель. 
 + 
 +==== DISCOVER — выделение набора (обратный ход) ==== 
 +Не присваивает метку; возвращает распределение FQDN на IP, из которого строятся ''masks''. Соответствует разделу «Выделение и дополнение сетов». 
 + 
 +<code> 
 +DISCOVER SET candidate 
 +  FROM  RAW where host_ip = "35.241.31.20" and host is not null 
 +  GROUP BY host 
 +  RANK  BY records                     // по числу записей 
 +</code>
  
 ===== Планируемое ===== ===== Планируемое =====
  • projects/qoe_analytics/unknown_discovering/start.1785240518.txt.gz
  • Last modified: 2026/07/28 14:08
  • by claude