PDNS Manager

Panel-API

Alles, was die Web-UI kann, kann auch ein Skript. Der Manager bietet dafür Panel-API-Tokens an, die wie ein normaler User behandelt werden – inkl. Audit, Webhooks und Multi-Server-Fan-out.

Endpunkt-Basis

  • Alle Endpunkte beginnen mit /api/v1.
  • Antworten und Bodies sind JSON.
  • Optional: interaktive Doku unter /docs, falls in der .env DOCS_ENABLED=true gesetzt ist.

Authentifizierung

Drei Wege funktionieren:

1 · Panel-Token (empfohlen für Skripte)

Im Panel als der gewünschte User: Einstellungen → API & Sicherheit → Tokens → Neues Token. Token bekommt den Prefix dnsmgr_usr_ und wird einmalig im Klartext gezeigt.

curl -H "Authorization: Bearer dnsmgr_usr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
     https://pdns.example.com/api/v1/auth/me

2 · Klassischer JWT (z. B. nach interaktivem Login)

# Login (Username/Passwort als Form-Felder)
curl -c cookies.txt -X POST "https://pdns.example.com/api/v1/auth/login" \
     -F "username=admin" -F "password=geheim"

# Folgeanfrage mit Cookie
curl -b cookies.txt "https://pdns.example.com/api/v1/auth/me"

Das Cookie heißt dns_manager_token und ist HttpOnly + (bei HTTPS) Secure.

3 · ACME-Token

Eingeschränkt auf _acme-challenge.* in freigegebenen Zonen, siehe ACME-Doku.

Wichtige Endpoints (Auswahl)

Server

# Liste aller eingetragenen PowerDNS-Server inkl. Erreichbarkeit
GET /api/v1/servers

# Detail + Statistik eines einzelnen Servers
GET /api/v1/servers/master-fra1
GET /api/v1/servers/master-fra1/statistics

Zonen

# Zonen eines Servers
GET /api/v1/zones/master-fra1

# Detail (rrsets sind dabei)
GET /api/v1/zones/master-fra1/example.com./detail

# Anlegen
POST /api/v1/zones
{
  "name": "example.com",
  "kind": "Native",
  "nameservers": ["ns1.example.com.", "ns2.example.com."],
  "soa_edit_api": "DEFAULT"
}

# Importieren mit Diff-Vorschau
POST /api/v1/zones/import/preview
POST /api/v1/zones/import

# NOTIFY auslösen
POST /api/v1/zones/master-fra1/example.com./notify

Records

# Auflisten
GET /api/v1/records/master-fra1/example.com.

# Anlegen / Upsert RRSet
POST /api/v1/records/master-fra1/example.com.
{
  "name": "www.example.com.",
  "type": "A",
  "ttl": 300,
  "records": [{ "content": "203.0.113.10", "disabled": false }]
}

# Bulk
POST /api/v1/records/master-fra1/example.com./bulk
{
  "create": [ ... ],
  "delete": [ ... ]
}

DNSSEC

# Keys auflisten / Detail
GET    /api/v1/dnssec/master-fra1/example.com./keys
GET    /api/v1/dnssec/master-fra1/example.com./keys/12345

# An- und Ausschalten
POST   /api/v1/dnssec/master-fra1/example.com./enable
POST   /api/v1/dnssec/master-fra1/example.com./disable

# DS-Records ablesen
GET    /api/v1/dnssec/master-fra1/example.com./ds

Audit

# Lesen mit Filtern
GET /api/v1/audit-log?action=DELETE&resource_type=RECORD&limit=50

# CSV-Export
GET /api/v1/audit-log/export?max_rows=10000

Settings

# Öffentliche App-Info (Branding, Captcha-Site-Key, Version)
GET /api/v1/settings/app-info

# Server-Verwaltung
GET    /api/v1/settings/servers
POST   /api/v1/settings/servers
PUT    /api/v1/settings/servers/{id}
DELETE /api/v1/settings/servers/{id}
POST   /api/v1/settings/servers/test
GET    /api/v1/settings/servers/{id}/api-key   # einmaliges Reveal, geht ins Audit

# SMTP / Captcha / Welcome-Mail
GET/PUT /api/v1/settings/smtp
POST    /api/v1/settings/smtp/test
POST    /api/v1/settings/smtp/test-email
GET/PUT /api/v1/settings/captcha
GET/PUT /api/v1/settings/welcome-email
POST    /api/v1/settings/welcome-email/test

Beispiel: Bulk-Anlage von 50 Subdomains

for i in $(seq 1 50); do
  curl -s -X POST "https://pdns.example.com/api/v1/records/master-fra1/example.com." \
    -H "Authorization: Bearer dnsmgr_usr_xxxxx" \
    -H "Content-Type: application/json" \
    -d "{
      \"name\":\"app${i}.example.com.\",
      \"type\":\"A\",
      \"ttl\":300,
      \"records\":[{\"content\":\"203.0.113.${i}\"}]
    }"
done

Fehlerantworten

Standard-HTTP-Codes:

  • 200 / 201 – ok.
  • 400 – ungültiger Body. Detail in detail.
  • 401 – Token fehlt oder falsch.
  • 403 – Token gültig, aber keine Berechtigung (z. B. read-only Zone schreiben).
  • 404 – Zone, Record, Server oder User nicht gefunden.
  • 429 – Login-Rate-Limit (nur bei /auth/login).
  • 500 – interner Fehler. Detail bleibt server-seitig im Log; nach außen geht eine kundenfreundliche Meldung.

Token rotieren / widerrufen

Im Panel: Einstellungen → API & Sicherheit → Tokens – pro Zeile ein Löschen-Button. Sofort wirksam.