Aller au contenu principal

Configurer un DNS avec PowerDns

· 4 minutes de lecture
Stéphane ROBERT
Consultant DevOps

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 :

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 :

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.

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 :

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 :

systemctl restart pdns

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

Powerdns-Admin le frontend de powerdns

Installons maintenant powerdns-Admin :

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 !) :

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 :

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 :

nginx -t
systemctl restart nginx

Maintenant créons les services et socket pdns :

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.