This repo contains a Golang implementation of the Ubiquiti Networks Inform protocol used by the Unifi access points and the mFi machine networking components. The primary purpose of this repository is to implement the core inform protocol for interoperability with Ubiquiti products. It is not recommended to use this protocol as the base for any new product development, it's rather Ubiquiti specific and not very secure in the bootstrap phase (uses well-known keys over plaintext channels).
This work is largely based on ubntmfi
This repo is a work in progress and semi-maintained, it is not yet considered stable. If you find it useful patches are welcome, just open a pull request.
This repository should work well with older mFi components and modern Unifi components as well. The author has tested with devices as new as the U6-Mesh devices.
If you need these then feel free to implement them. Pull requests are accepted.
- Support for writing AES GCM packets
- Support for writing zlib compressed packets
- Support for writing snappy compressed packets
The inform protocol works over HTTP or HTTPS in the case of modern
equipment, older equipment did not support HTTPS. The mcad
daemon
on the devices is responsible for speaking the inform protocol to the
controller.
A device will POST
an HTTP request to the controller with a
content-type of application/x-binary
which contains a payload encoded
in inform format. The server will respond with a payload that is inform
encoded.
Packets are binary and transmitted in big-endian format.
Size | Type | Purpose | Notes |
---|---|---|---|
4 bytes | int32 |
Protocol Magic Number | Must always be 1414414933 (UBNT ) |
4 bytes | int32 |
Packet Version | Currently this is 0 |
6 bytes | []byte |
Device MAC Address | Used for crypto-key lookup |
2 bytes | int16 |
Flags | See below |
16 bytes | []byte |
Encryption IV | |
4 bytes | int32 |
Data Version | Currently this is 1 |
4 bytes | int32 |
Encrypted Payload Length | |
n bytes | []byte |
Encrypted Payload | See below |
Flag | Name | Purpose |
---|---|---|
1 |
Encrypted | Indicates that the payload is encrypted |
2 |
Zlib Compressed | Indicates that payload is zlib compressed |
4 |
Snappy Compressed | Indicates that payload is snappy compressed |
8 |
GCM Encrypted | Indicates that packet is encrypted with AES GCM |
There are two encryption modes AES 128 CBC and AES 128 GCM. GCM is used
in newer devices and CBC in older devices. The same key is used for
either mode. It's stored as x_authkey
in the Unifi database and is
encoded as hex. The key must be decoded before decryption.
AES GCM requires authentication data to decrypt the packet. The authentication data is the following fields encoded in big-endian binary format.
- Protocol Magic Number
- Packet Version
- Device MAC Address
- Flags
- Encryption IV
- Data Version
- Data Length
In CBC mode the data is padded to fit a full AES block. In GCM mode the final block appears to be a padding/garbage block.
The payload is a JSON string that is device and application specific. The payload may also (but is not required to be) be compressed using either snappy or zlib compression as indicated by the flags.