Aller au contenu

Configurer un DNS avec PowerDns

Il y a quelques mois, je vous proposais de mettre en place un serveur DNS sur un raspberry pi avec BIND. Mais voilà, bind ne possède pas d’api et de plugin terraform. J’aurais pu gérer Bind le faire avec Ansible, mais c’est ça ne serait pas très stable.

Je vais utiliser donc PowerDns qui possède aussi pas mal de plugins et surtout une interface d’administration. Voyons comment installer tout ça sur un raspberry pi, mais vous pouvez le transposer sur d’autres distributions.

Installation d’un serveur maître powerdns

Je ne vais installer qu’un serveur maître sur un raspberry Pi 3B+ avec hypriot comme système d’exploitation.

Commençons par enlever le service systemd-resolved pour paramétrer à la main le dns principale :

Terminal window
systemctl disable --now systemd-resolved
rm -rf /etc/resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf

Vous pouvez mettre à la place de 8.8.8.8 l’adresse ip du serveur de dns de votre box.

Installons tous les packages :

Terminal window
sudo su
curl -sL https://deb.nodesource.com/setup_14.x | bash -
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
apt update
apt install -y pdns-server mariadb-server pdns-backend-mysql nginx python3-dev libsasl2-dev libldap2-dev libssl-dev libxml2-dev libxslt1-dev libxmlsec1-dev libffi-dev pkg-config apt-transport-https virtualenv build-essential libmariadb-dev git python3-flask nodejs yarn

Configurons mysql et injectons le schéma de la base powerdns. Le mot de passe est password par défaut, changez le sans oublier de le noter dans votre gestionnaire de mot de passe.

Terminal window
mysql -u pdnsadmin -p pdns < /usr/share/pdns-backend-mysql/schema/schema.mysql.sql

Éditons la conf pdns pour y indiquer que nous utilisons mysql comme backend :

Terminal window
vi /etc/powerdns/pdns.conf

Vers la ligne 250 ajouter ces lignes, en changeant par vos informations :

Launch gmysql backend
launch+=gmysql
gmysql parameters
gmysql-host=127.0.0.1
gmysql-port=3306
gmysql-dbname=pdns
gmysql-user=pdnsadmin
gmysql-password=password
gmysql-dnssec=yes

Rechercher les lignes api et api-key et entrez-y ceci (changer le secret) :

api=yes
api-key=yourapisecretekey

Relançons pdns :

Terminal window
systemctl restart pdns

Voilà powerdns est en place, reste à installer le frontend powerdns-admin.

Powerdns-Admin le frontend de powerdns

Installons maintenant powerdns-Admin :

Terminal window
git clone https://github.com/ngoduykhanh/PowerDNS-Admin.git /var/www/html/pdns
cd /var/www/html/pdns/
vi /var/www/html/pdns/powerdnsadmin/default_config.py

Modifier les variables : SALT, SECRET_KEY SQLA_DB_* avec vos valeurs

## BASIC APP CONFIG
SALT = '$2b$12$yLUMTIfl21FKJQpTkRQXCu'
SECRET_KEY = 'yourapisecretekey'
BIND_ADDRESS = '0.0.0.0'
PORT = 9191
HSTS_ENABLED = False
OFFLINE_MODE = False
FILESYSTEM_SESSIONS_ENABLED = False
## DATABASE CONFIG
SQLA_DB_USER = 'pdnsadmin'
SQLA_DB_PASSWORD = 'password'
SQLA_DB_HOST = '127.0.0.1'
SQLA_DB_NAME = 'pdns'
SQLALCHEMY_TRACK_MODIFICATIONS = True

Lançons le build (attention, c’est long !) :

Terminal window
virtualenv -p python3 flask
source ./flask/bin/activate
pip install -r requirements.txt
export FLASK_APP=powerdnsadmin/__init__.py
flask db upgrade
yarn install --pure-lockfile
flask assets build
chown -R www-data: /var/www/html/pdns

Passons à la configuration de nginx :

Terminal window
vi /etc/nginx/conf.d/pdns-admin.conf
server {
listen *:80;
server_name _;
index index.html index.htm index.php;
root /var/www/html/pdns;
access_log /var/log/nginx/pdnsadmin_access.log combined;
error_log /var/log/nginx/pdnsadmin_error.log;
client_max_body_size 10m;
client_body_buffer_size 128k;
proxy_redirect off;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffers 32 4k;
proxy_buffer_size 8k;
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_headers_hash_bucket_size 64;
location ~ ^/static/ {
include /etc/nginx/mime.types;
root /var/www/html/pdns/powerdnsadmin;
location ~* \.(jpg|jpeg|png|gif)$ {
expires 365d;
}
location ~* ^.+.(css|js)$ {
expires 7d;
}
}
location / {
proxy_pass http://unix:/run/pdnsadmin/socket;
proxy_read_timeout 120;
proxy_connect_timeout 120;
proxy_redirect off;
}
}

On vérifie que nginx fonctionne et on redémarre nginx :

Terminal window
nginx -t
systemctl restart nginx

Maintenant créons les services et socket pdns :

Terminal window
cat > /etc/systemd/system/pdnsadmin.socket << 'EOF'
[Unit]
Description=PowerDNS-Admin socket
[Socket]
ListenStream=/run/pdnsadmin/socket
[Install]
WantedBy=sockets.target
EOF
cat > /etc/systemd/system/pdnsadmin.service << 'EOL'
[Unit]
Description=PowerDNS-Admin
Requires=pdnsadmin.socket
After=network.target
[Service]
PIDFile=/run/pdnsadmin/pid
User=pdns
Group=pdns
WorkingDirectory=/var/www/html/pdns
ExecStart=/var/www/html/pdns/flask/bin/gunicorn --pid /run/pdnsadmin/pid --bind unix:/run/pdnsadmin/socket 'powerdnsadmin:create_app()'
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOL
echo "d /run/pdnsadmin 0755 pdns pdns -" >> /etc/tmpfiles.d/pdnsadmin.conf
mkdir /run/pdnsadmin/
chown -R pdns: /run/pdnsadmin/
systemctl enable --now pdnsadmin.service pdnsadmin.socket

Il ne reste plus qu’à vous connecter à avec l’adresse ip de votre raspberry pi depuis votre navigateur et créer le compte admin avec un mot de passe.

Créer un domaine, moi j’ai pris ‘robert.local’ comme nom de domaine, et ajoutez-y votre raspberry avec comme nom ‘pdnsadmin’. Modifier votre conf nginx en conséquence et relancer le :

server_name pdnsadmin.robert.local;

Ensuite sur votre box ajouter l’adresse ip de votre raspberry dans la conf DHCP. Perso je le mets en premier.

À bientôt pour la suite avec packer.