Files
NetAlertX/docs/PIHOLE_GUIDE.md
T
Mauricio Camayo e543f14d08 fix: address round 2 of jokob-sk's maintainer review
References PR #1765.

Docs:
- Added PIHOLEMON to docs/PLUGINS.md and a new "Approach 4" section in
  docs/PIHOLE_GUIDE.md, leading with anomaly detection (the actual
  differentiator vs PIHOLEAPI) and explaining when to pick each plugin.
- README/PLUGINS.md/config.json's UI-facing description all reordered
  and shortened to lead with anomaly detection instead of device
  import, and to drop implementation detail that belongs in the
  README, not the Settings page.
- Trimmed the "Why not extend PIHOLEAPI" README section per feedback -
  useful context for a maintainer, not for an end user configuring
  the plugin.

config.json / pihole_monitor.py:
- RUN defaults to "disabled", matching every other non-core plugin.
- VERIFY_SSL split into PRIMARY_VERIFY_SSL / SECONDARY_VERIFY_SSL -
  each instance can be http/https independently. Settings reordered so
  each *_VERIFY_SSL sits right under its matching *_PASSWORD.
- GRAPHQL_TOKEN removed; graphql_token now reads the core API_TOKEN
  setting instead of a plugin-specific duplicate.
- GRAPHQL_URL replaced with a GET_OWNER boolean - the endpoint is now
  derived from this app's own GRAPHQL_PORT (single source of truth)
  instead of a URL the user had to keep in sync by hand.
- HISTORY_LENGTH (run count) replaced with HISTORY_DAYS (a real time
  window): state now stores [timestamp, delta] samples and
  trim_history() drops anything older than the window, so the
  baseline means the same thing regardless of schedule - a faster
  schedule adds more data points instead of shrinking the window.
- STATE_FILE moved from the log folder to dbFolderPath, so the rolling
  anomaly baseline survives NetAlertX upgrades instead of being wiped
  with the logs.
- netalertx_device_owner() (1 GraphQL call per device) replaced by
  netalertx_device_owners() (1 call per run, batched) - avoids N
  blocking round-trips on a large network.
- Fixed a zero-baseline bug: `bool(... and baseline and ...)` silently
  exempted a device with an all-zero blocked-query history (0.0 is
  falsy in Python) from ever being flagged, even on its first real
  spike. Now checks `baseline is not None`.
- Fixed the placeholder-MAC filter: only excluded the literal "ip-::",
  not Pi-hole's general "ip-<address>" placeholder pattern. Caught
  downstream by is_mac() either way, but now the actual placeholder
  check does what it looks like it does.
- Fixed a cumulative-counter bug: Pi-hole's /api/stats/top_clients
  returns a count that's cumulative since FTL last started, not a
  per-interval or daily-resetting one (confirmed against FTL's own
  source and long-standing user reports that it doesn't reset at
  midnight). Comparing that raw total directly against a rolling
  average made any device's ordinary growing traffic look like an
  escalating anomaly. compute_delta() now diffs each run's raw count
  against the previous run's (state gained a per-key last_raw
  reference point alongside the delta history) - None (not 0) on the
  first-ever run for a device or right after a counter reset, so
  those runs re-anchor the reference point instead of fabricating or
  swallowing a delta.
- RUN_SCHD default changed from every 6 hours to every 5 minutes now
  that the baseline window is real days, not run count, so a frequent
  schedule only adds data points instead of narrowing the window; also
  matches the default most other device-scanner plugins use.
- RUN_SCHD gained the same live cron-validity checkmark ARPSCAN and
  other scanner plugins use (a ✓/✗ icon next to the field, validated
  client-side against a regex) - reuses the existing generic
  validateRegex() widget, nothing plugin-specific to build.

Tests: 48 tests (up from 37), 99% line+branch coverage. Every fix
above verified via mutation testing (deliberately broken, confirmed
the relevant test fails, then restored).
2026-08-31 11:49:02 -05:00

7.9 KiB
Executable File

Integration with Pi-hole

NetAlertX includes four plugins for integrating with an existing Pi-hole installation. The first plugin imports devices through the Pi-hole v6 API, the second parses the dhcp.leases file generated by Pi-hole, the third reads the Pi-hole SQLite database directly, and the fourth flags devices with a blocked-query spike (a common malware/compromised-device signature) and, alongside that, imports devices from one or two Pi-hole v6 instances at once. You can use any of these approaches individually or combine them with each other and other plugins.

Approach 1: PIHOLEAPI Plugin - Import devices directly from the Pi-hole v6 API

To use this approach, make sure a Web UI password is configured in Pi-hole.

Settings

PIHOLEAPI sample settings

Setting Description Recommended value
PIHOLEAPI_URL Your Pi-hole base URL, including the port. http://192.168.1.82:9880/
PIHOLEAPI_RUN_SCHD If you run multiple device scanner plugins, configure them to use the same schedule. */5 * * * *
PIHOLEAPI_PASSWORD The Pi-hole Web UI admin password. NetAlertX automatically handles Base64 encoding and decoding. passw0rd
PIHOLEAPI_SSL_VERIFY Whether to verify HTTPS certificates. Disable only when using self-signed certificates. False
PIHOLEAPI_API_MAXCLIENTS Maximum number of devices to request from Pi-hole. The default value is usually sufficient. 500
PIHOLEAPI_FAKE_MAC Generate a deterministic fake MAC address from the IP address. False

Check the PIHOLEAPI plugin README for additional details and troubleshooting.

docker-compose changes

No changes are required.


Approach 2: DHCPLSS Plugin - Import devices from the Pi-hole DHCP leases file

This approach requires mounting the Pi-hole DHCP leases file (dhcp.leases) into the NetAlertX container. This is straightforward when both applications run on the same host. If they run on different hosts, you'll need to synchronize the file or use the PIHOLEAPI plugin instead.

Settings

DHCPLSS sample settings

Setting Description Recommended value
DHCPLSS_RUN When the plugin should run. schedule
DHCPLSS_RUN_SCHD If you run multiple device scanner plugins, configure them to use the same schedule. */5 * * * *
DHCPLSS_paths_to_check Path to the mapped dhcp.leases file inside the container. The path must include pihole so the plugin can identify it as a Pi-hole leases file. ['/etc/pihole/dhcp.leases']

Check the DHCPLSS plugin README for additional details.

docker-compose changes

Path Description
:/etc/pihole/dhcp.leases Mount Pi-hole's dhcp.leases file. This path must match an entry in DHCPLSS_paths_to_check.

Approach 3: PIHOLE Plugin - Import devices directly from the Pi-hole database

This approach requires mounting the Pi-hole database file into the NetAlertX container. This is straightforward when both applications run on the same host. If Pi-hole is running on a different host, you'll need to synchronize the database file into the NetAlertX container. In that scenario, the PIHOLEAPI or DHCPLSS plugins are usually simpler.

Settings

PIHOLE sample settings

Setting Description Recommended value
PIHOLE_RUN When the plugin should run. schedule
PIHOLE_RUN_SCHD If you run multiple device scanner plugins, configure them to use the same schedule. */5 * * * *
PIHOLE_DB_PATH Path to the mapped Pi-hole database file inside the container. /etc/pihole/pihole-FTL.db

Check the PIHOLE plugin README for additional details.

docker-compose changes

Path Description
:/etc/pihole/pihole-FTL.db Mount Pi-hole's pihole-FTL.db database file.

Approach 4: PIHOLEMON Plugin - Blocked-query anomaly detection (plus device import from one or two Pi-hole v6 instances)

This plugin's main job is different from the other three above: it watches each device's own blocked-query count and flags it when that count spikes well above its recent average - a common signature of malware or a compromised device beaconing out to blocklisted domains, not just device discovery. Bundled into the same connection is a second job, the same idea as PIHOLEAPI's device import, extended to a primary and an optional secondary/failover Pi-hole instance under one set of settings.

How it differs from PIHOLEAPI:

  • Anomaly detection is the point, not a bonus. PIHOLEAPI only imports devices. This plugin's reason to exist is watching a device you already know for a sudden change in its own behavior - device import is the second, supporting job, not the main one.
  • Two Pi-hole instances, not one. A primary and an optional secondary/failover are both checked and their results combined under one set of settings - useful if you run more than one Pi-hole (e.g. two resolvers for redundancy) and want a single device list and a single anomaly baseline across both, instead of a blind spot on whichever instance isn't being watched.
  • Choose PIHOLEAPI if you only run one Pi-hole and just want device import - it's the simpler, more focused option. Choose PIHOLEMON if you want the anomaly detection, or run two Pi-holes needing one configuration, or both.

Check the PIHOLEMON plugin README for the full settings reference, the http:// vs https:// trade-off, and troubleshooting.

docker-compose changes

No changes are required - this plugin only talks to Pi-hole's API, the same as PIHOLEAPI.


Explore other plugins to discover additional information about your network, or learn how to scan remote networks.