tutorial

Uptime monitoring for PowerDNS authoritative and recursive DNS servers

DNS is the first thing that breaks and the last thing teams think to monitor. PowerDNS — whether you run it as an authoritative server (`pdns_server`) or as ...

DNS is the first thing that breaks and the last thing teams think to monitor. PowerDNS — whether you run it as an authoritative server (pdns_server) or as a resolver (pdns_recursor) — sits at the foundation of every network request your services make. When PowerDNS goes down, internal service discovery breaks, external users cannot resolve your domains, and your monitoring tools lose the ability to reach their own alert endpoints.

This tutorial covers production-grade uptime monitoring for PowerDNS using Vigilmon. We will walk through:

  • Monitoring the PowerDNS authoritative server via its HTTP API
  • Monitoring the PowerDNS Recursor health endpoint
  • DNS-level monitoring for your zones
  • SSL certificate monitoring
  • Webhook alerts for DOWN/UP events

Prerequisites

  • PowerDNS Authoritative Server 4.x or PowerDNS Recursor 4.x running on Linux
  • A free account at vigilmon.online

Part 1: Enable the PowerDNS HTTP API

Both pdns_server (authoritative) and pdns_recursor expose an HTTP API you can poll for health status and statistics. The API must be explicitly enabled in configuration.

Authoritative Server (pdns.conf)

# /etc/powerdns/pdns.conf

# Enable the HTTP API
api=yes
api-key=your-secret-api-key

# Bind the webserver
webserver=yes
webserver-address=127.0.0.1
webserver-port=8081
webserver-allow-from=127.0.0.1,::1

# Optional: allow external polling (restrict to Vigilmon IPs in production)
# webserver-address=0.0.0.0
# webserver-allow-from=0.0.0.0/0

Restart PowerDNS after updating the configuration:

systemctl restart pdns

Recursor (recursor.conf)

# /etc/powerdns/recursor.conf

# Enable the HTTP API
api-key=your-secret-recursor-key

# Bind the webserver
webserver=yes
webserver-address=127.0.0.1
webserver-port=8082
webserver-allow-from=127.0.0.1,::1
systemctl restart pdns-recursor

Verify the API is running

# Authoritative server
curl -s -H "X-API-Key: your-secret-api-key" \
  http://localhost:8081/api/v1/servers/localhost | jq .

# Recursor
curl -s -H "X-API-Key: your-secret-recursor-key" \
  http://localhost:8082/api/v1/servers/localhost | jq .

Expected response:

{
  "type": "Server",
  "id": "localhost",
  "daemon_type": "authoritative",
  "version": "4.9.1",
  "url": "api/v1/servers/localhost"
}

Part 2: Expose a health endpoint via nginx

The PowerDNS API requires an X-API-Key header for authentication. Vigilmon HTTP monitors support custom headers, but the simplest pattern for production is to expose a public /health endpoint via nginx that strips the key from internal calls:

# /etc/nginx/sites-available/pdns-health
server {
    listen 443 ssl;
    server_name dns-monitor.example.com;

    ssl_certificate     /etc/letsencrypt/live/dns-monitor.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/dns-monitor.example.com/privkey.pem;

    # Public health endpoint for Vigilmon — no auth required
    location /pdns/health {
        proxy_pass http://127.0.0.1:8081/api/v1/servers/localhost;
        proxy_set_header X-API-Key "your-secret-api-key";
        proxy_set_header Host localhost;
        access_log off;
    }

    # Public health endpoint for Recursor
    location /pdns-recursor/health {
        proxy_pass http://127.0.0.1:8082/api/v1/servers/localhost;
        proxy_set_header X-API-Key "your-secret-recursor-key";
        proxy_set_header Host localhost;
        access_log off;
    }

    # Block all other paths
    location / {
        return 403;
    }
}

Reload nginx:

nginx -t && systemctl reload nginx

Verify:

curl https://dns-monitor.example.com/pdns/health | jq .type
# "Server"

curl https://dns-monitor.example.com/pdns-recursor/health | jq .daemon_type
# "recursor"

Alternative: use the statistics endpoint for richer health checks

The /api/v1/servers/localhost/statistics endpoint returns detailed counters you can use to detect degraded states beyond simple process liveness:

curl -s -H "X-API-Key: your-secret-api-key" \
  http://localhost:8081/api/v1/servers/localhost/statistics | \
  jq '.[] | select(.name == "query-cache-hit") | .value'

Part 3: Set up HTTP monitoring in Vigilmon

Monitor the authoritative server

  1. Log in to vigilmon.online and click Add Monitor.
  2. Choose HTTP(S) monitor.
  3. Enter: https://dns-monitor.example.com/pdns/health
  4. Set interval to 1 minute.
  5. Add a keyword check: must contain authoritative or "type":"Server".
  6. Add your alert channel.
  7. Click Save.

Monitor the recursor

  1. Click Add Monitor again.
  2. Choose HTTP(S) monitor.
  3. Enter: https://dns-monitor.example.com/pdns-recursor/health
  4. Set interval to 1 minute.
  5. Add a keyword check: must contain recursor.
  6. Add your alert channel.
  7. Click Save.

Keep authoritative and recursor monitors separate. DNS resolution failures from the recursor look very different from zone-serving failures from the authoritative server, and you want the Vigilmon dashboard to show exactly which process is down.


Part 4: DNS-level monitoring

HTTP monitoring checks whether the PowerDNS process is alive. DNS monitoring checks whether PowerDNS is actually resolving queries correctly — which matters if the process is running but the zone data is corrupted or a backend database is unreachable.

Add a TCP monitor for each PowerDNS instance to confirm port 53 is open and accepting connections:

  1. In Vigilmon, click Add Monitor.
  2. Choose TCP monitor (or Port monitor).
  3. Enter: your PowerDNS server IP, port 53.
  4. Set interval to 1 minute.
  5. Add your alert channel.
  6. Click Save.

Pair this with monitoring of your authoritative zones. If you host example.com on PowerDNS, add an HTTP monitor that performs a DNS lookup via your public resolver and verifies the expected IP is returned. You can run this as a simple cron-based heartbeat:

#!/bin/bash
# check-dns-resolution.sh

EXPECTED_IP="203.0.113.10"
ACTUAL_IP=$(dig +short @your-pdns-server example.com A | head -1)

if [ "$ACTUAL_IP" = "$EXPECTED_IP" ]; then
  curl -s "https://vigilmon.online/api/heartbeat/your-dns-heartbeat-id"
else
  echo "DNS resolution mismatch: expected $EXPECTED_IP, got $ACTUAL_IP" >&2
  exit 1
fi

Part 5: Monitor PowerDNS in Docker or Kubernetes

Docker Compose

# docker-compose.yml
version: "3.8"

services:
  pdns:
    image: powerdns/pdns-auth-49:latest
    ports:
      - "53:53/udp"
      - "53:53/tcp"
      - "8081:8081"
    environment:
      PDNS_AUTH_API_KEY: your-secret-api-key
      PDNS_AUTH_WEBSERVER: "yes"
      PDNS_AUTH_WEBSERVER_ADDRESS: 0.0.0.0
      PDNS_AUTH_WEBSERVER_PORT: 8081
      PDNS_AUTH_WEBSERVER_ALLOW_FROM: "0.0.0.0/0"
    volumes:
      - ./pdns.conf:/etc/powerdns/pdns.conf:ro
    restart: unless-stopped

  pdns-recursor:
    image: powerdns/pdns-recursor-50:latest
    ports:
      - "5300:5300/udp"
    environment:
      PDNS_RECURSOR_API_KEY: your-recursor-key
      PDNS_RECURSOR_WEBSERVER: "yes"
      PDNS_RECURSOR_WEBSERVER_ADDRESS: 0.0.0.0
      PDNS_RECURSOR_WEBSERVER_PORT: 8082
    restart: unless-stopped

Kubernetes deployment with health probes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pdns-authoritative
  namespace: dns
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pdns-authoritative
  template:
    metadata:
      labels:
        app: pdns-authoritative
    spec:
      containers:
        - name: pdns
          image: powerdns/pdns-auth-49:latest
          ports:
            - containerPort: 53
              protocol: UDP
            - containerPort: 53
              protocol: TCP
            - containerPort: 8081
          livenessProbe:
            httpGet:
              path: /api/v1/servers/localhost
              port: 8081
              httpHeaders:
                - name: X-API-Key
                  value: your-secret-api-key
            initialDelaySeconds: 10
            periodSeconds: 30
          readinessProbe:
            httpGet:
              path: /api/v1/servers/localhost
              port: 8081
              httpHeaders:
                - name: X-API-Key
                  value: your-secret-api-key
            initialDelaySeconds: 5
            periodSeconds: 10

Part 6: SSL certificate monitoring

If PowerDNS-Admin (the web UI) or your DNS monitoring proxy endpoint uses TLS:

  1. In Vigilmon, click Add Monitor.
  2. Choose SSL monitor.
  3. Enter: dns-monitor.example.com
  4. Set alert threshold to 14 days before expiry.
  5. Add your alert channel.

Part 7: Webhook alerts

// webhook-receiver.ts
import express from 'express';

const app = express();
app.use(express.json());

app.post('/webhook/vigilmon', (req, res) => {
  const { monitor_name, status, url, response_code, checked_at } = req.body;

  if (status === 'down') {
    console.error('[VIGILMON] PowerDNS monitor DOWN', {
      monitor: monitor_name,
      url,
      code: response_code,
      at: checked_at,
    });

    // DNS failures are P1 — page immediately
    pageOnCall({
      title: `PowerDNS is DOWN: ${monitor_name}`,
      severity: 'critical',
      url,
      checked_at,
    });
  } else if (status === 'up') {
    console.info('[VIGILMON] PowerDNS recovered', { monitor: monitor_name });
  }

  res.sendStatus(204);
});

app.listen(3000);

Vigilmon sends this payload on DOWN and UP transitions:

{
  "monitor_id": "mon_abc123",
  "monitor_name": "PowerDNS Authoritative",
  "status": "down",
  "url": "https://dns-monitor.example.com/pdns/health",
  "checked_at": "2026-06-30T09:00:00Z",
  "response_code": 503,
  "response_time_ms": 2045
}

Summary

Your PowerDNS deployment now has four layers of monitoring:

  1. HTTP API health — Vigilmon polls /api/v1/servers/localhost every 60 seconds to confirm the PowerDNS process is alive and its API layer is responding.
  2. TCP port 53 monitor — confirms DNS port is open and accepting connections, independent of the API.
  3. DNS resolution heartbeat — a cron script verifies that actual DNS queries return the expected results and pings Vigilmon's heartbeat endpoint on success.
  4. Webhook alerts — DNS failures trigger P1 on-call pages immediately, because DNS outages cascade to every dependent service.

Vigilmon handles check scheduling, multi-region polling, alert routing, and uptime history — so your DNS infrastructure monitoring is as reliable as the DNS infrastructure itself.


Monitor your PowerDNS infrastructure free at vigilmon.online

#powerdns #dns #devops #monitoring #infrastructure

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →