128 lines
3.7 KiB
Markdown
128 lines
3.7 KiB
Markdown
|
+++
|
||
|
title = "A little dynamic in my DNS"
|
||
|
date = 2022-05-28T18:40:11+02:00
|
||
|
draft = false
|
||
|
categories = ["dns"]
|
||
|
tags = ["dns"]
|
||
|
author = "Yann Verry"
|
||
|
description = ""
|
||
|
+++
|
||
|
|
||
|
Today in the computer world almost *100%* works with API.
|
||
|
DNS servers are no exception, for example with PowerDNS without surprise there is an API but let's explore what works very well since years: **DNSUpdate** with its little RFC[2136](https://datatracker.ietf.org/doc/html/rfc2136.html).
|
||
|
|
||
|
## DynDNS
|
||
|
|
||
|
In 2022 many ISPs do not provide fixed *IPv4* or *IPv6*. So it changes regularly depending on a power cut or more from your operator.
|
||
|
There are many online services to do this job via an API, maybe even your registrar.
|
||
|
But when you host your own DNS, it is easier to use **nsupdate** which is often already installed on your machine when you need to dig into the question. Otherwise it is present for example via the *bind9-dnsutils* package under debian.
|
||
|
|
||
|
So we will make a small script that will get its ipv4 and v6 public and update them, here on the server **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
|
||
|
|
||
|
A second use case I use is to obtain a let's encrypt certificate via a DNS challenge. My own [ACME](https://datatracker.ietf.org/doc/html/rfc8738) is again something simple but robust: [dehydrated](https://github.com/dehydrated-io/dehydrated)
|
||
|
|
||
|
With dehydrated it's possible to add a hook in config `HOOK=/etc/dehydrated/hook/hook.sh`.
|
||
|
|
||
|
This script need to call two function `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
|
||
|
}
|
||
|
```
|
||
|
|
||
|
and `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
|
||
|
!
|
||
|
}
|
||
|
```
|
||
|
|
||
|
The DNS server (dnsupdate.verry.org) is `fd00::42:3` in private ipv6 address (vpn wireguard tunnel)
|
||
|
|
||
|
# Setup
|
||
|
|
||
|
Let's go to the server side setup now. Without surprise I will show you how it is done with PowerDNS.
|
||
|
|
||
|
### TSIG
|
||
|
|
||
|
All exchanges are done securely with *TSIG* [RFC2845](https://datatracker.ietf.org/doc/html/rfc2845.html)
|
||
|
|
||
|
You have to generate it on your *master* by specifying the algorithm **hmac-sha512** and a name:
|
||
|
|
||
|
```
|
||
|
pdnsutil generate-tsig-key tsig.verry.org hmac-sha512
|
||
|
```
|
||
|
|
||
|
We can finely authorize domain by domain, the right that we will put on this key, for example the right to make changes in the zone (dnsupdate) or to transfer this zone (axfr).
|
||
|
|
||
|
```
|
||
|
pdnsutil show-zone verry.org
|
||
|
```
|
||
|
On the metadata side we can see:
|
||
|
```
|
||
|
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
|
||
|
|
||
|
Let's add the authorization to do *dnsupdate* by whitelisting an IP.
|
||
|
In `/etc/powerdns/pdns.d/dnsupdate.conf` :
|
||
|
|
||
|
```
|
||
|
allow-dnsupdate-from=::/0
|
||
|
dnsupdate=yes
|
||
|
```
|
||
|
A small restart of powerdns and tada!
|
||
|
|
||
|
|
||
|
# Link
|
||
|
|
||
|
* https://doc.powerdns.com/authoritative/dnsupdate.html
|
||
|
* https://doc.powerdns.com/authoritative/tsig.html
|