Security & hardening
What setup does for you automatically and what you need to do yourself before exposing the panel.
What setup handles automatically
JWT_SECRET_KEYgenerated withopenssl rand -hex 64– without it every container restart invalidates all sessions.- DB passwords generated randomly.
.envgetschmod 600.- Swagger/OpenAPI at
/docsis disabled by default (DOCS_ENABLED=false). - Password hashing via
pwdlib+ bcrypt. Old passlib hashes still work. - Login rate limit active since v2.3.7 (HTTP 429 after too many failures).
- Webhook SSRF protection active since v2.3.7 (private URLs blocked).
What you have to do yourself
1 · Reverse proxy with TLS in front
The built-in HTTP server should not be reachable from the internet directly. Caddy is by far the fastest:
pdns.example.com {
encode zstd gzip
reverse_proxy localhost:5380
} nginx (classic, no auto-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 · Once HTTPS is up: turn on the cookie secure flag
# in .env
AUTH_COOKIE_SECURE=true Then docker compose up -d once. Otherwise the browser sends the cookie over HTTPS unreliably.
3 · Disable self-registration once accounts are created
# in .env
ENABLE_REGISTRATION=false 4 · Firewall: port 5380 only locally
sudo ufw allow 22/tcp
sudo ufw allow 80,443/tcp
sudo ufw deny 5380/tcp
sudo ufw enable Now only the local reverse proxy can reach the panel.
5 · Change the admin password after first login
If you used the initial password from the container log, set your own one in your profile right after first login – ideally enable TOTP too.
6 · Encrypt SMTP traffic
In the SMTP panel pick STARTTLS or TLS – not "no SSL". Otherwise mailserver credentials travel in clear text.
7 · DOCS_ENABLED on purpose
If you don't need the OpenAPI docs at /docs, leave DOCS_ENABLED=false. Endpoints work without it; otherwise every anonymous visitor would get the full schema.
Optional extras
- Fail2Ban on reverse proxy logs (additional layer to the built-in rate limit).
- IP allow-list for
/api/v1/auth/loginat the reverse proxy if you don't allow self-registration. - Cloudflare Tunnel / Tailscale Funnel – run the panel without open ports.
- Backups:
./update.shtakes one before each update, but don't rely on that. Better: daily cron dump to S3/Backblaze.
Known limitations
- No multi-tenant separation (no isolated "customers"). For that look at PowerDNS-Admin or commercial products.
- No built-in reverse proxy / TLS – use Caddy / nginx / Traefik / Cloudflare Tunnel.
- No DHCP, no recursor – this manages authoritative zones.
Found a vulnerability?
Don't open a public issue. Use GitHub Security → "Report a vulnerability" instead – details in SECURITY.md.