yann.verry.org/content/posts/dns/dnsupdate/index.md
2022-05-28 22:17:41 +02:00

3.9 KiB

+++ title = "Un peu de dynamic dans mon DNS" date = 2022-05-28T18:40:11+02:00 draft = false categories = ["dns"] tag = ["dns"] +++

Aujourd'hui notre monde informatique fonctionne quasi à 100% en API. Les serveurs DNS n'en font pas exception, par exemple avec PowerDNS sans surprise il éxiste une API mais explorons ce qui marche très bien depuis des années : DNSUpdate avec sa petite RFC2136.

DynDNS

En 2022 beaucoup d'ISP ne fournissent pas d'IPv4 ou IPv6 fixe. Elle change donc régulièrement au gré d'une coupure éléctrique ou plus de votre opérateur. Il éxiste beaucoup de service en ligne pour faire ce travail via une API, peut-être même votre registrar. Mais quand on héberge soit même son DNS il y a plus simple avec l'utilisation de nsupdate bien souvent déjà installé sur votre machine dès que vous avez besoin de creuser la question (dig). Sinon il est présent par exemple via le paquet bind9-dnsutils sous debian.

On va donc faire un tout petit script qui va obtenir son ipv4 et sa v6 public et les mettres à jours, ici sur le serveur dnsupdate.verry.org :

DOMAIN="verry.org"
HOST="raoul.verry.org"
ORIG_IPv4=$(dig +short a $HOST @dnsupdate.verry.org)
ORIG_IPv6=$(dig +short aaaa $HOST @dnsupdate.verry.org)
IPv4=$(curl -4 https://ip.verry.org)
IPv6=$(curl -6 https://ip.verry.org)
SERVER=$(dig +short aaaa dnsupdate.verry.org)

if [ "$ORIG_IPv4" != "$IPv4" ] || [ "$ORIG_IPv6" != "$IPv6" ];
then

nsupdate -y '<algo ici hmac-sha512>:<tsig name>:<ma clef TSIG base64>' <<!
server $SERVER 53
zone $DOMAIN
update delete $HOST. A
update delete $HOST. AAAA
update add $HOST. 3600 A $IPv4
update add $HOST. 3600 AAAA $IPv6
send
!

fi

Let's Encrypt

Un second cas d'usage que j'utilise est l'obtention de certificat let's encrypt via un challenge DNS. Mon ACME à moi est encore une fois quelque chose de simple mais de robuste : dehydrated

Avec dehydrated il est possible de faire un hook dans la config HOOK=/etc/dehydrated/hook/hook.sh.

Ce script fait appel à deux fonctions qui nous interesse deploy_challenge() :

deploy_challenge() {
  nsupdate -y '<algo ici hmac-sha512>:<tsig name>:<ma clef TSIG base64>' <<!
  server fd00::42:3 53
  zone ${DOMAIN}
  update add _acme-challenge.${DOMAIN} 60 TXT ${TOKEN_VALUE}
  send
  !
  
  sleep 3
}

et clean_challenge() :

clean_challenge() {
  nsupdate -y '<algo ici hmac-sha512>:<tsig name>:<ma clef TSIG base64>' <<!
  server fd00::42:3 53
  zone ${DOMAIN}
  update delete _acme-challenge.${DOMAIN} TXT ${TOKEN_VALUE}
  send
  !
}

Le serveur DNS (dnsupdate.verry.org) est fd00::42:3 en ipv6 privée (via un tunnel vpn wireguard)

Setup

Passons au setup serveur side maintenant. Sans surprise je vais vous montrer comment on fait avec PowerDNS.

TSIG

Tout les échanges s'éffectuent de manière sécurisé avec TSIG RFC2845

Il faut la générer sur votre master en précisant l'algorithme hmac-sha512 et un nom :

pdnsutil generate-tsig-key tsig.verry.org hmac-sha512

On peut finement autorisé domaine par domaine le droit que nous allons mettre sur cette clé, par exemple le droit de faire des modifications dans la zone (dnsupdate) ou de transférer cette zone (axfr).

pdnsutil show-zone verry.org

côté metadata on peut voir:

Zone has following allowed TSIG key(s): tsig.verry.org
Metadata items:
	TSIG-ALLOW-AXFR	tsig.verry.org
	TSIG-ALLOW-DNSUPDATE	tsig.verry.org

DNSUpdate

Ajoutons l'autorisation de faire des dnsupdate en whitelistant une IP. Dans /etc/powerdns/pdns.d/dnsupdate.conf :

allow-dnsupdate-from=::/0
dnsupdate=yes

Un petit restart de powerdns et tada !

Liens