| Filename | Latest commit message | Latest commit date |
|---|---|---|
| config | ||
| postgres-init | ||
| quadlet | ||
| .gitignore | ||
| README.md | ||
powerdns-quadlet
Podman Quadlet-Setup für einen PowerDNS Authoritative Server (Redmine #8), mit eigener PostgreSQL-Instanz als Backend (gpgsqlbackend).
Architektur
powerdns.network— eigenes Podman-Netzwerk, deklarativ statt perpodman network create(gleiches Muster wie beim Matrix-Quadlet-Umbau, Redmine #6).powerdns-db.volume— persistentes Volume für die Postgres-Daten.powerdns-db.container—postgres:16-alpine, Schema-Bootstrap über/docker-entrypoint-initdb.d(läuft nur einmal, gegen ein leeres Volume).powerdns.container— PowerDNS Authoritative Server, Konfiguration über eine gemountetepdns.conf, Backendgpgsql(PostgreSQL wird von PowerDNS nativ unterstützt, eigene MySQL-Instanz war daher nicht nötig).
Alle vier Units sind rootful/system-weit gedacht (/etc/containers/systemd/),
analog zu den bestehenden Matrix-Quadlets.
Dateien
quadlet/powerdns.network Podman-Netzwerk
quadlet/powerdns-db.volume Postgres-Datenvolume
quadlet/powerdns-db.container Postgres-Container
quadlet/powerdns.container PowerDNS-Container
postgres-init/01-pdns-gpgsql-schema.sql Schema-Bootstrap für Postgres
config/postgres.env.example Vorlage für Postgres-Zugangsdaten
config/pdns.conf.example Vorlage für pdns.conf
.gitignore verhindert versehentliches Commit der echten Secrets
Installation
-
Quadlet-Dateien nach
/etc/containers/systemd/kopieren:sudo cp quadlet/*.network quadlet/*.volume quadlet/*.container /etc/containers/systemd/ -
Konfigurationsverzeichnis anlegen und Vorlagen befüllen:
sudo mkdir -p /etc/powerdns-quadlet/postgres-init sudo cp postgres-init/01-pdns-gpgsql-schema.sql /etc/powerdns-quadlet/postgres-init/ sudo cp config/postgres.env.example /etc/powerdns-quadlet/postgres.env sudo cp config/pdns.conf.example /etc/powerdns-quadlet/pdns.conf sudo chmod 600 /etc/powerdns-quadlet/postgres.env /etc/powerdns-quadlet/pdns.confIn beiden Dateien ein echtes Passwort setzen (
POSTGRES_PASSWORDbzw.gpgsql-password— müssen identisch sein) sowie einenapi-keyfür das PowerDNS-Webinterface/API. -
Units aktivieren:
sudo systemctl daemon-reload sudo systemctl start powerdns-network.service sudo systemctl start powerdns-db.service sudo systemctl start powerdns.service -
Verifizieren:
sudo podman ps sudo podman exec powerdns pdns_control ping dig @127.0.0.1 . NS +short # sollte antworten, auch ohne Zonen curl -s -H 'X-API-Key: <api-key>' http://127.0.0.1:8081/api/v1/servers/localhost
Zonen anlegen
Zonen werden wie bei jedem PowerDNS-Setup über pdnsutil (im Container)
oder die API verwaltet, z.B.:
sudo podman exec powerdns pdnsutil create-zone example.com ns1.example.com
sudo podman exec powerdns pdnsutil add-record example.com www A 10.0.0.10
Offen / noch zu prüfen
Analog zum Vorgehen bei den Matrix-Quadlets (Redmine #6) hier transparent dokumentiert, weil in dieser Session kein Podman und kein Internetzugriff auf die PowerDNS-Doku zur Verfügung standen:
- Nicht gegen echtes Podman getestet — nur strukturelle Prüfung der
Quadlet-Syntax. Vor dem produktiven Einsatz mit
podman-system-generator --dryrunbzw. einem echtensystemctl startauf dem Zielsystem verifizieren. - Image-Tag
docker.io/powerdns/pdns-auth-49:latestist eine Annahme. Bitte auf dem Zielsystem gegen die tatsächlich verfügbaren Tags auf Docker Hub / doc.powerdns.com prüfen und auf eine konkrete Version pinnen (nichtlatest), bevor produktiv geschaltet wird. - Mount-Pfad
/etc/pdns/pdns.confist der bei den offiziellen PowerDNS-Images übliche Konfigurationspfad, kann sich aber je nach gewähltem Image unterscheiden — bitte gegen die Image-Doku prüfen. - Postgres-Schema (
postgres-init/01-pdns-gpgsql-schema.sql) basiert auf dem seit Jahren stabilen gpgsqlbackend-Schema von PowerDNS, konnte in dieser Session aber nicht gegen die aktuelle Doku (https://doc.powerdns.com/authoritative/backends/generic-postgresql.html) gegengeprüft werden. Vor dem ersten Start kurz diffen. - DNSSEC ist im Backend aktiviert (
gpgsql-dnssec=yes), es werden aber noch keine Keys erzeugt/verwaltet — folgt bei Bedarf in einem eigenen Ticket. - SELinux-Mount-Labels (
:Z) sind bereits gesetzt (Lehre aus #6, wo das bei den Matrix-Quadlets nachträglich ergänzt werden musste). - Exposition/Firewall: Port 53 (UDP+TCP) geht direkt auf den Host-Port,
die Web-API bewusst nur auf
127.0.0.1:8081. Falls die API von außen (z.B. über die WAF wie bei #6 geplant) erreichbar sein soll, muss das noch angepasst werden.