Serveur DNS : PowerDNS (Serveur Web sur Debian Lenny)

Publié le

UPDATE : voir la version à jour pour Debian Squeeze.

 

J'ai choisi PowerDNS plutôt que Bind parce que sa configuration peut se faire de différentes façons. J'ai choisi d'utiliser MySQL. On désinstalle donc bind avant d'installer PowerDNS :

apt-get remove bind9
apt-get install pdns-server pdns-backend-mysql pdns-recursor

PowerDNS est découpé de deux façon différentes et indépendantes : le serveur qui permet de définir vos zones (vos sites, sous-domaines, etc...) et le recursor qui permet d'effectuer des requêtes DNS vers l'extérieur.

Configurons d'abord le serveur DNS dans /etc/powerdns/pdns.conf :

allow-axfr-ips=217.70.177.40
allow-recursion=127.0.0.1
disable-axfr=no
cache-ttl=300
launch=gmysql
logging-facility=0
out-of-zone-additional-processing=yes
query-cache-ttl=300
recursive-cache-ttl=150
recursor=127.0.0.1:54

Les paramètres avec axfr sont utilisé pour autoriser les transfert de zones vers l'IP 217.70.177.40, qui n'est autre que ns6.gandi.net, le DNS secondaire des domaines que j'utilise. De cette façon, lorsque je fait une mise à jour de mes DNS sur mon serveur, Gandi vérifie régulièrement la version de mon paramètrage et met à jour ses DNS si besoin.
On paramètre bien sûr du cache pour ne pas rappeler tout le temps les mêmes requêtes MySQL. On sélectionne le backend mysql avec le paramètre launch, active les log en précisant le logging-facility à 0 (cf plus bas) et en indiquant l'adresse du recursor. Recursor que l'on configure tout de suite dans /etc/powerdns/recursor.conf :

allow-from=127.0.0.1
local-address=127.0.0.1
local-port=54
logging-facility=1

On le lance sur le port 54, en n'autorisant les requêtes que locales et en logant les fichiers via logging-facility 1.

Mais qu'est ce que ces logging-facility ? Il s'agit en fait d'utiliser le démon rsyslog fourni avec Debian pour loggé les fichiers. Les logs seront en fait crée sous le nom localN, où N est le numéro que nous avons indiqués. Il faut donc paramétrer rsyslog pour gérer ces fichiers :

echo "local0.*  /var/log/pdns.log" > /etc/rsyslog.d/pdns.conf
echo "local1.*  /var/log/pdns-recursor.log" >> /etc/rsyslog.d/pdns.conf

Dans le même temps, paramétrons ces log pour ne pas qu'ils fassent une taille énorme via le proccessus des logrotate. Pour ce fait, ajouter simplement dans /etc/logrotate.d/rsyslog les lignes suivantes, juste après /var/log/messages

/var/log/pdns.log
/var/log/pdns-recursor.log

On recharge rsyslog pour être tranquille avec les logs :

/etc/init.d/rsyslog force-reload

Mais maintenant, il reste encore à paramétrer le backend MySQL pour exécuter les requêtes correctes sur le serveur. Et pour faire ça, il faut qu'une base de données soit prête pour contenir toutes les informations nécessaires. Appelons (et créons) cette base serverconf :

mysqladmin -p create serverconf

Comme le schéma de la base est assez simple, je ne vais pas le décrire ici. Vous pouvez simplement télécharger le fichier de création.
Ce fichier créé aussi l'utilisateur associé et son mot de passe. A vous de modifier... Exécutons simplement ce script :

mysql -h localhost -u root --password=MySQL serverconf < /PATH/TO/powerdns.sql

Enfin, éditons le fichier /etc/powerdns/pdns.d/pdns.local pour paramétrer la connexion et toutes les requêtes du serveur DNS :

gmysql-socket=/var/run/mysqld/mysqld.sock
gmysql-dbname=serverconf
gmysql-user=serverconfuser
gmysql-password=serverconfpass

gmysql-basic-query=select content,ttl,prio,type,domain_id,name from record where type='%s' and name='%s'
gmysql-id-query=select content,ttl,prio,type,domain_id,name from record where type='%s' and name='%s' and domain_id=%d
gmysql-any-query=select content,ttl,prio,type,domain_id,name from record where name='%s'
gmysql-any-id-query=select content,ttl,prio,type,domain_id,name from record where name='%s' and domain_id=%d
gmysql-list-query=select content,ttl,prio,type,domain_id,name from record where domain_id=%d
gmysql-master-zone-query=select master from domainDNS where name='%s' and type='SLAVE'
gmysql-info-zone-query=select domain_id AS id,name,master,last_check,notified_serial,type from domainDNS where name='%s'
gmysql-info-all-slaves-query=select domain_id AS id,name,master,last_check,type from domainDNS where type='SLAVE'
gmysql-supermaster-query=select account from supermaster where ip='%s' and nameserver='%s'
gmysql-insert-slave-query=insert into domainDNS (type,name,master,account) values('SLAVE','%s','%s','%s')
gmysql-insert-record-query=insert into record (content,ttl,prio,type,domain_id,name) values ('%s',%d,%d,'%s',%d,'%s')
gmysql-update-serial-query=update domainDNS set notified_serial=%d where id=%d
gmysql-update-lastcheck-query=update domainDNS set notified_serial=%d where id=%d
gmysql-info-all-master-query=select domain_id,name,master,last_check,notified_serial,type from domainDNS where type='MASTER'
gmysql-delete-zone-query=delete from record where domain_id=%d
gmysql-wildcard-query=select content,ttl,prio,type,domain_id,name from record where type='%s' and name like '%s'
gmysql-wildcard-id-query=select content,ttl,prio,type,domain_id,name from record where type='%s' and name like '%s' and domain_id=%d
gmysql-wildcard-any-query=select content,ttl,prio,type,domain_id,name from record where name like '%s'
gmysql-wildcard-any-id-query=select content,ttl,prio,type,domain_id,name from record where name like '%s' and domain_id=%d

Et on finit par recharger les deux démons :

/etc/init.d/pdns-recursor force-reload
/etc/init.d/pdns force-reload


Prêt pour passer au plus gros, le serveur de mail ?

Retour au sommaire.