Skip to main content

Unbound smart home integration, free and open source

Unbound integration for Gladys Assistant

Unbound DNS resolver: queries, cache, recursion time, SERVFAIL, alerts and cache flush.

Follow your Unbound DNS resolver from Gladys, over your local network: queries per minute, cache hit rate, average recursion time, SERVFAIL and NXDOMAIN answers, uptime, and an alert when it stops answering, fails too many lookups or gets flooded with queries. Unbound is often the recursive resolver behind Pi-hole, AdGuard Home or Blocky: those block the ads, Unbound answers the rest. This integration watches the resolver, not the blocking.

Tested against a real Unbound 1.25.2 (Alpine package, in Docker, with the certificates of unbound-control-setup and real dig queries), not yet with a real Gladys installation: feedback welcome. If something does not work as described, please say so on the Gladys forum or in the issues.

What you need​

  • Gladys Assistant 5.1.0 or later.
  • Unbound with its remote control turned on, the channel used by unbound-control. Gladys sends the same commands as unbound-control stats_noreset and unbound-control status: it only reads, and never runs stats, which resets the counters.
  • For the SERVFAIL and NXDOMAIN figures, the extended statistics.

In unbound.conf:

server:
extended-statistics: yes

remote-control:
control-enable: yes
# An address of the Unbound machine that Gladys can reach (not 127.0.0.1:
# Gladys runs the integration in its own container).
control-interface: 192.168.1.2
control-port: 8953

Then create the certificates once, on the Unbound machine, and restart Unbound:

sudo unbound-control-setup
sudo systemctl restart unbound

unbound-control-setup writes three files, usually in /etc/unbound: unbound_server.pem, unbound_control.pem and unbound_control.key (plus the server key, which stays there). Check that sudo unbound-control status works on the machine before going on.

If statistics-interval is set in unbound.conf, also set statistics-cumulative: yes: otherwise Unbound resets its counters at each interval and the rates are wrong.

Set up​

In Gladys, Integrations → Unbound → Configuration:

  1. Address: the IP address or name of the Unbound machine, with :port if the control port is not 8953.
  2. Name: the name of the device in Gladys (optional).
  3. Connection: TLS with certificates (the default of Unbound), or Plain TCP if unbound.conf says control-use-cert: no. Plain TCP has no password at all: anyone who reaches the port can stop Unbound. Keep it for a port closed to the rest of the network.
  4. Certificates: open each file with a text editor (sudo cat /etc/unbound/unbound_control.pem) and paste the whole content, from -----BEGIN to -----END, into Server certificate (unbound_server.pem), Client certificate (unbound_control.pem) and Client key (unbound_control.key). The field keeps only one line: that is expected, the integration puts the line breaks back. The key is stored as a secret, never shown again nor logged.
  5. Options: the refresh interval (1 minute by default), the two alert thresholds, Allow flushing the cache (off by default), and the language of the feature names.
  6. Save, then Test the connection: it shows the version of Unbound, the connection used, its uptime and whether the extended statistics are on.
  7. In the Discovery tab, add the device.

The device​

One device for the server, with these features:

FeatureWhat it shows
Reachable1 when the remote control answers, 0 otherwise
DNS queries per minuteQueries received, between the last two readings
Cache hit rateShare of the queries answered from the cache, last 15 minutes (%)
Average recursion timeTime to resolve a name absent from the cache, last 15 minutes
SERVFAIL per minuteFailed resolutions (extended statistics)
NXDOMAIN per minuteNames that do not exist (extended statistics)
UptimeHours since Unbound started
VersionVersion of Unbound

Without the extended statistics, the device has no SERVFAIL nor NXDOMAIN; turn them on and Gladys proposes Update in the Discovery tab. The rates appear from the second reading. After a restart of Unbound its counters start again from zero: the rates come back one reading later.

Dashboard​

The Unbound widget shows three tiles (queries per minute, cache hit rate, recursion time) and a list: the state of the resolver, SERVFAIL and NXDOMAIN per minute (SERVFAIL in orange above its alert threshold), uptime and version. When Allow flushing the cache is on, a button, Flush the cache, empties it.

Scenes​

Triggers​

  • Unbound no longer answers: two readings in a row without answer (the second one 15 seconds after the first). Variables: server name, device, error.
  • Unbound answers again: back after an outage, with the minutes without answer.
  • Unbound SERVFAIL above the threshold: the SERVFAIL answers per minute reach SERVFAIL alert of the configuration (20 by default, 0 turns it off). It fires once, then again only after the rate went back below. Needs the extended statistics.
  • Unbound queries surging: the queries per minute reach Query surge alert (2000 by default, 0 turns it off), for a device stuck in a loop or a malware. Same once-only rule.

Actions​

  • Read the Unbound statistics: reads Unbound now. Gives a sentence ("Unbound: 120 queries per minute, 85 % answered from the cache, 32 ms per recursion.") for a message or a voice announcement, and the figures for a condition.
  • Flush the Unbound cache: empties the cache, for one domain and everything below it, or all of it when the field is empty. Refused unless Allow flushing the cache is on. Useful after changing a DNS record at home.

Scene ideas​

  • Unbound no longer answers → send a message: "The DNS of the house is down". Add Unbound answers again for the good news.
  • Unbound SERVFAIL above the threshold → a message with the rate: the internet link or the upstream servers have a problem.
  • Every morning at 8:00 → Read the Unbound statistics → send the sentence.
  • Unbound queries surging → a notification, to look for the device gone mad.

Troubleshooting​

  • "does not answer": wrong address or port, Unbound stopped, or control-interface still on 127.0.0.1 (the default). Gladys runs the integration in a container: it needs an address of the network, and a firewall open on port 8953 for the Gladys machine.
  • "TLS refused": one of the three certificate fields does not match the files of this Unbound (they change each time unbound-control-setup -r is run), or Unbound is in plain mode (control-use-cert: no): choose Plain TCP.
  • "connection closed: TLS expected?": Plain TCP is chosen but Unbound waits for TLS: choose TLS with certificates.
  • "paste the whole file": a certificate field holds only a part of the file; copy everything, the -----BEGIN and -----END lines included.
  • No SERVFAIL nor NXDOMAIN: add extended-statistics: yes under server:, restart Unbound, then Update the device in the Discovery tab.
  • Odd or missing rates: another tool runs unbound-control stats (which resets the counters), or statistics-interval is set without statistics-cumulative: yes.
  • Logs: Integrations → Unbound → Logs. Add LOG_LEVEL=debug for every reading.

Limits​

  • One Unbound server per installation of the integration.
  • Developed with a real Unbound in Docker, without a real Gladys installation: feedback welcome.
  • The rates per minute are measured between two readings: a burst shorter than the refresh interval is averaged out.
  • The cache hit rate and the recursion time cover the last 15 minutes; right after the integration starts, they cover the time since Unbound started.
  • Through a Unix socket only (control-interface: /run/unbound.ctl), Unbound cannot be reached from the container of Gladys: use a network address.
  • Not affiliated with NLnet Labs.

Configuration settings​

These are the settings Unbound asks for in its configuration screen in Gladys.

SettingTypeRequiredDescription
Your Unbound serversectionNoGladys reads Unbound through its remote control (remote-control: in unbound.conf, port 8953): control-enable: yes, and control-interface on an address Gladys reaches.
AddressstringYesIP address or name of the server, with :port if it is not 8953.
NamestringNoName of the device in Gladys. Empty: "Unbound" followed by the address.
ConnectionselectNoTLS with the certificates of unbound-control-setup (Unbound's default), or plain TCP if unbound.conf says control-use-cert: no.
Certificates (TLS)sectionNoOpen each file made by unbound-control-setup (often in /etc/unbound) and paste its whole content, from -----BEGIN to -----END. Not needed in plain TCP.
Server certificate (unbound_server.pem)stringNo
Client certificate (unbound_control.pem)stringNo
Client key (unbound_control.key)secretNoKept by Gladys, never shown again nor written in the logs.
OptionssectionNo
Refresh intervalselectNoHow often Unbound is read. The rates per minute are measured between two readings.
SERVFAIL alert (per minute)numberNoThe scene event fires when SERVFAIL answers reach this rate (needs extended-statistics: yes). 0: off.
Query surge alert (per minute)numberNoThe scene event fires when the queries reach this rate: a device gone mad, a loop. 0: off.
Allow flushing the cachebooleanNoOff by default: Gladys then only reads Unbound. On: the scene action and the widget button can empty the cache (flush_zone).
Language of the feature namesselectNoNames given to the features when the device is added, and texts of the scene events and actions.

How to install Unbound in Gladys​

  1. In Gladys, open Integrations: Unbound appears in the catalog, next to the native integrations, with a community badge.
  2. Click Install. Gladys pulls the Docker image (ghcr.io/guim31/gladys-unbound:1.0.0), starts it in a sandbox isolated from the core, and generates the integration's interface (devices, discovery and configuration).
  3. Open the Configuration screen of the integration, fill in the settings, and save.
  4. You can also install it directly from its repository URL: https://github.com/guim31/gladys-unbound.

Unbound requires Gladys >=5.1.0. The catalog inside Gladys refreshes every hour, so a new version becomes available at most one hour after its release.

Not running Gladys yet? It is free and open source: follow the installation guide to get started.

About external integrations​

Unbound is an external integration: a community integration packaged as a Docker container and published on GitHub, that Gladys installs in one click and runs in a sandbox isolated from its core. It is published and maintained by guim31, not by the Gladys core team.

Subscribe to the Gladys Assistant newsletter

A few emails per month about new releases and project news. Sent by Pierre-Gilles Leymarie, founder of the project. Unsubscribe anytime 🙂