Slyber Turn Server включает мощную встроенную систему телеметрии, которая отслеживает активные сессии в реальном времени, ведет 24 часовую почасовую статистику, выявляет атакующие IP адреса и сохраняет данные на диск.
Доступ к служебным эндпоинтам (/metrics,/events,/api/node-stats): Эти маршруты закрыты от посторонних (isInternalOrAuthorized). Доступ к ним разрешен только если:
- Передан заголовок
X-Turn-Secret(илиAuthorization: Bearer); - ИЛИ запрос выполнен напрямую с локальной машины (
127.0.0.1/::1); - ИЛИ IP клиента явно входит в белый список
ALLOWED_IPS.
1. Проверка здоровья: GET /healthz
Публичный легковесный эндпоинт для мониторинга сервера:
curl http://127.0.0.1:8080/healthz
# Ответ (200 OK): {"status":"ok"}
2. Метрики: GET /metrics
Возвращает метрики в стандартном текстовом формате Prometheus (text/plain; version=0.0.4):
turn_auth_requests_total{status="success"}(counter) — общее количество уникальных успешных пользовательских подключений к TURN.turn_auth_requests_total{status="failed"}(counter) — общее количество отклоненных попыток авторизации (с учетом 10-секундной дедупликации повторов с одного IP).turn_active_allocations(gauge) — количество активных пользовательских TURN-сессий в данный момент.turn_relayed_bytes_total(counter) — суммарный объем медиа-трафика в байтах, переданный через TURN-релей.turn_ssrf_blocked_total(counter) — количество заблокированных попыток SSRF-атак на приватные и системные адреса.turn_udp_listeners_active(gauge) — количество активных серверных UDP-сокетов (TURN_THREADS).
3. Полная аналитика узла: GET /api/node-stats
Возвращает развернутый JSON слепок состояния сервера для построения дашбордов и панелей управления:
{
"status": "online",
"uptime_sec": 86400,
"active_sessions": 2,
"allocated_ports": 3,
"active_sessions_list": [
{
"id": 14,
"user_id": "user_777",
"client_ip": "198.51.100.10",
"relay_port": 49200,
"transport": "udp (+1 standby)",
"started_at": "2026-10-27T08:10:00Z",
"duration_sec": 345,
"relayed_bytes": 48250112
}
],
"port_pool_capacity": 16384,
"port_pool_used_percent": 0.0183,
"auth_success": 1250,
"auth_failed": 4,
"relayed_bytes": 10737418240,
"ssrf_blocked": 1,
"lan_skipped": 420,
"udp_listeners": 8,
"hourly_24h": [
{
"hour_unix": 1761552000,
"peak_active": 18,
"connections": 95,
"relayed_bytes": 524288000,
"auth_failed": 0,
"ssrf_blocked": 0
}
],
"top_offenders": [
{
"ip": "203.0.113.199",
"last_user_id": "attacker",
"auth_fails": 12,
"ssrf_blocks": 2,
"last_seen": "2026-10-27T08:05:12Z"
}
]
}
Особенности подсчета активных сессий и переключения сетей (Wi-Fi ↔ 4G):
- Таймаут неактивности (
maxSessionIdle = 30s): Если по выделенному сокету нет трафика более 30 секунд, он перестает отображаться в списке активных сессий. - Умная обработка смены сети (
supersededSocketIdle = 5s): Когда пользователь во время звонка выходит из дома и его телефон переключается с Wi-Fi на 4G, создается новая TURN аллокация, а старая замолкает. Сервер видит, что у того жеuser_idпоявился свежий активный сокет (с трафиком за последние 3 секунды), и скрывает старый брошенный сокет уже через 5 секунд тишины вместо 30. - Группировка сокетов (
+N standby): Если клиент открыл несколько параллельных аллокаций (например, для аудио и видео или резервный сокет), они группируются в одну карточку сессии с суммированием трафика и пометкойudp (+1 standby). - Рейтинг нарушителей (
top_offenders): Сортирует IP адреса по индексу угрозы по формуле:Score = AuthFails + (SSRFBlocks * 5)и возвращает топ-10 самых опасных IP.
4. Журнал событий: GET /events
Сервер ведет в памяти кольцевой буфер последних 2000 событий (SmartEvent). Если одно и то же событие (совпадают тип, user_id, client_ip и target_ip) повторяется в течение 30 секунд, сервер не плодит дубликаты, а увеличивает поле "count" у существующей записи и обновляет ее timestamp.
Параметры фильтрации GET /events:
type— фильтр по типу события:ALL(или пусто) — все события.ALERTS— только инциденты безопасности (AUTH_FAILиSSRF_BLOCK).CREDS_ISSUED— выдача учетных данных через HTTP API.AUTH_OK— успешное установление новой пользовательской TURN-сессии.SESSION_CLOSED— завершение сессии с итоговой сводкой (порт, длительность и объем переданного трафика в B/KB/MB).AUTH_FAIL— ошибка авторизации (неверный формат, истекший TTL, чужой Origin/IP, отсутствие секрета).SSRF_BLOCK— заблокированная попытка SSRF-атаки.user_id— поиск по подстрокеuser_id(без учета регистра).ip— поиск по подстроке вclient_ipилиtarget_ip.limit— максимальное количество возвращаемых записей (от самых свежих к старым).
Пример запроса:
curl "http://127.0.0.1:8080/events?type=ALERTS&limit=20"
5. Сохранение данных на диск
Чтобы статистика не терялась при перезапуске сервера или обновлении версии, NodeTelemetry каждые 10 секунд (только если были изменения - флаг dirty), а также в момент остановки сервера (SIGTERM/SIGINT) атомарно сохраняет данные в директорию DATA_DIR:
stats.json- общие счетчики, 24 часовые корзиныhourlyи база нарушителейoffenders.events.jsonl- журнал событий в формате JSON Lines.
Запись производится сначала во временный файл .tmp с правами 0600, а затем выполняется атомарный os.Rename, что исключает повреждение файлов при внезапном отключении питания.