PDNS Manager

Sicherheit & Härtung

Was beim Setup automatisch passiert und was du selbst noch erledigen solltest, bevor das Panel öffentlich erreichbar ist.

Was beim Setup automatisch passiert

  • JWT_SECRET_KEY wird mit openssl rand -hex 64 erzeugt – ohne den Schlüssel sind nach jedem Container-Restart alle Logins ungültig.
  • DB-Passwörter werden zufällig generiert.
  • .env bekommt chmod 600.
  • Swagger/OpenAPI unter /docs ist standardmäßig aus (DOCS_ENABLED=false).
  • Passwort-Hashing über pwdlib mit bcrypt. Alte Hashes aus passlib-Zeiten bleiben gültig.
  • Login-Rate-Limit ist seit v2.3.7 aktiv (HTTP 429 bei zu vielen fehlgeschlagenen Logins).
  • Webhook-SSRF-Schutz ist seit v2.3.7 aktiv (private URLs blockiert).

Was du selbst machen musst

1 · Reverse-Proxy mit TLS davorschalten

Der eingebaute HTTP-Server soll nicht direkt aus dem Internet erreichbar sein. Caddy ist mit Abstand am schnellsten aufgesetzt:

pdns.example.com {
    encode zstd gzip
    reverse_proxy localhost:5380
}

nginx (klassisch, ohne automatisches HTTPS):

server {
    listen 443 ssl http2;
    server_name pdns.example.com;

    ssl_certificate     /etc/letsencrypt/live/pdns.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pdns.example.com/privkey.pem;

    client_max_body_size 8m;

    location / {
        proxy_pass         http://127.0.0.1:5380;
        proxy_http_version 1.1;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_read_timeout 60s;
    }
}

2 · Sobald HTTPS läuft: Cookie-Secure-Flag setzen

# in der .env
AUTH_COOKIE_SECURE=true

Anschließend einmal docker compose up -d. Sonst sendet der Browser den Cookie über HTTPS unzuverlässig.

3 · Selbst-Registrierung abschalten, sobald alle Accounts da sind

# in der .env
ENABLE_REGISTRATION=false

4 · Firewall: Port 5380 nur lokal

Auf dem Host:

# UFW
sudo ufw allow 22/tcp
sudo ufw allow 80,443/tcp
sudo ufw deny 5380/tcp
sudo ufw enable

Damit ist nur der Reverse-Proxy auf dem Host noch in der Lage, das Panel zu erreichen.

5 · Admin-Passwort nach dem ersten Login ändern

Falls du das Initial-Passwort aus dem Container-Log genutzt hast: nach dem ersten Login direkt im Profil ein eigenes setzen und idealerweise auch TOTP aktivieren.

6 · SMTP-Verkehr verschlüsseln

Im SMTP-Panel STARTTLS oder TLS aktivieren – nicht „kein SSL". Sonst landen Mailserver-Credentials im Klartext über das Netz.

7 · DOCS_ENABLED bewusst entscheiden

Wer die OpenAPI-Doku unter /docs nicht braucht, lässt DOCS_ENABLED=false. Die Endpunkte selbst funktionieren auch ohne, aber jeder anonyme Besucher würde sonst die komplette Schema-Liste bekommen.

Optional: zusätzliche Schichten

  • Fail2Ban auf die Reverse-Proxy-Logs (zusätzlich zum eingebauten Login-Rate-Limit).
  • IP-Allowlist für /api/v1/auth/login (über den Reverse-Proxy), wenn du keine Selbst-Registrierung anbietest und alle Admin-User aus festen Netzen kommen.
  • Cloudflare Tunnel / Tailscale Funnel – wenn du das Panel ohne offene Ports betreiben willst.
  • Backups: ./update.sh macht vor jedem Update eines, aber sich darauf verlassen ist optimistisch. Lieber täglicher Cron-Dump nach S3/Backblaze.

Bekannte Begrenzungen

  • Keine Multi-Tenant-Mandantentrennung (keine getrennten „Kunden"). Wer das braucht, ist mit PowerDNS-Admin oder einer kommerziellen Lösung besser bedient.
  • Kein eingebauter Reverse-Proxy / kein TLS – das macht Caddy / nginx / Traefik / Cloudflare Tunnel davor.
  • Kein DHCP, kein Recursor – das hier verwaltet Authoritative Zones.

Eine Sicherheitslücke gefunden?

Bitte kein öffentliches Issue. Stattdessen über GitHub Security → „Report a vulnerability" – Details in SECURITY.md.