Skip to content
Блог › Software configuration › Monitoring BIND in Zabbix: Two Easy Ways

Monitoring BIND in Zabbix: Two Easy Ways

0. Prerequisites

  • Zabbix Server 7.0+
  • Zabbix Agent (classic or agent2) running on the DNS host
  • Utilities: curl and one of the XML tools: xmllint (from libxml2) or xmlstarlet
  • On Alma/RHEL 9/10: dnf install -y curl libxml2 xmlstarlet
  • On Debian/Ubuntu: apt-get install -y curl libxml2-utils xmlstarlet

On AlmaLinux 10, the xml2 package is often missing — use xmllint or xmlstarlet instead.


1. Enable statistics in BIND and secure access

Add this configuration in named.conf (outside of any view, or inside the specific view if you use them):

// Enable statistics over HTTP (XML/JSON, depending on BIND version)
statistics-channels {
    inet 127.0.0.1 port 8053 allow { 127.0.0.1; <IP_ZABBIX_SERVER>; };
};

// Recommendations for an authoritative NS
options {
    directory "/var/named";         // or /var/cache/bind on Debian
    recursion no;                   // on authoritative servers
    allow-query { any; };           // or your ACL
    // … your other options …
};

Then check and reload:

named-checkconf -z
systemctl reload named   # or named-chroot / named-pkcs11 etc., depending on your package

Verify that statistics are working:

curl -fsS http://127.0.0.1:8053/ | head

If BIND is behind a reverse proxy and you receive a 307 Temporary Redirect, disable redirection for 127.0.0.1 or access the port directly (8053).


2. Option A (quick): use a ready-made “BIND9 statistics by HTTP” template

  1. Import the community template Template Bind9-stat by HTTP (Zabbix 7.0) in the Zabbix UI (this template reads statistics via HTTP).
  2. On the host running BIND:
    • Ensure curl and either xmllint or xmlstarlet are installed.
    • In zabbix_agentd.conf, remove deprecated lines such as: # EnableRemoteCommands=1 <-- deprecated And add the permission only for the specific key: AllowKey=system.run[*]
    • Restart the agent: systemctl restart zabbix-agent
  3. Link the template to your BIND host. If the template expects a macro for the statistics URL, set it to http://127.0.0.1:8053/.
  4. In the frontend (Latest data → filter by host), you should see counters per query types (A / AAAA / NS / …).

If the import fails, confirm you selected the version for Zabbix 7.0 (YAML export format changed in 7.0).


3. Option B (minimal custom): 3 metrics via UserParameter

This is a backup — a custom minimalist approach using xmllint / xmlstarlet. We’ll write a small parsing script and agent keys.

3.1 Parsing script

Create /usr/local/bin/bindstat.sh:

#!/bin/bash
set -euo pipefail

# URL of BIND statistics interface
URL="${BINDSTAT_URL:-http://127.0.0.1:8053/}"
WHAT="${1:-queries-in}"   # queries-in | queries-out | counter
QTYPE="${2:-A}"           # e.g. A, AAAA, MX …

DATA="$(curl -fsS "$URL")"

extract_rdtype() {
  local dir="$1" q="$2"
  if command -v xmllint >/dev/null; then
    xmllint --xpath "string(//${dir}/rdtype[@name='${q}'])" - 2>/dev/null || true
  elif command -v xmlstarlet >/dev/null; then
    xmlstarlet sel -t -v "//${dir}/rdtype[@name='${q}']" 2>/dev/null || true
  else
    grep -oP "<${dir}[^>]*>.*?<rdtype name=[\"']${q}[\"']>([0-9]+)</rdtype>.*?</${dir}>" -m1 \
      | grep -oP "(?<=<rdtype name=[\"']${q}[\"']>)[0-9]+"
  fi
}

case "$WHAT" in
  queries-in)
    echo "$DATA" | extract_rdtype "queries-in" "$QTYPE"
    ;;
  queries-out)
    echo "$DATA" | extract_rdtype "queries-out" "$QTYPE"
    ;;
  counter)
    # Example: counter server/nsstat/Requestv4 (custom usage)
    # echo "$DATA" | xmllint --xpath 'string(//server/counters[@type="nsstat"]/counter[@name="Requestv4"])' -
    ;;
  *)
    echo "Unsupported" >&2
    exit 1
    ;;
esac

Make it executable:

chmod +x /usr/local/bin/bindstat.sh

3.2 Agent UserParameter configuration

In /etc/zabbix/zabbix_agentd.d/bind.conf:

# Note: Ensure in zabbix_agentd.conf you have AllowKey=system.run[*]

# Incoming queries for QTYPE (A, AAAA, MX…)
UserParameter=bind.queries.in[*],/usr/local/bin/bindstat.sh queries-in "$1"

# Outgoing (recursive / forwarding) queries for QTYPE — usually 0 on authoritative
UserParameter=bind.queries.out[*],/usr/local/bin/bindstat.sh queries-out "$1"

Then restart the agent:

systemctl restart zabbix-agent

Test from the Zabbix server:

zabbix_get -s <IP_DNS> -k "bind.queries.in[A]"

Create in Zabbix your own “mini-template” with two items:

  • bind.queries.in[A] (Type: Zabbix agent, value type: Numeric (unsigned), update: 60s)
  • bind.queries.in[AAAA] … and so on (or use LLD for query types)

Then add simple triggers, e.g. “no queries in 10 min” or “abnormally many NXDOMAIN”.


4. Security recommendations

  • Keep statistics-channels bound to 127.0.0.1 and query it locally via the agent.
  • If remote access is needed — open the port only to the Zabbix Server’s IP via firewall, or place an Nginx reverse proxy with basic authentication.
  • SELinux:
    • For zone directories (if you’re also monitoring slave/master files) use the named_zone_t context.
    • For statistics itself, typically no additional SELinux config is needed.

5. Common errors and how to catch them

  • 404 or 307 Temporary Redirect — you’re hitting the wrong endpoint (due to reverse proxy or prefix). Verify curl http://127.0.0.1:8053/.
  • xml2: command not found — install libxml2 (gives xmllint) or xmlstarlet, and switch to Option B or updated template.
  • No data in Latest data — check journalctl -u zabbix-agent -n 100, or test via zabbix_get.

6. What to monitor exactly

  • Queries in, by QTYPE: A / AAAA / MX / NS / SOA — illustrates traffic behavior
  • SERVFAIL / FORMERR / NXDOMAIN (if you pull counters) — resolution errors
  • Zone transfers (IXFR / AXFR counters) — for authoritative clusters
  • Recursive / forwarding responses — applicable to recursive servers

Summary

The easiest way is to enable statistics-channels in BIND, import the ready-made Bind9 statistics by HTTP template for Zabbix 7.0, and ensure curl + xmllint/xmlstarlet are available on your server. If you prefer control and minimalism, then 2–3 UserParameter metrics with a small parsing script will give you the essential graphs in about 10 minutes.

Leave a Reply

Your email address will not be published. Required fields are marked *