Testé avec Bind 9.7.3 sous Debian Squeeze, poste moniteur sous Debian Squeeze
De nombreuses connexions internet ADSL ou satellite ne disposent pas d’une adresse IP externe fixe. Dès lors qu’on veut installer un serveur derrière ce type de liaison ou mettre en place un accès distant, on utilise généralement des services de DNS dynamique tels que Dyn ou no-ip. Ces services restent très limités dans leur version gratuite.
L’idée est donc de pouvoir s’en passer en utilisant notre propre serveur DNS pour tenir à jour un enregistrement DNS du type monip.mondomaine.com qui pointera sur l’adresse IP externe courante de la connexion. L’enregistrement DNS sera mis à jour de façon sécurisée par l’utilitaire DNS nsupdate.
Pré-requis
- Un serveur DNS Bind 9.2 ou plus récent connecté directement à internet. Ce serveur doit être maître pour la zone qui contiendra l’enregistrement DNS choisi :
Pour l’enregistrementmonip.onsenfout.com
le serveur doit être maître pour la zoneonsenfout.com
. - Une machine linux derrière la connexion à surveiller, ici j’utilise un serveur Debian Squeeze. Je l’appelle poste moniteur dans la suite de l’article.
Préparation du poste moniteur
installer les utilitaires DNS
aptitude install bind9utils dnsutils
Générer la paire de clés TSIG
Il y a 2 méthodes pour sécuriser les mises à jours dynamiques du DNS : avec des clés TSIG ou avec des clés SIG(0). Les clés TSIG sont symétriques, la même clé est utilisée par le client et le serveur. A l’inverse, les clés SIG(0) sont asymétriques, ce qui est à priori plus sécurisé, mais la version actuelle de nsupdate dans Squeeze (dnsutils 1:9.7.3.dfsg-1~squeeze4
) plante avec les clés SIG(0). Je me suis donc rabattu sur TSIG en attendant que ça soit corrigé.
La clé sera générée avec dnssec-keygen:
dnssec-keygen -a HMAC-MD5 -b 512 -n HOST monip.onsenfout.com
On obtient deux fichiers :
Kmonip.onsenfout.com.+157+?????.private Kmonip.onsenfout.com.+157+?????.key
Le contenu du fichier Kmonip.onsenfout.com.+157+13642.private est le suivant :
cat Kmonip.onsenfout.com.+157+13642.private Private-key-format: v1.3 Algorithm: 157 (HMAC_MD5) Key: BXLFFCyzbVK1OxTu+3HaJ2YytB64Rxplat738Zk3UFWDeLtkfUYIwgbX83LYR5W6z7fRgGBcwgVD191KtOErMQ== Bits: AAA= Created: 20120404104934 Publish: 20120404104934 Activate: 20120404104934
C’est le moment de copier la valeur de la clé (après Key: ) dans le presse-papiers, on en aura besoin pour configurer le serveur DNS.
Configuration du serveur DNS
créer un fichier /etc/bind/keys.conf et y ajouter la clé publique :
key monip.onsenfout.com { algorithm HMAC-MD5; secret "BXLFFCyzbVK1OxTu+3HaJ2YytB64Rxplat738Zk3UFWDeLtkfUYIwgbX83LYR5W6z7fRgGBcwgVD191KtOErMQ=="; };
Editer /etc/bind/named.conf.local et inclure le fichier de clé :
include "/etc/bind/keys.conf";
Côté serveur il ne reste plus qu’à définir les autorisations de mise à jour de la zone. L’instruction update-policy va nous permettre d’autoriser la clé monip.onsenfout.com
à modifier l’enregistrement DNS de type A monip.onsenfout.com
, et seulement celui là :
zone "onsenfout.com" in { type master; file "db.onsenfout.com"; update-policy { grant monip.onsenfout.com. name monip.onsenfout.com. A; };
On redémarre Bind :
/etc/init.d/bind9 restart
Test de la mise à jour dynamique
Le serveur est prêt à recevoir des mises à jour dynamiques. Nous allons pouvoir vérifier que tout fonctionne en initialisant l’enregistrement DNS avec nsupdate
à partir du poste moniteur. La syntaxe de nsupdate est:
nsupdate -k <fichier clé privée> -v <fichier>
-v
force l’utilisation de TCP au lieu d’UDP
fichier
contient le jeu d’instructions à envoyer au serveur, s’il est omis nsupdate passe en mode interactif.
C’est ce qu’on va faire pour initialiser l’enregistrement monip.onsenfout.com
avec l’adresse 0.0.0.0 et un TTL de 30. La commande show
affiche la requète de mise à jour, send
l’envoie au serveur :
nsupdate -k Kmonip.onsenfout.com.+157+13642.private -v > zone onsenfout.com > update add monip.onsenfout.com. 30 A 0.0.0.0 > show Outgoing update query: ;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0 ;; flags:; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0 ;; ZONE SECTION: ;onsenfout.com. IN SOA ;; UPDATE SECTION: monip.onsenfout.com. 30 IN A 0.0.0.0 > send > quit
On vérifie que tout s’est bien passé en regardant les logs de Bind et en faisant un dig sur le serveur DNS :
dig +nocmd monip.onsenfout.com +noall +answer monip.onsenfout.com. 30 IN A 0.0.0.0
Le fichier journal
Après la première mise à jour dynamique, on s’aperçoit qu’un nouveau fichier db.onsenfout.com.jnl
a été créé dans le répertoire des fichiers de zones, /var/cache/bind/
chez moi. On constate aussi que la commande dig retourne bien l’enregistrement demandé, mais que celui-ci n’apparaît pas dans le fichier de zone : lors des mises à jour dynamiques, Bind modifie la zone chargée en mémoire, stocke l’information dans le fichier journal de la zone avec une extension .jnl
, et attend d’être peinard pour mettre à jour le fichier de zone. C’est un point important à prendre en compte si on doit éditer manuellement une zone comportant des enregistrements dynamiques.
Dans ce cas il faut suspendre les mises à jour de la zone et forcer l’écriture du journal avec rndc freeze
:
rndc freeze onsenfout.com
Editer la zone sans oublier d’incrémenter le numéro de série, rétablir les mises à jour et recharger la zone rndc thaw
:
rndc thaw onsenfout.com
Le fichier journal n’est pas directement lisible mais l’utilitaire named-journalprint remédie au problème.
Un p’tit script pour finir
Maintenant que tout fonctionne il ne manque plus qu’un script placé en crontab, toutes les minutes par exemple :
#!/bin/bash # Teste si l'ip publique a été modifiée et met à jour l'enregistrement DNS # Utilise la clé TSIG # François Grange 2012 # Inits ADMIN="[email protected]" ZONE="onsenfout.com" RR="monip.$ZONE." TTL=30 LAST_IP="0.0.0.0" LAST_IP_FILE="/var/local/lastip" FLAG_ERR=0 ERR_FILE="/var/local/dyndns.err" KEY_FILE="/etc/bind/keys/Kmonip.onsenfout.com.+157+13642.private" TMP_FILE="/tmp/dyndns.tmp" CUR_IP=`wget -q -O - whatismyip.org` sortie() { # mail si erreur ou modification if [ $1 -eq 1 ]; then if [ ! -f $ERR_FILE ]; then touch $ERR_FILE cat $TMP_FILE | mail -s "Erreur de mise à jour de $RR" $ADMIN fi else cat $TMP_FILE | mail -s "Changement d'IP pour $RR" $ADMIN if [ -f $ERR_FILE ]; then rm -f $ERR_FILE fi fi exit } if [ "$CUR_IP" = "" ] || [ "$CUR_IP" = "unknown" ]; then echo "Impossible de récupérer l'IP actuelle - Abandon" > $TMP_FILE sortie 1 fi if [ -f $LAST_IP_FILE ]; then LAST_IP=`cat $LAST_IP_FILE` fi if [ ! "$LAST_IP" = "$CUR_IP" ]; then # L'adresse a changé echo "IP actuelle : $CUR_IP" > $TMP_FILE echo "IP précédente : $LAST_IP" >> $TMP_FILE ( echo "zone $ZONE" echo "update delete $RR A" echo "update add $RR $TTL A $CUR_IP" echo "send" ) | nsupdate -k $KEY_FILE -v if [ $? -ne 0 ]; then echo "Echec de la mise à jour de $RR" >> $TMP_FILE FLAG_ERR=1 else echo $CUR_IP > $LAST_IP_FILE fi sortie $FLAG_ERR fi
Liens
Secure dynamic DNS howto
nsupdate: Painless Dynamic DNS
Mise en place d’un serveur DNS dynamique
Rating: 0.0/5 (0 votes cast)