Intro
These are the mad writings of an lone engineer and not official documentation.
Here be dragons.
What is this?
This book documents what I've observed and learned about UniFi and how the SDN works. This book is based on and is a continuation of previous works of others. There is no set reading order for this book.
💡 Tip: You can search through this book by clicking on the 🔍 icon at the top of the page, or by pressing the
s
key.
Who is this for?
This book is for anyone who is interested in how UniFi's SDN devices work. You should be familiar with networking and some knowledge of data encryption and compression.
Contributing
This book is open source! Find a typo? Was something overlooked? Send a pull request!
License
This book is released under the Apache License 2.0
Protocols
This section documents what I've learned about how the UniFi protocols are structured.
Discovery Protocol
A factory reset UniFi device will send discovery packets as multicast to 233.89.188.1
.
The packets are based on Type-Length-Value (TLV).
The value is a list of TLVs.
Packet Structure
Offset | Size | Name |
---|---|---|
0 | u8 | Packet version |
1 | u8 | Type |
2-3 | u16 | Length |
4 | [u8] | Value |
There are currently two (maybe three?) packet versions. At the moment this document is only covering version 2.
Packet Value Types
Type | Name | Content |
---|---|---|
0x01 | HardwareAddress | [u8; 6] |
0x02 | IpInfo | HardwareAddress([u8; 6]), IPv4([u8; 4]) |
0x03 | FirmwareVersion | String |
0x04 | Unknown | Unknown |
0x05 | Unknown | Unknown |
0x06 | Username | String |
0x07 | Salt | [u8] |
0x08 | Challenge | [u8] |
0x09 | Unknown | Unknown |
0x0A | Uptime | i64 |
0x0B | Hostname | String |
0x0C | Platform | String |
0x0D | ESSID | String |
0x0E | WMode | i32 |
0x0F | Unknown | Unknown |
0x10 | Unknown | String |
0x11 | Unknown | Unknown |
0x12 | Sequence * | i32 |
0x13 | Serial ** | String |
0x14 | Unknown | Unknown |
0x15 | Model | String |
0x16 | MinimumControllerVersion | String |
0x17 | IsDefault | bool |
0x18 | Unknown | bool |
0x19 | Unknown | bool |
0x1A | Unknown | bool |
0x1B | Version | String |
0x1C | Unknown | i32 |
0x1D | Unknown | String |
* Sequence is an incrementing number
** Serial is usually the hardware address without any separators
Inform Protocol
UniFi devices communicate to their controller via HTTP POST as application/x-binary
containing it's current status every ~10 seconds to the inform URL
.
The inform URL
defaults to http://unifi:8080/inform
but may be set to the controller's IP address.
A controller will respond with either a no-op and an interval for the next inform or command for the device to execute.
A UniFi device will execute commands and send another inform packet.
Requests and responses share the same format encoded in big endian byte order.
When reading, inform packets are decrypted before decompression, inverse is true for writing.
There is currently only one payload version. Payload version 1 is JSON content and is the current version.
Encryption/Decryption
There are two possible ciphers used to encrypt the inform payload.
Although you can send the controller plain-text, it will not respond to non-encrypted payloads.
AES-CBC
is used, and is the default, if the 1st-bit
is set on the flag, or AES-GCM
if the 1st-bit
and 4th-bit
are set.
The Initialization Vector is 16 bytes in length and is sent in the header.
The default encryption authkey
is the MD5 hash of ubnt
(ba86f2bbe107c7c57eb5f2690775c712
).
When decrypting AES-GCM
the first 40 bytes of the packet is used as the additional authenticated data (AAD) and the last 16 bytes of the payload is the tag.
Compression/Decompression
There are two possible compression modes used at the moment.
The default method is ZLib and uses the 2nd-bit
of the flag.
Snappy is another possible compression method and uses the 3rd-bit
.
Packet Structure
Offset | Size | Name |
---|---|---|
0-3 | u32 | Magic Header (TNBU or 1414414933 ) |
4-7 | u32 | Packet Version |
8-13 | [u8; 6] | Hardware Address |
14-15 | u16 | Flags |
16-31 | [u8; 16] | Initialization Vector for encryption |
32-35 | u32 | Payload Version |
36-39 | u32 | Payload Length |
40-n | [u8] | Payload |
Flags
Value | Bits | Name |
---|---|---|
0x01 | 0b0000000000000001 | Encrypted |
0x02 | 0b0000000000000010 | ZLibCompressed |
0x04 | 0b0000000000000100 | SnappyCompressed |
0x08 | 0b0000000000001000 | EncryptedGCM |
Inform Protocol JSON Payload
# TODO: Write about the inform JSON payload content, there is a lot here...
Table of Contents
Command Payloads
There are six command types at the moment.
Name | Type |
---|---|
_type | String: Inform Command Type |
use_alert | bool |
device_id | String |
datetime | String |
time | u64 |
cmd | String |
mgmt_cfg | String |
system_cfg | String |
md5sum | String |
url | String |
version | String |
interval | u64 |
server_time_in_utc | String |
Inform Command Type
Type | Description |
---|---|
noop | Do nothing |
setparam | Update a config (mgmt_cfg / system_cfg) |
upgrade | Upgrade the device using the firmware file located at url |
reboot | Reboot the device |
cmd | Run a cmd |
setdefault | Factory reset the device |
Adoption
Official documentation for UniFi adoption methods
Layer 2 Adoption
UniFi adopts devices within the layer 2 network via an SSH remote command to assign the authkey
used for inform encryption.
The controller will send /usr/bin/syswrapper.sh set-adopt <inform_url> <authkey>
to the device using the default username and password of ubnt
:ubnt
.
Layer 3 Adoption
Layer 3 adoption works by having a new device reach out with an inform packet to a 'remote' controller over HTTP POST using the default authkey
.
The new device will show as Pending Adoption
in the UniFi controller UI until an operator adopts the device.
Adoption Process
On the first inform packet during adoption the controller will respond with a setparam
command that will set the device's unique authkey
as well as other config settings.
The second response will provision the device and contain the device's configuration.
Config
This section documents what I've learned about how the UniFi configuration is structured.
Management Config
# TODO: Write about the management configuration.
System Config
# TODO: Write about the system configuration.