PowerDNS mit DNSSEC
Ich möchte gern meine eigenen DNS-Server nutzen und bin ungern auf „fremde“ Lösungen angewiesen. Aus diesem Grund habe ich mir PowerDNS mit PowerDNS-Admin angeschaut um eine für mich gute und auch praktikable Lösung zu haben.
Zuerst benötigen wir zwei Server, idealerweise in unterschiedlichen Rechenzentren. Meine Server befinden sich beide beim gleichen Hoster, also habe ich den ersten Schritt nicht optimal gelöst. Aber was nicht ist, kann ja noch werden. ;-)
Für meinen Anwendungsfall reichen mir zwei Server für je 1,–€ monatlich.
Die Server habe ich mit Debian 12 minimal installiert und dann weitestgehend abgesichert, indem ich
ufw
sowie Docker installiert habe. Das PowerDNS-Setup habe ich mit Docker-Containern realisiert.
Also, los geht´s: – PowerDNS Master
erstmal alles aktualisieren
apt update && apt upgrade -y
Docker installieren: Schritt 1 – Docker Repository einbinden
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
Schritt 2 – Docker installieren
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Schritt 3 – Verzeichnisse anlegen und docker-compose.yml anlegen. Ich habe dazu ein Verzeichnis /opt/pdns angelegt.
services:
mariadb:
image: bitnami/mariadb:10.4
volumes:
- mariadb-data:/bitnami/mariadb
environment:
MARIADB_ROOT_PASSWORD: 123123123123 #bitte abändern
MARIADB_DATABASE: pdns
MARIADB_USER: pdns
MARIADB_PASSWORD: 321321321321 #bitte abändern
MARIADB_REPLICATION_MODE: master
MARIADB_REPLICATION_USER: replicator
MARIADB_REPLICATION_PASSWORD: 456456456 #bitte abändern - wird für den Slave gebraucht
ports:
- 3306:3306
restart: unless-stopped
pdns:
image: psitrax/powerdns:v4.2
environment:
MYSQL_HOST: mariadb
MYSQL_DB: pdns
MYSQL_USER: pdns
MYSQL_PASS: 321321321321 #bitte anpassen (Zeile10)
MYSQL_DNSSEC: yes
MYSQL_AUTOCONF: "true"
ports:
- 53:53/tcp
- 53:53/udp
- 8081:8081
command:
- --api=yes
- --api-key=abcdefabcdef #bitte abändern
- --webserver-address=0.0.0.0
- --webserver-allow-from=0.0.0.0/0
- --gmysql-dnssec=yes
restart: unless-stopped
volumes:
- ./pdns.conf:/opt/pdns/pdns.conf
admin:
image: powerdnsadmin/pda-legacy:latest
environment:
SQLALCHEMY_DATABASE_URI: mysql://pdns:321321321321@mariadb/pdns #bitte das DB-Passwort anpassen (Zeile 10)
PDA_API_URL: http://pdns:8081/api/v1
PDA_API_KEY: abcdefabcdef #bitte abändern (Zeile 34)
volumes:
- admin-data:/data
ports:
- 8080:80
logging:
driver: json-file
options:
max-size: 50m
restart: unless-stopped
nginx:
image: nginx:latest
container_name: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./certs:/etc/nginx/certs
volumes:
mariadb-data:
driver: local
admin-data:
driver: local
Soweit so Gut. Was haben wir gemacht? Zum einen haben wir PowerDNS in den Container gepackt, PowerDNS -Admin, MariaDB sowie NGINX um das Backend schlussendlich SSL-gesichert aufrufen zu können.
Jetzt müssen wir uns noch um eine URL für das Backend kümmern sowie die Zertifikate beziehen.
wir erstellen im gleichen Verzeichnis noch eine nginx.conf
events {}
http {
server {
listen 80;
server_name pdns.meinedomain.de; #anpassen
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name pdns.meinedomain.de; #anpassen
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
location / {
proxy_pass http://pdns-admin:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
um die benötigten Zertifikate für unser Backend zu erhalten installieren wir im ersten Schritt certbot
apt install certbot
um dann mittels DNS-Challenge unser Zertifikat zu beziehen
certbot certonly --manual --preferred-challenges dns -d pdns.meinedomain.de
dabei folgen wir den Anweisungen von certbot.
Sobald wir die Zertifikate erfolgreich bezogen haben kopieren wir diese noch in die richtigen Verzeichnisse:
cp /etc/letsencrypt/live/pdns.meinedomain.de/fullchain.pem ./certs/
cp /etc/letsencrypt/live/pdns.meinedomain.de/privkey.pem ./certs/
Jetzt haben wir es fast geschafft, es fehlt noch ein letztes
docker compose up -d
und die images werden bezogen sowie die Container gestartet.
ABER
Wir müssen ja noch unseren SLAVE einrichten. Also einloggen auf dem zweiten Server, ebenfalls das Verzeichnis /opt/pdns erstellen und die folgende docker-compose.yml anlegen. Natürlich auch auf diesem Server zuerst docker installieren (siehe Schritt 1&2 ganz am Anfang)
services:
mariadb:
image: bitnami/mariadb:10.4
volumes:
- mariadb-data:/bitnami/mariadb
environment:
MARIADB_REPLICATION_MODE: slave
MARIADB_MASTER_HOST: 123.123.123.123 #IP des Master-Server
MARIADB_MASTER_ROOT_USER: root
MARIADB_MASTER_ROOT_PASSWORD: 123123123123 #anpassen an Master
MARIADB_REPLICATION_USER: replicator
MARIADB_REPLICATION_PASSWORD: 456456456 #anpassen an Master
restart: unless-stopped
pdns:
image: psitrax/powerdns:v4.2
# mariadb slave is readonly, so we cannot autoconfigure the database
environment:
MYSQL_AUTOCONF: "false"
# all database options must be passed as command args
# unless https://github.com/psi-4ward/docker-powerdns/blob/master/entrypoint.sh
# contains an option to disable schema updates only
command:
- --gmysql-host=123.123.123.123 # IP des Master-Server
- --gmysql-dbname=pdns
- --gmysql-user=pdns
- --gmysql-password=321321321321 #anpassen an den Master
- --gmysql-dnssec=yes
ports:
- 53:53/tcp
- 53:53/udp
restart: unless-stopped
volumes:
mariadb-data:
driver: local
auch hier noch ein abschließendes
docker compose up -d
und schon kannst Du dich über die URL
https://pdns.meinedomain.de
anmelden.

Jetzt noch „schnell“ einen Account erstellen (der erste Account ist automatisch der Admin-Account) und anschließend einloggen.
Aller Wahrscheinlichkeit musst noch im Backend die Zugangsdaten zur API hinterlegen. Den API-Key hast Du in der docker-compose.yml des Master-Server in Zeile 34 selbst vergeben ;-)

Viel Spaß mit deinem eigenen PowerDNS Setup!