Reverse-engineering UniFi inform protocol for multi-tenant routing

UniFi inform protocol structure
Every UniFi device (access points, switches, gateways) phones home to its controller via HTTP POST to port 8080 every 10 seconds. This handles device stats, config sync, firmware versions, and client counts. While the payload is AES-128-CBC encrypted, the header contains plaintext device identification.
Packet header details
The first 40 bytes of every inform packet are unencrypted:
Offset Size Field ────── ───── ────────────────────────── 0 4B Magic: "TNBU" (0x544E4255) 4 4B Packet version (currently 0) 8 6B Device MAC address 14 2B Flags (encrypted, compressed, etc.) 16 2B AES IV length 18 16B AES IV 34 4B Data version 38 4B Payload length 42+ var Encrypted payload (AES-128-CBC)
The MAC address at byte offset 8 is completely unencrypted. "TNBU" is "UBNT" backwards (Ubiquiti's ticker symbol and default SSH credentials).
MAC extraction and routing
Extracting the MAC requires minimal code:
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])With the MAC in hand, routing becomes simple: maintain a table mapping MAC addresses to tenants, then forward the entire packet (header and encrypted payload untouched) to the correct backend. The proxy can be implemented in about 200 lines of Go with an in-memory MAC-to-tenant lookup table.
Controller port overview
Other controller ports include:
- 8443 TCP/HTTPS: Web UI and API
- 3478 UDP: STUN
- 6789 TCP: Speed test (internal)
- 27117 TCP: MongoDB (internal)
- 10001 UDP: L2 discovery (local only)
The MAC-based routing primarily serves as a fallback for edge cases like devices that haven't been reconfigured yet or factory-reset devices re-adopting. Once adopted, devices can be pointed at tenant-specific subdomains using standard Host header routing.
📖 Read the full source: HN AI Agents
👀 See Also

Jork Agentic Framework Built with Claude Ranks Top 10 in $4M Hackathon
A developer built an agentic framework called Jork using Claude and GLM models that ranked Top 10 among 2000+ applications in a $4 million hackathon. The framework autonomously developed tools including a Solana launchpad radar and a working word search game.

SkillsGate: Open Source Marketplace for AI Coding Agent Skills
SkillsGate is an open source marketplace that indexes 45,000+ skills for AI coding agents like Claude Code, Cursor, and Windsurf. It provides semantic search with vector embeddings and one-command installation via npx.

cc-session-utils: TUI Dashboard for Managing Claude Code Sessions and Costs
A developer built cc-session-utils, a terminal UI tool for managing Claude Code session files, tracking costs by model, cleaning orphaned sessions, and migrating data between projects. It requires Python 3.11+ and is built with Textual.

VTCode: A Rust TUI Coding Agent That Aggressively Trims Context with AST-Level Chunking
VTCode is an open-source Rust TUI coding agent that aggressively trims context using AST-level chunking via ripgrep and ast-grep. It supports custom OpenAI-compatible providers, sandboxing with macOS Seatbelt and Linux Landlock, and tree-sitter-bash validation on generated commands.