Open source Omada controller written in Python.
The official TP-Link Omada controller is a Java server (~500MB) used for managing Omada products (Access Points, switches, routers). It also exists as dedicated hardware (OC200, OC300) with limitations.
OpenOmada is a lightweight Python alternative that implements the minimum required to manage Omada Access Points. It supports automatic AP adoption, basic statistics, device configuration, and firmware upgrades.
Ideal for small embedded devices with Python and SSL/TLS support.
- Automatic discovery and adoption of Omada Access Points
- Device configuration (SSID, PSK)
- Basic statistics and status monitoring
- Firmware upgrade support
- CLI for device management
- Can replace an existing Omada controller without re-adopting APs
- Python 3.11+
- Python packages (see
requirements.txt) - TLS certificates extracted from an official Omada controller (see below)
Install dependencies:
pip install -r requirements.txtOpenOmada requires the TLS certificates used by the official Omada controller to communicate with Access Points. These must be extracted from a running official controller using extract-tls-secrets.
- Install and run an official Omada controller (the Java-based server)
- Clone and build extract-tls-secrets:
git clone https://github.com/neykov/extract-tls-secrets.git cd extract-tls-secrets mvn package - Run the Omada controller with the extract-tls-secrets Java agent attached to extract the certificate and private key
- Place the extracted files in the OpenOmada directory as:
omada_cert.pem- the TLS certificateomada_private_key.pem- the TLS private key
Create a file named omada.config in the OpenOmada directory with the following JSON format:
{
"ap_config": {
"ssid": "MyWiFiNetwork",
"psk": "MyWiFiPassword",
"security_mode": "WPA_PERSONAL",
"psk_version": "WPA3_SAE",
"psk_cipher": "AES",
"pmf_mode": "CAPABLE"
},
"controllerId": "",
"username": "admin",
"password": "",
"api_listen": "0.0.0.0:8050",
"cli_port": "/tmp/omada.sock",
"certfile": "omada_cert.pem",
"keyfile": "omada_private_key.pem",
"device_db": "device_db.json"
}| Field | Description |
|---|---|
ap_config.ssid |
WiFi SSID to configure on adopted Access Points |
ap_config.psk |
WiFi pre-shared key (password) |
ap_config.security_mode |
Security mode: NONE, WPA_ENTERPRISE, WPA_PERSONAL, PPSK_WITHOUT_RADIUS, PPSK_WITH_RADIUS (default: WPA_PERSONAL) |
ap_config.psk_version |
WPA version: WPA, WPA2, WPA_WPA2, WPA3_SAE (default: WPA3_SAE) |
ap_config.psk_cipher |
Encryption cipher: AUTO, AES (default: AES). Must be AES when using WPA3 |
ap_config.pmf_mode |
Protected Management Frames: MANDATORY, CAPABLE, DISABLE (default: CAPABLE) |
controllerId |
Unique controller identifier. Leave empty to auto-generate, or copy from an existing Omada controller to take over its APs |
username |
Admin username for AP authentication |
password |
MD5-hashed admin password (see below) |
api_listen |
Address and port for the REST API (default: 0.0.0.0:8050) |
cli_port |
Unix socket path for CLI communication (default: /tmp/omada.sock) |
certfile |
Path to the TLS certificate file (default: omada_cert.pem) |
keyfile |
Path to the TLS private key file (default: omada_private_key.pem) |
device_db |
Path to the device database file (default: device_db.json) |
The password in the config file must be an MD5 hash. Use the CLI to generate it:
# Interactive (hidden input):
./omada_cli.py -p
# Or pass the password directly:
./omada_cli.py -p "mypassword"Copy the output into the "password" field of omada.config.
If username and password are omitted from the config, they default to admin/admin.
Adopted devices are stored in a separate device_db.json file, created and updated automatically by the server. This file does not need to be created manually.
To replace an existing official Omada controller without re-adopting your APs:
- Copy the
controllerIdfrom the existing controller intoomada.config - Set the same
usernameandpasswordas the existing controller - Set the same
ssidandpskinap_config - Stop the official controller and start OpenOmada
The APs will reconnect to OpenOmada automatically.
# Start with default config (omada.config in current directory)
./omada.py
# Specify a custom config file path
./omada.py -c /path/to/myconfig.config
# Disable the self-test on startup
./omada.py --no-self-test
# Enable debug logging
./omada.py --log-level debug| Option | Description |
|---|---|
-c, --config PATH |
Path to the configuration file (default: omada.config) |
--no-self-test |
Disable the self-test that runs on startup |
--log-level LEVEL |
Set logging verbosity: debug, info, warning, error, critical (default: warning) |
The server listens on the following ports:
| Port | Protocol | Purpose |
|---|---|---|
| 29810 | UDP | AP discovery |
| 29814 | TCP/TLS | AP adoption and management |
| 8050 | TCP/HTTP | REST API (configurable) |
/tmp/omada.sock |
Unix socket | CLI communication (configurable) |
The CLI communicates with a running OpenOmada server via Unix socket.
# List all connected devices
./omada_cli.py -l
# Upgrade firmware on a device (by MAC address)
./omada_cli.py -U 78:8C:B5:64:27:86
# Hash a password for the config file
./omada_cli.py -p
# Specify a different server socket
./omada_cli.py -H /path/to/socket -l
# Show version
./omada_cli.py -v| Option | Description |
|---|---|
-l, --list |
List connected devices and their status |
-U, --fw-upgrade MAC |
Start firmware upgrade for the device with the given MAC address |
-p, --hash-password [PASSWORD] |
Hash a password for the config file. Prompts for hidden input if no password is given |
-H, --host PATH |
Unix socket path or hostname (default: /tmp/omada.sock) |
-v, --verbose |
Enable verbose debug output |
-V, --version |
Display version and exit |
This project is licensed under the GNU Lesser General Public License v3.0. See LICENSE for details.