Core Feature: DNS Blocking via Pi-hole
Relevant source files
The following files were used as context for generating this wiki page:The DNS Blocking feature provides a simplified, API-driven interface for managing domain filtering across one or more Pi-hole v6 instances. It is a core component of the Overlord Network Kill Switch, designed to allow non-technical users to control network access through home automation systems like HomeKit. The functionality is exposed via a FastAPI web server, which can be triggered by systems like Node-RED listening to MQTT messages.
This system offers two primary modes of control: granular management of predefined domain groups (both blocklists and allowlists) and a global "master switch" to enable or disable all DNS filtering temporarily or permanently. It abstracts the underlying pihole6api library to provide a consistent state across multiple Pi-hole devices.
Sources: README.md, cgi-bin/controller.py:46-57, lib/pihole/pihole.py, lib/pihole/alldns.py
Architecture and Core Components
The Pi-hole integration is built around a set of classes that handle configuration, API session management, and the specific logic for domain and global DNS control. The main application initializes and routes requests to these components based on the configuration.
Sources: cgi-bin/controller.py:195-198, lib/pihole/pihole_router.py:31-38
Initialization Flow
On application startup, if pihole_control_enabled is true in the configuration, the main controller initializes the Pi-hole routers and their handler classes.
This diagram shows the initialization process for the Pi-hole feature during the application's lifespan setup.
Sources: cgi-bin/controller.py:83-89, cgi-bin/controller.py:195-198, lib/pihole/pihole_router.py:31-38
Class Structure
The functionality is implemented across three main classes, all inheriting from a Pydantic BaseModel.
This diagram illustrates the inheritance structure of the Pi-hole handler classes.
Sources: lib/pihole/base.py:11, lib/pihole/pihole.py:24, lib/pihole/alldns.py:25
BaseHTTPHandler
This is the base class for all Pi-hole interactions. It is responsible for:
- Reading Pi-hole connection details (
remote_pi_list,remote_pi_password) from the application configuration. - Managing connection sessions to multiple Pi-hole instances using the
pihole6api.PiHole6Client. - Handling the initial connection and login process via
first_connect(). - Providing a clean shutdown method to close all active sessions.
Sources: lib/pihole/base.py:11-80
PiHoleOverlord
This class manages granular control over domain lists. It handles enabling and disabling predefined groups of regex-based domain filters.
- It determines whether a domain group is a
deny(blacklist) orallow(whitelist) rule based on the configuration. - The
get()method checks if all domains within a specified group are present and enabled on the Pi-hole instances. - The
post()method adds (enable) or removes (disable) all domains in a group from the respective Pi-hole list.
Sources: lib/pihole/pihole.py:24-151
MasterEnabler
This class implements the global DNS blocking switch.
- The
flip_mode()method enables or disables DNS blocking across all configured Pi-hole instances. disable_dns_blocking()can accept an optional timer (in seconds) to automatically re-enable blocking after a period.- The
get()method checks the blocking status across all Pi-holes and returns a consolidated status. It returns "unknown" if the states are inconsistent across devices.
Sources: lib/pihole/alldns.py:25-111
Configuration
The Pi-hole feature is configured through the ../etc/config.ini file. The feature is only activated if pihole_control_enabled is set to True.
| Section | Key | Description | Example |
|---|---|---|---|
[general] | pihole_control_enabled | Enables or disables the entire Pi-hole feature. | True |
[general] | remote_pi_list | A space-separated list of Pi-hole IP addresses or hostnames. | 192.168.1.53 192.168.1.54 |
[general] | remote_pi_password | The admin password for all Pi-hole instances. | YourPiholePassword |
[block_domains] | {group_name} | A named group of regex domains to be managed as a blocklist. Each domain is on a new line. | hbomax = hbo.com\nhbogo.com |
[allow_domains] | {group_name} | A named group of regex domains to be managed as an allowlist. Each domain is on a new line. | school_work = google.com\nwikipedia.org |
Sources: cgi-bin/controller.py:83-110
API Endpoints
The feature exposes two sets of API endpoints, one for domain group management and one for global DNS control.
Domain Group Control (/pihole)
These endpoints are handled by the PiHoleOverlord class and are used to manage specific domain block/allow groups defined in the configuration.
| Method | Path | Description |
|---|---|---|
GET | /pihole/status/{domain_block} | Checks if the specified domain group is currently enabled. Returns {"status": "true"} or {"status": "false"}. |
POST | /pihole/enable/{domain_block} | Enables the specified domain group by adding its domains to the Pi-hole lists. |
POST | /pihole/disable/{domain_block} | Disables the specified domain group by removing its domains from the Pi-hole lists. |
Sources: lib/pihole/pihole_router.py:41-57, AGENTS.md:28-31
Global DNS Control (/alldns)
These endpoints are handled by the MasterEnabler class and control the overall DNS blocking status on all Pi-holes.
| Method | Path | Description |
|---|---|---|
GET | /alldns/ | Gets the current global blocking status. Returns {"status": "true"} if enabled, {"status": "false"} if disabled, or {"status": "unknown"} if states are inconsistent. |
POST | /alldns/ | Disables DNS blocking on all Pi-holes. An optional timer query parameter can be provided to re-enable blocking after N seconds. |
DELETE | /alldns/ | Enables DNS blocking on all Pi-holes. |
Sources: lib/pihole/pihole_router.py:67-81, AGENTS.md:33-37
Data Flows
Enabling a Domain Block
This sequence diagram shows the process of enabling a domain block group via the API.
Checking Global DNS Status
This sequence diagram shows how the global DNS blocking status is retrieved.
Summary
The DNS Blocking via Pi-hole feature provides a robust and centralized mechanism for controlling DNS filtering across multiple Pi-hole devices. By exposing a simple REST API, it decouples the core logic from the user-facing control system (like HomeKit), allowing for flexible integration into various home automation ecosystems. Its ability to manage both fine-grained domain lists and a global kill switch makes it a powerful tool for parental controls and network management.
Sources: README.md, cgi-bin/controller.py