Open-source project
Crosstalk-Solutions/unifi-toolkit avatar
Crosstalk-Solutions/unifi-toolkit

unifi-toolkit adds client tracking and lockdown to a UniFi console

A suite of tools for UniFi network management

724 stars74 forksPythonMIT

At a glance

What is it?
unifi-toolkit is a self-hosted Python dashboard that talks to a UniFi OS console and adds four things the console does not do: a device tracker with roaming history, an IDS/IPS event viewer, a zone-based lockdown tool, and a live network pulse. The trade is that it stores your controller credentials encrypted and only runs against UniFi OS hardware, since standalone controllers are unsupported.
Who is it for?
unifi-toolkit suits an operator of a UniFi OS console who wants a searchable history of where a specific device has been on the network, or who wants to lock a segment down without hand-writing firewall rules, and who is comfortable giving a tool on their LAN the controller credentials.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four tools that sit beside the UniFi console, not inside it

The problem is that a UniFi console shows you the network as it is right now, and a fair amount of what you actually want to know is about time. unifi-toolkit is a suite of tools for UniFi network management and monitoring, and it is structured as four separate surfaces rather than one dashboard. The Dashboard gives real-time system status: gateway info with model, firmware and uptime, CPU and RAM utilisation, network health across WAN, LAN, WLAN and VPN with diagnostic reasons, connected client counts split between wired and wireless, WAN status with IP, ISP, latency and uptime supporting three or more WANs dynamically, and a one-click copy of debug info for issue reporting. Network Pulse is a second monitoring view with Chart.js visualisations of clients by band, by SSID and top bandwidth, clickable AP cards, and WebSocket-powered live updates.

Wi-Fi Stalker answers where a device has actually been

The first of the four tools is a device tracker, and it is the one with a clear job. Wi-Fi Stalker tracks specific client devices through your UniFi infrastructure, by MAC address, for both wireless and wired clients. The features that make it more than a live view are the history and the analysis: roaming detection between access points, connection history with timestamps and CSV export, and tracking of signal strength, radio band across 2.4, 5 and 6 GHz, and SSID. The device analytics go further, with dwell time, favourite access point and a presence pattern heatmap, and you can block or unblock a device directly from the interface. Webhook alerts to Slack, Discord or n8n fire on connect, disconnect, roam, block and unblock, so the tracker can feed a chat channel rather than only a browser tab.

Threat Watch reads the gateway's own IDS events

The second tool is a view over security events that the gateway already generates. Threat Watch monitors IDS and IPS security events from your UniFi gateway, with real-time event monitoring that the README notes requires UniFi OS. On top of the stream it adds categorization and analysis, top attackers and top targets, ignore rules that filter noise by IP address and severity level, sortable event columns and advanced filtering, and the same webhook alert targets as the tracker, covering Slack, Discord and n8n. The ignore rules are the part that decides whether this is usable, because an IDS feed without a way to drop known-benign sources is just another page of noise, and the filtering is what makes the top-attacker view meaningful.

House Arrest locks a device or a network, and admits its limits

The third tool is the most interesting to read, because it is the one the README is careful about. House Arrest locks a device or a whole network down using UniFi's zone-based firewall, and the description says it is reversible in one click and honest about exactly what is and is not being blocked. The Networks tab gives an editable audit matrix of your VLANs showing firewall zone, network isolation, internet access, mDNS and DHCP DNS at a glance, with per-SSID Wi-Fi client isolation. DNS Lockdown forces chosen networks onto approved DNS resolvers and blocks everything else answering DNS, optionally with DNS-over-TLS too. Devices get per-device lockdown presets by MAC, either Full lockdown, Internet only or LAN only, with multi-device selection, and a blocked traffic view attributes what each lockdown stopped to its own rules by ID. The reassuring part is in the details: every change is previewed before applying, every rule carries a marker so release can only ever delete its own rules, and a lockdown that stops enforcing because the MAC changed or the rule was disabled in UniFi is flagged rather than shown green. It requires the zone-based firewall, UniFi Network 9.0 or newer on a UniFi OS console, and the full guide with measured limitations is in docs/HOUSE-ARREST.md.

Local or production, and the setup wizard writes the env file for you

There are two deployment shapes and the difference is significant. The local deployment is LAN only, with no authentication, accessed at http://localhost:8000. The production deployment is internet-facing, with authentication enabled and HTTPS through Let's Encrypt via Caddy, and the firewall has to be opened for 80 and 443. Both paths start the same way, and the setup wizard is the recommended route:

bash
git clone https://github.com/Crosstalk-Solutions/unifi-toolkit.git
cd unifi-toolkit
./setup.sh  # Select 1 for Local

# Start
docker compose up -d

running setup.sh generates an encryption key, configures the deployment mode as local or production, sets up authentication for production only, and creates your .env file. The manual alternative is to copy .env.example to .env and edit it yourself, where the one required setting is ENCRYPTION_KEY, which encrypts stored credentials and is auto-generated by the wizard, and the production-only settings are DEPLOYMENT_TYPE, DOMAIN, AUTH_USERNAME and a bcrypt AUTH_PASSWORD_HASH.

The controller credentials are the thing to think about

This tool needs the controller password or API key, so the security question is unavoidable. The compose file passes UNIFI_CONTROLLER_URL, UNIFI_USERNAME, UNIFI_PASSWORD, UNIFI_API_KEY, UNIFI_SITE_ID and a UNIFI_VERIFY_SSL flag that defaults to false, and the ENCRYPTION_KEY exists to encrypt the stored credentials at rest. The compose file also documents Docker Swarm secrets support, where sensitive values are supplied as _FILE environment variables rather than inline, with ENCRYPTION_KEY, AUTH_USERNAME and AUTH_PASSWORD_HASH named as the supported ones. The local mode having no authentication at all is the point to weigh: it is fine on a LAN, and it is a reason to keep the local profile on a LAN and use the production profile with Caddy and a domain for anything else.

A non-root container with a health check, and two release channels

The build is a two-stage Docker build on python:3.12-slim, and the build stage of the Dockerfile reads like this:

dockerfile
FROM python:3.12-slim AS builder

# Set working directory
WORKDIR /app

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Copy requirements
COPY requirements.txt .

# Install Python dependencies to a known prefix
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

with the dependencies installed into a prefix in the builder stage and copied into the runtime stage, which also installs curl for the health check. The container creates a non-root user with a specific uid, chowns the data directory to it, copies the application code with matching ownership, switches to that user, exposes port 8000, and declares a health check that curls the health endpoint on a 30 second interval with a 40 second start period. The compose file pulls the published image from GHCR by default with the local build commented out, and sets a restart policy of unless-stopped. The day to day commands are a fixed set:

text
| Start (local) | `docker compose up -d` |
| Start (production) | `docker compose --profile production up -d` |
| Stop | `docker compose down` |
| View logs | `docker compose logs -f` |
| Restart | `docker compose restart` |
| Reset password | `./reset_password.sh` |
| Update | `./upgrade.sh` |

Images are published to both GHCR and Docker Hub and are identical, with the latest tag as the release channel that only moves on tagged releases and the edge tag as the beta channel rebuilt on every merge.

Only UniFi OS controllers, and the versions move fast

The hard requirement is the controller type. The README lists a UniFi OS controller, meaning a UDM, a UCG or a Cloud Key Gen2 or newer, and states that standalone or self-hosted controllers are not supported as of v1.11.0. The rest of the stack is a FastAPI application with SQLAlchemy on SQLAlchemy async with aiosqlite by default, Alembic for migrations, APScheduler for the scheduled work, Jinja2 for templates and Pydantic with pydantic-settings for configuration. The requirements file pins minimum versions and explains at least one of them, with a floor on fastapi that is a security fix rather than a compatibility bound, because the older fastapi pin was unsatisfiable-as-intended and pulled a starlette release that broke the template response signature. The package requires Python 3.9 up to but not including 3.13, and the recent releases move quickly, v1.13.4 on 2026-10-15, v1.13.3 on 2026-10-14 and v1.13.2 on 2026-10-13, with the last push to the repository on 2026-10-21.

Editorial conclusion

unifi-toolkit suits an operator of a UniFi OS console who wants a searchable history of where a specific device has been on the network, or who wants to lock a segment down without hand-writing firewall rules, and who is comfortable giving a tool on their LAN the controller credentials. It does not suit a network on a standalone or self-hosted controller, since the README states those are unsupported as of v1.11.0, and it does not suit a site that cannot run a Docker container holding decrypted credentials. Before deploying, run the local setup rather than the production profile first, decide where the ENCRYPTION_KEY and the controller API key live, and note that the last push to the repository was on 2026-10-21 with release v1.13.4 dated 2026-10-15.

Frequently asked questions

Which UniFi controllers does unifi-toolkit support?

The requirements list a UniFi OS controller, that is a UDM, a UCG or a Cloud Key Gen2 or newer. The README states that standalone or self-hosted controllers are not supported as of v1.11.0, and the House Arrest lockdown feature additionally requires UniFi Network 9.0 or newer on a UniFi OS console.

How do I install unifi-toolkit?

Clone the repository, run `./setup.sh` and pick 1 for Local or 2 for Production, then start with `docker compose up -d`. The wizard generates the encryption key, configures the deployment mode, sets up authentication for production, and writes your .env file.

What does the Wi-Fi Stalker track?

It tracks specific client devices by MAC address across wireless and wired clients, and records roaming between access points, connection history with timestamps and CSV export, signal strength, radio band and SSID. It also computes dwell time, favourite access point and a presence pattern heatmap, and can block or unblock devices and fire webhooks to Slack, Discord or n8n.

What is House Arrest in unifi-toolkit?

It locks a device or whole network down using UniFi's zone-based firewall. It offers per-VLAN audit of firewall zone, isolation, internet access, mDNS and DHCP DNS, DNS lockdown onto approved resolvers, per-device presets by MAC, and a blocked traffic view. Every change is previewed before applying, and a lockdown that stops enforcing is flagged rather than shown green.

How are the controller credentials stored?

The compose file passes UNIFI_CONTROLLER_URL, UNIFI_USERNAME, UNIFI_PASSWORD and UNIFI_API_KEY to the container, and the ENCRYPTION_KEY setting encrypts stored credentials. The compose file also documents Docker Swarm secrets support through _FILE environment variables for ENCRYPTION_KEY, AUTH_USERNAME and AUTH_PASSWORD_HASH.

Official sources

  1. Crosstalk-Solutions/unifi-toolkit on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/crosstalk-solutions-unifi-toolkit.svg)](https://hysenlabs.com/projects/crosstalk-solutions-unifi-toolkit)

Was this useful?