+++
title = "Un peu de dynamisme dans mon DNS"
date = 2022-05-28T18:40:11+02:00
draft = false
categories = ["dns"]
tags = ["dns"]
author = "Yann Verry"
description = ""
+++

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 RFC[2136](https://datatracker.ietf.org/doc/html/rfc2136.html).

## 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** :

```bash
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](https://datatracker.ietf.org/doc/html/rfc8738) à moi est encore une fois quelque chose de simple mais de robuste : [dehydrated](https://github.com/dehydrated-io/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](https://datatracker.ietf.org/doc/html/rfc2845.html)

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

* https://doc.powerdns.com/authoritative/dnsupdate.html
* https://doc.powerdns.com/authoritative/tsig.html