Getting Started Guide
Relevant source files
The following files were used as context for generating this wiki page:This guide provides instructions on how to set up, configure, and use the Overlord Network Kill Switch. The project provides a web server that allows one-touch blocking of specific domains on a per-device basis via HomeKit switches, or entire network ranges via Ubiquiti firewall rules. It is designed to simplify network control for non-technical users, enabling features like parental controls or personal focus time.
The system integrates with HomeKit via Homebridge and MQTT, using Node-RED for orchestration. The core logic is a FastAPI application that communicates with Pi-hole and Ubiquiti Network Controller APIs to enforce network policies.
Sources: README.md:4-12, AGENTS.md:3-6
Architecture
The system operates by translating user actions in the HomeKit app into API calls to Pi-hole and Ubiquiti services. An MQTT broker acts as the central messaging system, with Node-RED processing messages and forwarding them to the Gunicorn/Flask web server.
Sources: README.md:103-125, AGENTS.md:8-10
The following diagram illustrates the data flow from a user's action to the target service.
Sources: README.md:104-125
System Requirements
To use this project, the following components are required:
- Homebridge: MQTT Thing
- Node-RED
- Gunicorn / Flask (FastAPI)
- Pi-hole (v6 supported)
- Ubiquiti Network Controller (Tested on 9.4.19)
Sources: README.md:14-25
Container Quickstart
The application is designed to run in a container. You can use the provided podman run command to start the service. An environment file is used to pass necessary credentials and connection details to the container.
Sources: README.md:37-46
Environment Variables
Create an envfile with the following variables. These can also be provided directly to the container runtime.
| Variable | Description | Source |
|---|---|---|
DNS_SERVERS | Comma-separated list of DNS server IP addresses. | README.md:38 |
REMOTE_PI_PASSWORD | The admin password for your Pi-hole instance(s). | README.md:39 |
REMOTE_PI_LIST | A space-separated list of Pi-hole IP addresses. | README.md:40 |
MQTT_BROKER | The IP address of your MQTT broker. | README.md:41 |
MQTT_PORT | The port for your MQTT broker. | README.md:42 |
REMOTE_UBIQUITI_DEVICE | The IP address of your UniFi controller. | README.md:43 |
REMOTE_UBIQUITI_API_KEY | The API key for your UniFi controller. | README.md:44 |
Sources: README.md:37-45, AGENTS.md:96-103
Running the Container
Use the following command to run the container. You may need to mount a custom config.ini for advanced configuration.
# Add if needed -v ./etc/config.ini:/opt/webserver/etc/config.ini
podman run -d --replace --name=overlord-dns -p 19000:19000 --env-file=./etc/envfile ghcr.io/nickjlange/overlord-network-kill-switch:latest
The server will be accessible on port 19000.
Sources: README.md:48-50, cgi-bin/gunicorn_config.py:2
Configuration
Configuration is managed through a combination of environment variables and the config.ini file. The main application controller parses this file on startup to enable features and define targets.
Sources: cgi-bin/controller.py:65-163
config.ini File
The config.ini file is located in the etc/ directory and allows for detailed configuration of the Pi-hole and Ubiquiti integrations.
The following diagram shows the configuration loading process.
[general] Section
This section controls which major components of the application are active.
| Key | Description | Default |
|---|---|---|
pihole_control_enabled | Set to true to enable Pi-hole integration. | false |
ubiquiti_control_enabled | Set to true to enable Ubiquiti integration. | false |
mqtt_announce_enabled | Set to true to publish service status via MQTT Last Will and Testament (LWT). | false |
remote_pi_list | Space-separated list of Pi-hole IPs. Can be overridden by REMOTE_PI_LIST env var. | REMOTE_PI_LIST |
remote_pi_password | Pi-hole admin password. Can be overridden by REMOTE_PI_PASSWORD env var. | REMOTE_PI_PASSWORD |
Sources: cgi-bin/controller.py:75-90, cgi-bin/controller.py:98-108
[block_domains] & [allow_domains] Sections
These sections define groups of domains to be blocked or allowed by Pi-hole. Each key is a logical name (e.g., hbomax, school_work) that can be targeted by API calls. The values are newline-separated regex patterns.
[block_domains]
hbomax =
hbo.com
hbomax.com
school_work =
youtube.com
netflix.com
Sources: cgi-bin/controller.py:91-97
[ubiquiti] Section
Configures the connection to the Ubiquiti controller.
| Key | Description | Default |
|---|---|---|
remote_ubiquiti_device | UniFi controller IP/hostname. | REMOTE_UBIQUITI_DEVICE |
remote_ubiquiti_api_key | UniFi API key. | REMOTE_UBIQUITI_API_KEY |
Sources: cgi-bin/controller.py:112-118
[ubiquiti_targets] & [ubiquiti_rules] Sections
[ubiquiti_targets]: Defines groups of MAC addresses to be blocked or unblocked. Each key is a logical name.[ubiquiti_rules]: Defines firewall rules by name that can be enabled or disabled.
[ubiquiti_targets]
kids_devices =
AA:BB:CC:DD:EE:FF
11:22:33:44:55:66
[ubiquiti_rules]
streaming_block_rule =
Block Streaming Services
Sources: cgi-bin/controller.py:119-130
[mqtt] Section
Configures the MQTT broker connection for status announcements.
| Key | Description | Default |
|---|---|---|
broker | MQTT broker IP/hostname. | MQTT_BROKER or localhost |
port | MQTT broker port. | MQTT_PORT or 1883 |
lwt_topics | Newline-separated list of topics to publish a "true" or "false" status message on startup and shutdown. | [] |
Sources: cgi-bin/controller.py:131-152
Integrations
Node-RED
Node-RED is used to translate MQTT messages from Homebridge into HTTP requests to the FastAPI server. An example flow is provided in node_red_flows/dns.json. The flow listens on cmnd/# topics, parses the target and command, and makes the corresponding API call. It then publishes the result back to a stat/# topic.
The flow logic can be summarized as follows:
- MQTT In: Subscribes to command topics (e.g.,
cmnd/dns_controller/media/hbomax/change). - Parse Message: A function node extracts the target (e.g.,
hbomax) and the desired state (true/false) from the topic and payload. - Construct URL: The function node builds the appropriate API endpoint URL (e.g.,
http://<server>:19000/pihole/enable/hbomax). - HTTP Request: Sends the request to the FastAPI server.
- Process Response: A change node extracts the
statusfrom the JSON response. - MQTT Out: Publishes the new status to the corresponding status topic (e.g.,
stat/dns_controller/media/hbomax/status).
Sources: node_red_flows/dns.json, README.md:52-53
Homebridge MQTT-Thing
To integrate with HomeKit, you need to configure the homebridge-mqttthing plugin. This creates switches in the Home app that publish to the MQTT topics Node-RED is listening on.
Here is an example configuration for a switch to control the hbomax domain block:
{
"type": "switch",
"name": "HBO",
"debounceRecvms": 100,
"topics": {
"getOnline": "stat/dns_controller/master/service_status",
"getOn": "stat/dns_controller/media/hbomax/status",
"setOn": "cmnd/dns_controller/media/hbomax/change"
},
"accessory": "mqttthing"
}
getOn: Subscribes to the status topic published by Node-RED.setOn: Publishes the new state to the command topic that Node-RED receives.
Sources: README.md:57-72
API Endpoints
The FastAPI application exposes endpoints to control Pi-hole and Ubiquiti devices.
Sources: AGENTS.md:38-63, lib/pihole/pihole_router.py, lib/ubiquity/ubiquity.py
Pi-hole Control (/pihole)
Manages domain-level blocking.
Sources: lib/pihole/pihole_router.py:40-58, [AGENTS.md:41-44]
| Method | Path | Description |
|---|---|---|
GET | /pihole/status/{domain_block} | Checks if a named domain block is enabled. |
POST | /pihole/enable/{domain_block} | Enables a named domain block. |
POST | /pihole/disable/{domain_block} | Disables a named domain block. |
Global DNS Control (/alldns)
Manages the global DNS blocking status for all configured Pi-hole instances.
Sources: lib/pihole/pihole_router.py:61-79, [AGENTS.md:46-49]
| Method | Path | Description |
|---|---|---|
GET | /alldns/ | Gets the current global DNS blocking status. |
POST | /alldns/ | Disables DNS blocking. Accepts an optional timer query parameter for temporary disabling. |
DELETE | /alldns/ | Enables DNS blocking. |
Ubiquiti Control (/ubiquiti)
Manages firewall rules and device connectivity on a Ubiquiti controller.
Sources: lib/ubiquity/ubiquity.py:532-569, [AGENTS.md:51-63]
| Method | Path | Description |
|---|---|---|
GET | /ubiquiti/status_rule/{target} | Gets the status (enabled/disabled) of a named firewall rule. |
GET | /ubiquiti/enable_rule/{target} | Enables a named firewall rule. |
GET | /ubiquiti/disable_rule/{target} | Disables a named firewall rule. |
GET | /ubiquiti/status_device/{target} | Gets the status (online/offline) of a named device group. |
GET | /ubiquiti/enable_device/{target} | Unblocks a named device group (sets state to online). |
GET | /ubiquiti/disable_device/{target} | Blocks a named device group (sets state to offline). |
GET | /ubiquiti/refresh | Forces a refresh of the cached firewall rules from the controller. |