InfraGuard

IP-соединения

Хостовое представление удалённых IP-узлов по каждому серверу в виде точек интенсивности по портам, с всплывающим окном расследования IP: разбивка соединений, история по агрегатам, гео/ASN, репутация и прямая ссылка на блокировку.

Обзор — что делает экран

IP-соединения — второй экран раздела Инфраструктура ▸ Подключения и трафик (host view). Если Соединения по портам строятся вокруг связки «порт → сервер», то этот экран строится вокруг связки «сервер (хост) → удалённый IP-узел». На карточке каждого сервера перечислены удалённые IP-адреса, подключённые к нему в данный момент, упорядоченные по интенсивности соединений, и для каждого IP показана точка интенсивности сессий по каждому наблюдаемому порту. Цель — с одного взгляда понять, какой IP обращается к какому серверу, по какому порту и насколько интенсивно.

Щелчок по удалённому IP открывает общее всплывающее окно расследования IP, где можно изучить разбивку соединений этого IP (какой сервер / порт / состояние TCP / число сессий), спарклайн истории соединений по агрегатам, обогащение гео/ASN/провайдер, внешнюю ссылку на репутацию и прямую ссылку на блокировку в Блок-лист — всё в одном месте.

Все данные читаются только на чтение из унаследованной БД трафика (legacy_glory). Этот экран ничего не записывает — операции записи, такие как блокировка, передаются по прямой ссылке из всплывающего окна на экран Блок-лист, где запись и происходит.

Когда использовать

Компоновка

Шапка · таймер

В правом верхнем углу расположены переключатель таймера (1 мин / 5 мин / 1 час), задающий окно отображения, метка времени последнего снимка и кнопка ручного обновления. Таймер — это длина окна запроса, привязанного к последнему снимку.

таймер Окно запроса
1 (по умолчанию) Только одна минута последнего снимка
5 Последние 5 минут от последнего снимка
60 Последние 60 минут от последнего снимка

Выбранный таймер сохраняется в localStorage['infr:timer:traffic-ips'] между визитами. Допустимы только значения 1/5/60; любое другое приводится к 1.

Легенда интенсивности + чипы серверов

Карточки серверов (хостов)

По одной карточке на каждый выбранный сервер. В заголовке — имя хоста и число удалённых узлов, в теле — таблица.

Карточки можно перетаскивать за рукоятку для изменения порядка (порядок сохраняется в infr:order:traffic-ips), они перестраиваются кладкой с растягиванием по строкам и разбиваются на страницы по 20 штук.

Цвета точки интенсивности по портам

Сессии Токен Цвет Значение
0 none бледный На этом порту соединений нет
1–9 good зелёный Низкая интенсивность
10–49 warn янтарный Средняя интенсивность
50+ crit красный Высокая интенсивность

Всплывающее окно расследования IP

Работает на общем миксине mixins/ip_detail.js и частичном шаблоне infra/partials/ip-detail-modal.blade.php. У него два режима.

  1. режим sources — список IP-источников в окне (сервер, порт). Вход из круга SRC на экране Соединения по портам.
  2. режим investigate (вход по умолчанию с этого экрана) — углублённый разбор одного IP. Вход по щелчку на строке узла.

Что показывает режим investigate:

Область Содержимое Источник
Сводные KPI Всего сессий · число серверов · число портов · первое/последнее наблюдение ipSeenSpan() (MIN/MAX(created_at) за весь срок хранения)
Гео Страна · город · ASN · провайдер ip_info_loop (ipEnrichment())
История соединений спарклайн по гранулярности (5min / 1hour / 1day) таблицы агрегатов (ipHistory())
Разбивка соединений Сессии по серверу × порту × состоянию TCP · удалённые порты · первое/последнее traffic_session_ct (ipBreakdown())

Действия в нижней части окна (investigate): Скопировать IP · Показать IP (повторное расследование на этой странице через ?src_ip=) · Репутация ↗ (внешний AbuseIPDB, новая вкладка) · Заблокировать IP (прямая ссылка в Блок-лист через ?add=).

Кнопка Репутация ↗ в этом окне — обычная ссылка, открывающая внешний abuseipdb.com/check/… в новой вкладке. Встроенное окно репутации, показывающее шкалу доверия и историю жалоб прямо в консоли, — это возможность экранов раздела «Безопасность»; см. Репутация IP.

Как пользоваться

Базовый порядок действий

  1. Задайте окно (1/5/60 мин) с помощью таймера. Чем оно короче, тем ближе к состоянию «подключён прямо сейчас».
  2. Сузьте список до интересующих серверов с помощью чипов серверов (по умолчанию выбраны все).
  3. На карточке сервера ищите узлы с красной точкой интенсивности (50 сессий и больше) или узлы, охватывающие несколько портов.
  4. Щёлкните по строке подозрительного узла, чтобы открыть окно расследования.
  5. В окне используйте разбивку соединений, чтобы увидеть, на какой сервер, порт и состояние пришлись обращения, историю — чтобы оценить устойчивость (разовое явление или повторяющееся), и гео/ASN — чтобы понять происхождение.
  6. При необходимости проверьте внешнюю историю жалоб через Репутация ↗, а если IP вредоносный — передайте его в Блок-лист кнопкой Заблокировать IP.

Переключение гранулярности истории

Переключение гранулярности в разделе истории меняет используемую таблицу агрегатов. Гранулярность по умолчанию — часовая (1hour), лучший баланс плотности и скорости.

5min    → traffic_session_ct_5min   · отдельный IP · окно −6h от последнего снимка
1hour   → traffic_session_ct_1hour  · отдельный IP · окно −3d от последнего снимка   (по умолчанию)
1day    → traffic_session_ct_1day   · блок /24     · окно −120d от последнего снимка

Суточная (1day) история агрегируется по блоку /24 этого IP (первые 3 октета, 256 адресов), а не по отдельному IP — потому что сборщик агрегатов хранит _1day по классу C. Поэтому окно выводит метку области CIDR вида 211.224.128.0/24, чтобы область была указана явно. Гранулярности 5min и 1hour используют отдельный IP как есть.

Прямые ссылки

/infra/traffic/ips?src_ip=203.0.113.10
/infra/traffic/ips?servers=glory,blue

Опрос

Страница опрашивает /infra/traffic/ips/live каждые 30 секунд для автоматического обновления (это не Reverb — сборщик пишет в БД вне Laravel, поэтому опрос здесь разумный выбор). При обновлении, если были выбраны все серверы, новые появившиеся серверы включаются автоматически, а исчезнувшие убираются из выбора.

Источники данных

Привязка окна

Окно отображения привязано к последнему снимку данных (MAX(snapshot_ts)), а не к now() приложения. Часы хранения у сборщика могут отставать от часов приложения примерно на 9 часов, поэтому окно, построенное от now(), попало бы за пределы данных и отрисовалось бы пустым.

Запрос хостового представления (ipPeers)

-- TrafficRepository::ipPeers (с привязкой параметров)
SELECT server_name, remote_ip, local_port, SUM(session_count) AS total_sessions
  FROM traffic_session_ct
 WHERE snapshot_ts BETWEEN :min AND :max
   AND local_port IN (:ports)          -- OpsPolicy::monitoredPorts()
 GROUP BY server_name, remote_ip, local_port;

monitored ports не зашиты в код — они берутся из infra_monitored_ports (CSV) в разделе Операционная политика. Результат ipsData() кэшируется на 20 секунд (ключ infr:traffic:ips:v1:{timer}:{ports}).

Запросы окна расследования

Метод Таблица Что делает
ipSeenSpan() traffic_session_ct MIN/MAX(created_at) = реальный интервал наблюдений (срок хранения около 8 ч), MAX(snapshot_ts) = собственная последняя партия этого IP (точка привязки разбивки)
ipBreakdown() traffic_session_ct Суммы сессий по серверу×порту×состоянию · удалённые порты · первое/последнее (LIMIT 200)
ipHistory() 3 агрегата История сессий по гранулярности (LIMIT 400)
ipEnrichment() ip_info_loop Страна · город · ASN · провайдер (при отсутствии данных мягко возвращает null)

Разбивка соединений привязана к собственной последней партии снимка этого IP, а не к глобальному последнему окну. Так сделано намеренно: IP, который сейчас не подключён, но обращался к нам в прошлом, всё равно покажет своё распределение, восстановленное по последнему моменту наблюдения.

Оговорка об индексах агрегатов (критично для производительности)

ipHistory() всегда явно указывает direction IN ('inbound','outbound').

-- _1day использует составной индекс t_ip(direction, remote_ip).
-- Без явного direction сканируется только диапазон created_at → более 12 с.
-- С ним индекс задействуется → около 20 мс (замер 2026-08-06).
SELECT created_at, SUM(session_count) AS sessions
  FROM traffic_session_ct_1day
 WHERE direction IN ('inbound','outbound')
   AND remote_ip = :cclass_key           -- суточный уровень использует ключ /24 из первых 3 октетов
   AND created_at >= :since
 GROUP BY created_at
 ORDER BY created_at
 LIMIT 400;

Агрегаты огромны (_5min ≈ 209M · _1hour ≈ 112M · _1day ≈ 24M), поэтому узкое окно created_at >= вместе с LIMIT обязательны. Результаты окна защищены кэшами: investigate — 25 с, sources — 20 с.

Доступ

Устранение неполадок и частые вопросы

Карточки пустые, показывается только «в этом окне нет узлов». Это значит, что в последнем снимке нет соединений на наблюдаемых портах. (1) Расширьте таймер до 5 или 60, (2) убедитесь, что реальные сервисные порты зарегистрированы в infra_monitored_ports раздела Операционная политика, и (3) проверьте, что свежие снимки попадают в traffic_session_ct (сборщик check_ct.js).

Всё пусто, и нет метки времени снимка. Вероятно, проблема в подключении legacy_glory или сама таблица traffic_session_ct пуста. Проверьте учётные данные БД legacy_glory в .env и работу сборщика трафика. При сбое запроса в ответе передаётся error:true.

Только суточная история показывает «нет суточной истории агрегатов для этого блока /24». Суточная агрегация может отставать на сутки и индексируется по блоку /24. Сначала проверьте гранулярности 5min и часовую. Если для блока агрегата ещё нет, это ожидаемо.

Я щёлкнул по IP, но разбивка соединений пуста. У этого IP нет сессий в свежем снимке, но есть прошлые наблюдения. Используйте первое/последнее наблюдение в сводных KPI и историю соединений, чтобы подтвердить прошлую активность (разбивка восстанавливается по последней партии снимка этого IP).

Кнопка «Репутация ↗» открывает новую вкладку вместо показа внутри окна. Так и задумано. Это всплывающее окно трафика использует внешнюю ссылку на AbuseIPDB. Чтобы увидеть шкалу доверия и историю жалоб внутри консоли, воспользуйтесь встроенным окном репутации на экранах раздела «Безопасность».

Чем определяются цвета точек интенсивности? Диапазоном числа сессий по порту — 1–9 зелёный · 10–49 янтарный · 50+ красный · 0 даёт бледную точку. Столбцами выводятся только первые 8 наблюдаемых портов.

Связанные разделы

IP 연결 — 서버별 원격 peer
IP 연결 — 서버별 원격 peer