Project Goals and Use Cases
Relevant source files
The following files were used as context for generating this wiki page:The Overlord Network Kill Switch project is designed to simplify network administration tasks for non-technical users within a smart home environment, specifically those using Apple's HomeKit. The primary goal is to provide a one-touch method for blocking or allowing network access on a per-device or per-service basis, abstracting away the complexity of managing Pi-hole and Ubiquiti network controllers directly.
This is achieved through a lightweight Python FastAPI webserver that exposes a simple API. This API is then integrated into a home automation system using Node-RED and MQTT, allowing actions to be triggered by HomeKit switches. The project aims to make powerful network filtering capabilities accessible for common household scenarios.
Sources: README.md:4-8, AGENTS.md:5-7
Primary Use Cases
The system is built to address two main scenarios:
- Parental Controls: Parents can temporarily disable internet access for their children's devices with a single tap in the Home app.
- Focus Time: Users can block distracting websites (e.g., streaming services) while they are working to improve productivity.
Sources: README.md:10-13
System Architecture
The project follows a layered architecture that connects a user's HomeKit interface to the backend network services (Pi-hole and Ubiquiti).
This diagram illustrates the flow of commands and status updates through the system.
Sources: README.md:104-126, AGENTS.md:9-11
The key components are:
- HomeKit: The user-facing application on iOS devices.
- Homebridge with
homebridge-mqttthing: Creates virtual switches in HomeKit that communicate over the MQTT protocol. - MQTT Broker: A central message bus for communication between Homebridge, Node-RED, and the FastAPI server.
- Node-RED: An orchestration layer that subscribes to MQTT topics, parses the messages, and translates them into HTTP requests to the FastAPI server.
- FastAPI Server: The core of the project. It receives requests and executes commands against the Pi-hole and Ubiquiti APIs.
- Pi-hole / Ubiquiti: The target network services that perform the actual domain blocking and firewall rule enforcement.
Sources: README.md:15-20, AGENTS.md:9-11
Core Features
The application's features are divided into two main control modules: Pi-hole management and Ubiquiti network management. These can be enabled or disabled independently via the config.ini file.
Sources: cgi-bin/controller.py:46-51
Pi-hole Management
This feature allows for dynamic control over DNS filtering across one or more Pi-hole instances. It leverages the pihole6api library for compatibility with Pi-hole v6.
Sources: README.md:25, etc/webserver_requirements.txt:19
Domain-Level Blocking
Users can enable or disable predefined groups of domains. These groups are configured in the [block_domains] and [allow_domains] sections of the config.ini file. When a request is received, the PiHoleOverlord class iterates through the specified domains and enables or disables the corresponding regex-based filter rules on all configured Pi-hole instances.
Sources: lib/pihole/pihole.py:113-145, cgi-bin/controller.py:52-57
Global DNS Control
The MasterEnabler class provides functionality to enable or disable all DNS blocking across all Pi-holes simultaneously. It supports an optional timer to automatically re-enable blocking after a set period, which is useful for temporarily allowing access.
Sources: lib/pihole/alldns.py:79-90, AGENTS.md:41-43
Pi-hole API Endpoints
| Method | Endpoint | Description | Handler Class |
|---|---|---|---|
GET | /pihole/status/{domain_block} | Check if a domain block group is enabled. | PiHoleOverlord |
POST | /pihole/enable/{domain_block} | Enable a domain block group. | PiHoleOverlord |
POST | /pihole/disable/{domain_block} | Disable a domain block group. | PiHoleOverlord |
GET | /alldns/ | Get the global DNS blocking status. | MasterEnabler |
POST | /alldns/?timer=<seconds> | Disable global DNS blocking (with optional timer). | MasterEnabler |
DELETE | /alldns/ | Enable global DNS blocking. | MasterEnabler |
Sources: AGENTS.md:37-47, lib/pihole/pihole_router.py:43-78
Ubiquiti Network Management
This module provides control over a Ubiquiti UniFi Network Controller, allowing for management of firewall rules and client device access. It uses a direct API key for authentication.
Sources: lib/ubiquity/ubiquity.py:79-82, lib/ubiquity/ubiquity.py:190-193
Firewall Rule Control
The system can enable or disable specific firewall rules by name. The rule names are defined in the [ubiquiti_rules] section of config.ini. The UbiquitiOverlord class fetches all firewall rules, caches them, and sends a PUT request to update the enabled state of a target rule.
Sources: lib/ubiquity/ubiquity.py:355-408, cgi-bin/controller.py:84-88
Client Device Control
The system can block or unblock network access for groups of devices. Device MAC addresses are grouped under target names in the [ubiquiti_targets] section of config.ini. The UbiquitiOverlord class sends a POST request to the UniFi controller's stamgr endpoint to block or unblock the specified MAC addresses.
Sources: lib/ubiquity/ubiquity.py:410-467, cgi-bin/controller.py:79-83
Ubiquiti API Endpoints
| Method | Endpoint | Description | Handler Class |
|---|---|---|---|
GET | /ubiquiti/status_rule/{target} | Get the status (enabled/disabled) of a firewall rule. | UbiquitiOverlord |
GET | /ubiquiti/enable_rule/{target} | Enable a firewall rule. | UbiquitiOverlord |
GET | /ubiquiti/disable_rule/{target} | Disable a firewall rule. | UbiquitiOverlord |
GET | /ubiquiti/status_device/{target} | Get the block status of a device group. | UbiquitiOverlord |
GET | /ubiquiti/enable_device/{target} | Unblock a device group. | UbiquitiOverlord |
GET | /ubiquiti/disable_device/{target} | Block a device group. | UbiquitiOverlord |
GET | /ubiquiti/refresh | Force a refresh of the cached firewall rules. | UbiquitiOverlord |
Sources: AGENTS.md:49-55, lib/ubiquity/ubiquity.py:500-530
Integration and Orchestration Flow
The integration between HomeKit and the backend API is a key aspect of the project's goal to simplify user interaction.
The following diagram shows the sequence of events when a user toggles a switch in HomeKit.
Sources: README.md:52-62, node_red_flows/dns.json
Node-RED Orchestration
Node-RED acts as the glue code. It subscribes to MQTT topics published by homebridge-mqttthing, parses the topic to determine the target and action, and constructs the appropriate API call to the FastAPI server.
For example, an incoming MQTT message on the topic cmnd/dns_controller/media/hbomax/change with a payload of true is processed by a function node.
// Snippet from a function node in Node-RED
let webserver = flow.get('endpoint');
// ...
msg.topic = `stat/dns_controller/media/${msg.target}/status`
msg.url = `${webserver}/pihole/${msg.verb}/${msg.target}`
if (msg.verb == "change")
{
msg.method = "POST"
if (msg.payload == "true") msg.verb = "enable"
if (msg.payload == "false") msg.verb = "disable"
msg.url = `${webserver}/pihole/${msg.verb}/${msg.target}`
}
return msg;
This logic dynamically builds the URL and method for the HTTP request node, which then calls the FastAPI server.
Sources: node_red_flows/dns.json:79-102
Key Software Components
The server-side logic is encapsulated in several Pydantic-based classes that handle the interactions with the target APIs.
This diagram shows the inheritance structure of the main handler classes.
*BaseHTTPHandler**: A base class that manages session connections to multiple Pi-hole instances, including login and shutdown logic. Sources: lib/pihole/base.py.
PiHoleOverlord: Inherits fromBaseHTTPHandlerand implements the logic for enabling/disabling specific domain block groups. Sources: lib/pihole/pihole.py.MasterEnabler: Inherits fromBaseHTTPHandlerand manages the global enable/disable state of all connected Pi-holes. Sources: lib/pihole/alldns.py.UbiquitiOverlord: A standalone class that handles all communication with the Ubiquiti UniFi controller, including session management, firewall rule parsing, and device blocking commands. Sources: lib/ubiquity/ubiquity.py.