PowerDNS mit PowerDNS-Admin auf Debian 12 mit MariaDB

In dieser Anleitung installieren wir PowerDNS mit PowerDNS-Admin als WebGUI auf einem Debian 12. Als Backend kommt eine MariaDB zum Einsatz.

1. Als erstes installieren wir uns ein paar Dinge die wir brauchen:

$ sudo apt update
$ sudo apt -y install dnsutils curl gnupg gnupg1 gnupg2 git

2. MariaDB für PowerDNS intallieren/vorbereiten

Maria DB installieren:

$ sudo apt -y install mariadb-server
$ sudo mariadb-secure-installation
Enter current password for root (enter for none): ENTER
Switch to unix_socket authentication [Y/n]: n + ENTER
Change the root password? [Y/n] ENTER
New password: PASSWORT + ENTER
Re-enter new password: PASSWORT + ENTER
Remove anonymous users? [Y/n] ENTER
Disallow root login remotely? [Y/n] ENTER
Remove test database and access to it? [Y/n] ENTER
Reload privilege tables now? [Y/n] ENTER

# Oder in kurz: -> Enter, n Enter, Enter [new Password] Enter [Re-Enter new Password], Enter, Enter, Enter, Enter

PowerDNS Datenbank anlegen, Datenbank Benutzer erstellen und Rechte gewähren.

$ mysql -u root -p <<< '
CREATE DATABASE powerdns;
GRANT ALL ON powerdns.* TO "powerdns"@"localhost" IDENTIFIED BY "strongpassword";
FLUSH PRIVILEGES;'

3. systemd-resolved abschalten

Debian 12 hat standardmäßig systemd-resolved auf Port 53 laufen. Den müssen wir erst einmal abschalten:

$ sudo systemctl stop systemd-resolved
$ sudo systemctl disable systemd-resolved
# Die nächsten beiden Befehle sind in einem Container unter Proxmox nicht notwendig
$ sudo unlink /etc/resolv.conf 
$ echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf

4. Installation/Konfiguration von PowerDNS

$ sudo apt -y install pdns-server pdns-backend-mysql

Ist der Server installiert, konfigurieren wir PowerDNS, dass er die Datenbank als Backend nutzt.
Hierfür legen wir die Datei /etc/powerdns/pdns.d/pdns.local.gmysql.conf mit folgendem Inhalt an:

# MySQL Configuration
# Launch gmysql backend
launch+=gmysql
# gmysql parameters
gmysql-host=localhost
gmysql-port=3306
gmysql-dbname=powerdns
gmysql-user=powerdns
gmysql-password=strongpassword
gmysql-dnssec=yes

Jetzt kann die Datenbankstruktur erstellt werden:

$ mysql -u root -p powerdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql

Um später mit PowerDNS-Admin auf unseren PowerDNS zugreifen zu können, müssen wir die API noch aktivieren und einen API-Key hinterlegen. Hierfür öffnen wir die Datei /etc/powerdns/pdns.conf und ändern folgende Einträge:

api=yes
api-key=verysecurekey

Und starten den PowerDNS-Dienst neu:

$ sudo systemctl restart pdns.service

 5. Installation von PowerDNS-Admin als WebGUI

Erstmal brauchen wir ein paar Packages:

$ sudo apt -y install python3-dev python3-venv python3-pip
$ sudo apt -y install default-libmysqlclient-dev python3-mysqldb libsasl2-dev libffi-dev libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev pkg-config libpq-dev

Yarn installieren:

$ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/yarnkey.gpg
$ echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
$ sudo apt update $ sudo apt -y install yarn

Als nächstes holen wir uns die aktuellste Version von PowerDNS-Admin und wechseln in das Verzeichnis:

$ repo="PowerDNS-Admin/PowerDNS-Admin"
$ url="https://github.com/${repo}/releases/latest"
$ latest_version=$(curl -s -I $url | awk -F '/' '/^location/ {print substr($NF, 1, length($NF)-1)}')
$ sudo git clone https://github.com/PowerDNS-Admin/PowerDNS-Admin /opt/powerdns-admin
$ cd /opt/powerdns-admin
$ sudo git checkout $latest_version

Dann erstellen wir uns eine VirtualEnv und installieren die Abhängigkeiten, die wir brauchen:

$ sudo python3 -m venv flask
$ sudo flask/bin/pip install -r requirements.txt

Nun bearbeiten wir die Datei powerdnsadmin/default_config.py und ändern die Einträge unter DATABASE CONFIG auf unsere Datenbank-Zugangdaten, entfernen den Kommentar bei SQLALCHEMY_DATABASE_URI für die MySQL-Verbindung und setzen ein Kommentarzeichen vor die sqlite Zeile:

SQLA_DB_USER = 'powerdns'
SQLA_DB_PASSWORD = 'strongpassword'
SQLA_DB_HOST = 'localhost'
SQLA_DB_NAME = 'powerdns'

### DATABASE - MySQL
SQLALCHEMY_DATABASE_URI = 'mysql://{}:{}@{}/{}'.format(
    urllib.parse.quote_plus(SQLA_DB_USER),
    urllib.parse.quote_plus(SQLA_DB_PASSWORD),
    SQLA_DB_HOST,
    SQLA_DB_NAME
) ### DATABASE - SQLite
#SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'pdns.db')

Für die nächsten Schritte brauchen wir eine Umgebungsvariable, die root aber mit einem sudo nicht zur Verfügung steht. Daher machen wir uns jetzt ein wenig länger zu root:

$ sudo -s

Dann bereiten wir unsere Datenbank für PowerDNS-Admin vor.

$ export FLASK_APP=powerdnsadmin/__init__.py
$ flask/bin/flask db upgrade
$ flask/bin/flask db migrate -m "Init DB"

 Installieren der benötigten Pakete und generieren der asset-Dateien:

$ apt -y install npm
$ yarn install --pure-lockfile $ flask/bin/flask assets build

 Nun können wir PowerDNS-Admin zum testen einmal starten:

$ flask/bin/python3 run.py

Der PowerDNS-Admin sollte jetzt unter http://Server-IP:9191 erreichbar sein.

Klickt unten auf der Loginseite auf Create an account um einen Account zu erstellen und loggt euch anschließend mit dem Account ein.

Nun werdet ihr aufgefordert, die PDNS Config fertig zu stellen.

Hier tragt ihr folgendes ein:

PowerDNS API URL: http://127.0.0.1:8081

PowerDNS API KEY: (Euren API-Key. Haben wir vorhin unter Schritt 3. in die /etc/powerdns/pdns.conf eingetragen)

Und unten auf den Button Save Settings klicken.

Um zu verhindern, dass weitere Benutzer sich einen Account erstellen können, stellen wir noch die Selbstregistrierung ab:

Dazu entfernen wir den Hacken bei:

Settings -> Authentication -> Local Authentication Settings -> Allow users to sign up

Und drücken auf Save Settings

Auf der Kommandozeile könnt ihr den Server jetzt mit Strg+C stoppen und exit eingeben um die root-Shell wieder zu verlassen.

6. PowerDNS-Admin als Dienst im systemd registrieren

Zuerst erstellen wir uns einen Benutzer, unter dem der Dienst später läuft:

$ sudo adduser --system --group --no-create-home --shell /bin/false pdns-admin

Dann legen wir unsere systemd-Service-Datei /etc/systemd/system/powerdns-admin.service mit folgendem Inhalt an:

[Unit]
Description=PowerDNS-Admin
After=network.target

[Service]
PIDFile=/run/powerdns-admin/pid
User=pdns-admin
Group=pdns-admin
WorkingDirectory=/opt/powerdns-admin
ExecStart=/opt/powerdns-admin/flask/bin/gunicorn --workers 1 --pid /run/powerdns-admin/pid --bind 0.0.0.0:9191 'powerdnsadmin:create_app()'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Jetzt braucht der Benutzer noch das Recht, ein PIDFile unter /run anzulegen. Dazu legen wir die Datei /etc/tmpfiles.d/powerdns-admin.conf mit folgendem Inhalt an:

d /run/powerdns-admin 0755 pdns-admin root -

Und einmal manuell ausführen: 

$ sudo systemd-tmpfiles --create /etc/tmpfiles.d/powerdns-admin.conf

Eigentümer von vom PowerDNS-Admin Verzeichnis ändern:

$ sudo chown -R pdns-admin: /opt/powerdns-admin

Jetzt können wir den Dienst starten:

$ sudo systemctl start powerdns-admin.service

Zum Schluss aktivieren wir den Dienst noch, damit unsere WebGUI auch nach einem Neustart des Linux gestartet wird:

$ sudo systemctl enable powerdns-admin.service

Viel Spaß mit eurem neuen DNS-Server... ;-)

Peter
Peter 05.07.2024 16:25

Servus!

Ich hab deine Anleitung bereits ein paarmal durchspielt - scheitere aber dennoch.

1.) in powerdnsadmin/default_config.py fehlt oben "import urllib"

2.) nach dem Hinterlegen von API URL und API Key klicke ich dann auf Save Settings und bekomme ich dann:

HTTP 403 Error
Oops! Access Denied
You don't have permission to access this page You may return to the dashboard.

Hast du eine Idee, was ich falsch machen könnte - ich hab das auf einem frisch installierten Deb12 versucht.

Liebe Grüße
Peter

Danny
Danny 05.07.2024 22:33

Ja, die Version 0.4.2 hat ein paar Bugs auf Github. Habe ich auch schon gesehen. Hatte gehofft, dass das Entwicklerteam das Problem zügig fixt. Ist leider noch nicht geschehen. Den fehlenden Import kann noch recht leicht korrigiert werden. Zwei andere Bugs sind aber nicht so leicht mit einem Workaround zu fixen.

Würde dir für den Produktiveinsatz dann die Version 0.4.1 empfehlen.
Dafür kannst du in der Anleitung die Zeile "sudo git checkout $latest_version" durch "sudo git checkout v0.4.1" ersetzen.
Dort tritt das Problem nicht auf und wenn die 0.4.3 raus kommt, kannst du direkt auf diese wechseln.

Peter
Peter 08.07.2024 06:58

Servus Danny,

Zuerst mal herzlichen Dank fü den Hinweis - ja, das hat das Problem behoben. Auch dein Hinweis per Email, dass im requirements.txt PyYAML auf 6.0.1 war perfekt. Fazit: damit läuft das Ding nun. Letztendlich: toller Guide!

Martin Krüger
Martin Krüger 24.07.2024 15:40

Hallo

vielen Dank für den Hinweis, weißt du vielleicht wie ich den Bug mit DNSSEC Icon beheben kann?

Bei meiner 0.4.1 Version wird DNSSEC aktiviert, aber das Icon bleibt Rot.

MIt freundlichen Grüßen
Martin Krüger

Sascha
Sascha 08.09.2024 16:33

Echt super Anleitung, hat sofort geklappt :-)
Kannst Du eine Anleitung für das hinzufügen weitere DNS-Server anbieten?

LG Sascha

Neuen Kommentar hinzufügen

Sie können einen Kommentar abgeben, indem Sie das unten stehende Formular ausfüllen. Nur Text.

Ihre E-Mail-Adresse wird nicht veröffentlicht