Security Considerations
Relevant source files
The following files were used as context for generating this wiki page:This document outlines the security considerations for the Overlord Network Kill Switch application. The project's primary function is to provide a simplified interface for controlling network access via Pi-hole and Ubiquiti devices, intended for use within a trusted home network. The security model is therefore built around authenticating to these backend services and assumes the local network environment is secure.
The main security aspects involve how the application handles credentials for backend services, the security of the API it exposes, and the protocols used for communication. The application does not implement authentication on its own API endpoints, relying on network isolation to restrict access.
Authentication with Backend Services
The application authenticates with Pi-hole and Ubiquiti controllers to perform its functions. The methods and credentials used for each service are distinct.
Ubiquiti Controller Authentication
Authentication with the Ubiquiti Network Controller is performed using a long-lived API key. This is a more secure approach than the previously used username/password method, which is now deprecated in the code.
- Method: The API key is passed in the
X-API-KEYHTTP header with every request to the controller. - Configuration: The key is loaded from the
REMOTE_UBIQUITI_API_KEYenvironment variable or theremote_ubiquiti_api_keyfield inconfig.ini. - Implementation: The
UbiquitiOverlordclass inlib/ubiquity/ubiquity.pymanages the session and sets the header after loading the key. If the API key is not set, requests will fail with a 401 Unauthorized error.
Sources: lib/ubiquity/ubiquity.py:102, lib/ubiquity/ubiquity.py:207-209, cgi-bin/controller.py:113-119, AGENTS.md
The following diagram illustrates the authentication flow with the Ubiquiti controller.
Pi-hole Authentication
Authentication with Pi-hole instances is handled by the pihole6api library, which uses the Pi-hole web interface password.
- Method: The password is used to establish a session with each Pi-hole device.
- Configuration: The password is loaded from the
REMOTE_PI_PASSWORDenvironment variable or theremote_pi_passwordfield inconfig.ini. - Implementation: The
BaseHTTPHandlerclass initializes aPiHole6Clientfor each Pi-hole IP address listed in the configuration, passing the password to the client constructor. - Security Risk: Communication with Pi-hole occurs over unencrypted HTTP. This means the password and all subsequent API commands are transmitted in cleartext across the local network.
Sources: lib/pihole/base.py:22-30, lib/pihole/base.py:73-81, cgi-bin/controller.py:99-105
The diagram below shows the Pi-hole authentication sequence.
API Server Security
The FastAPI application exposes endpoints to control network services. Its security posture is minimal, relying on the assumption that it operates within a protected network.
Unauthenticated Endpoints
The API does not require any form of authentication from its clients (e.g., Node-RED, Homebridge). Any device that can reach the server on its listening port can execute commands.
- The
controller.pyfile, which defines the FastAPI app, includes no authentication middleware. - Router files like
lib/pihole/pihole_router.pycontain commented-out codedependencies=[Depends(get_token_header)], suggesting that authentication was considered but is not currently implemented. - The example Node-RED flow in
node_red_flows/dns.jsonshows direct HTTP calls to the API without any authentication headers or tokens.
Sources: cgi-bin/controller.py, lib/pihole/pihole_router.py:40, node_red_flows/dns.json
Network Exposure
The Gunicorn web server is configured to be accessible from any network interface.
- Configuration: The
binddirective ingunicorn_config.pyis set to0.0.0.0:19000. - Risk: This configuration is convenient but makes the application accessible from any network connected to the host. If the host machine has a public IP or is connected to an untrusted network, the unauthenticated API becomes a significant security risk. The deployment model assumes the host is firewalled and only accessible from the LAN.
Sources: cgi-bin/gunicorn_config.py:2, cgi-bin/wsgi.py:11
Secrets Management
Secrets such as passwords and API keys are managed through a combination of a configuration file and environment variables.
Configuration Loading
The init_config function in controller.py orchestrates the loading of all settings. It uses a fallback mechanism, prioritizing the config.ini file and then checking for environment variables. This is a standard pattern that supports both local development (with a file) and containerized deployments (with environment variables).
Sources: cgi-bin/controller.py:65-155, README.md, AGENTS.md
This flowchart shows the logic for loading a secret.
Key Secrets
The following table summarizes the critical secrets used by the application.
| Environment Variable | config.ini Key | Description | Source File |
|---|---|---|---|
REMOTE_PI_PASSWORD | remote_pi_password | The web admin password for all Pi-hole instances. | [cgi-bin/controller.py:102](https://github.com/NickJLange/overlord-network-kill-switch/blob/HEAD/cgi-bin/controller.py#L102) |
REMOTE_UBIQUITI_API_KEY | remote_ubiquiti_api_key | The API key for the Ubiquiti Network Controller. | [cgi-bin/controller.py:115](https://github.com/NickJLange/overlord-network-kill-switch/blob/HEAD/cgi-bin/controller.py#L115) |
MQTT_BROKER | broker | The IP address or hostname of the MQTT broker. | [cgi-bin/controller.py:137](https://github.com/NickJLange/overlord-network-kill-switch/blob/HEAD/cgi-bin/controller.py#L137) |
MQTT_PORT | port | The port for the MQTT broker. | [cgi-bin/controller.py:143](https://github.com/NickJLange/overlord-network-kill-switch/blob/HEAD/cgi-bin/controller.py#L143) |
Sources: README.md, AGENTS.md, cgi-bin/controller.py:89-155
Communication Security
The security of data in transit varies depending on the service being contacted.
- Ubiquiti (HTTPS): Communication with the Ubiquiti controller is encrypted using HTTPS. However, the global disabling of
InsecureRequestWarningincontroller.pysuggests that the application may be configured to work with self-signed certificates without proper validation, which could expose it to Man-in-the-Middle (MITM) attacks on a compromised network. - Pi-hole (HTTP): Communication with Pi-hole devices is unencrypted (HTTP). This exposes the Pi-hole password and all API interactions to anyone who can monitor traffic on the local network.
- MQTT (TCP): The connection to the MQTT broker is over plain TCP. The configuration does not specify any settings for TLS encryption or client authentication, meaning status messages are sent in cleartext.
Sources: lib/ubiquity/ubiquity.py:110, lib/pihole/base.py:75, cgi-bin/controller.py:25, cgi-bin/controller.py:171-180
Dependency Security
The project pins its Python dependencies to specific versions in etc/webserver_requirements.txt.
- Benefit: Pinning versions ensures reproducible builds and prevents breaking changes from upstream packages.
- Risk: This practice means that security vulnerabilities discovered in a pinned dependency will not be patched automatically. The project maintainers must actively monitor for vulnerabilities and update the
webserver_requirements.txtfile.
Sources: etc/webserver_requirements.txt