Обратная разработка протокола UniFi inform для маршрутизации в мультитенантной среде

Структура протокола UniFi inform
Каждое устройство UniFi (точки доступа, коммутаторы, шлюзы) связывается со своим контроллером через HTTP POST на порт 8080 каждые 10 секунд. Это передаёт статистику устройств, синхронизацию конфигураций, версии прошивок и количество клиентов. Хотя полезная нагрузка зашифрована с помощью AES-128-CBC, заголовок содержит идентификацию устройства в открытом виде.
Детали заголовка пакета
Первые 40 байт каждого пакета inform не зашифрованы:
Смещение Размер Поле ────── ───── ────────────────────────── 0 4Б Магия: "TNBU" (0x544E4255) 4 4Б Версия пакета (в настоящее время 0) 8 6Б MAC-адрес устройства 14 2Б Флаги (зашифровано, сжато и т.д.) 16 2Б Длина AES IV 18 16Б AES IV 34 4Б Версия данных 38 4Б Длина полезной нагрузки 42+ var Зашифрованная полезная нагрузка (AES-128-CBC)
MAC-адрес по смещению 8 байт полностью не зашифрован. "TNBU" — это "UBNT" наоборот (биржевой символ Ubiquiti и учетные данные SSH по умолчанию).
Извлечение MAC и маршрутизация
Извлечение MAC требует минимального кода:
header := make([]byte, 40)
if _, err := io.ReadFull(conn, header); err != nil {
return err
}
if string(header[0:4]) != "TNBU" {
return fmt.Errorf("not an inform packet")
}
mac := fmt.Sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
header[8], header[9], header[10],
header[11], header[12], header[13])Получив MAC-адрес, маршрутизация становится простой: поддерживайте таблицу, сопоставляющую MAC-адреса с арендаторами, а затем пересылайте весь пакет (заголовок и зашифрованную полезную нагрузку без изменений) на нужный бэкенд. Прокси можно реализовать примерно в 200 строках Go с таблицей поиска MAC-адресов в памяти.
Обзор портов контроллера
Другие порты контроллера включают:
- 8443 TCP/HTTPS: Веб-интерфейс и API
- 3478 UDP: STUN
- 6789 TCP: Тест скорости (внутренний)
- 27117 TCP: MongoDB (внутренний)
- 10001 UDP: Обнаружение L2 (только локально)
Маршрутизация на основе MAC-адресов в основном служит запасным вариантом для крайних случаев, таких как устройства, которые ещё не были перенастроены, или сброшенные до заводских настроек устройства, которые снова подключаются. После подключения устройства можно направить на субдомены конкретных арендаторов с использованием стандартной маршрутизации по заголовку Host.
📖 Read the full source: HN AI Agents
👀 Смотрите также

Внедрение проверок ИИ с продолжением для проверок PR под контролем версий
Continue интегрирует проверки ИИ непосредственно в рабочий процесс запросов на слияние, используя markdown файлы в качестве проверок с управлением версиями, которые видны через статусные проверки GitHub.

SprintiQ: планирование спринтов с открытым исходным кодом для Claude Code
SprintiQ — это платформа с открытым исходным кодом для гибкой разработки, которая выступает в роли оркестрационного слоя для Claude Code, предлагая генерацию пользовательских историй на базе ИИ, планирование спринтов, отслеживание скорости и CLI, синхронизирующий активность git со спринтами в реальном времени.

CC-Ledger: Отслеживайте затраты Claude Code за сессию и PR с помощью локального SQLite
CC-Ledger — это Rust-бинарник, который подключается к Claude Code и записывает каждый запрос в локальную SQLite. Отслеживайте неконтролируемые сессии в реальном времени и получайте разбивку затрат на PR без необходимости в API-ключе. Включает строку меню macOS, веб-панель и CLI.

Claude Code v2.1.166: Резервные модели, правила глобального запрета, межсессионная защита
Claude Code v2.1.166 представляет до 3 резервных моделей, поддержку glob-шаблонов в правилах запрета, усиленную межсессионную передачу сообщений, а также исправления мерцания терминала, зависших процессов и многое другое.