//				vim: set syntax=asciidoc textwidth=75:
Dynamic DNS Updates
===================
Holger Zuleger,  0.3, 18. May 2021  
:lang: en
:icons:
:data-uri:
include::{ldir}/attributes.adoc[]

== DNS Overview

DNS is a UDP (optionally TCP) based client/server protocol using port 53 on
server side.  There are mainly four DNS-protocol messages types, each of it
related to a dedicated application.

[style="arabic"]
. DNS Queries (recursive / non-recursive)
. Zone transfer, full or incremental
. Notify (A SOA query like DNS message)
. Usually authenticated DNS updates

There are three different types of DNS name server:

[style="lowerroman"]
. Authoritative name server (ANS) +
  These are the name servers hosting the content of a DNS domain (+zone+)
. Recursive name server (RNS), also called Resolver +
  These are used in the query process only
. Forwarding name server (mostly useless but widespread today) +
  Out of scope here.


== Queries

* The DNS query is the most used DNS message.
* UDP as transport protocol but also TCP is used, especially if the response
  packet is larger than the maximum DNS UDP packet size (512 minimum, now adjustable)
* Two query types:
  - recursive
  - iterative (non-recursive)
* Queries are send by
  - Stub resolvers (clients) as recursive query against recursive name server (RNS)
  - Resolver (RNS) as non-recursive query against authoritative name servers (ANS)

ifdef::backend-html5,backend-xhtml11[image::queries.svg[]]
ifndef::backend-html5,backend-xhtml11[]
include::queries.a2s[]
endif::[]

.Stub Resolver query (recursive) against recursive ns
----
$ dig  host.hznet.de @rns.hkn.hznet.de | grep -e "^host" -e ";; flags"

;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
host.hznet.de.          20776   IN      AAAA    2a01:4f8:150:92a9::2
----

The flags field in the message header shows that this is a query response
(+qr+) with recursion desired (+rd+) and recursioan available (+ra+) flag
on and DNSSEC validation successfull (+ad+).  dig(1) sets the +rd+ bit by
default.

.Resolver query (non-recursive) against the authoritative ns for the zone
----
$ dig  +norec host.hznet.de @ns1.hznet.de | grep -e "^host" -e ";; flags"

;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
host.hznet.de.          21600   IN      AAAA    2a01:4f8:150:92a9::2
----

Here the +rd+ bit is cleared and in the response the +aa+ bit
(authoritative answer) is set.

.Resolver query (non-recursive) against a ANS *not* responsible for the zone
----
$ dig  +norec host.hznet.de @a.nic.de | sed -n -e '/;; flags/p' -e '/^;; AUTH/,/^$/p'
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 3, ADDITIONAL: 5
;; AUTHORITY SECTION:
hznet.de.               86400   IN      NS      ns2.hznet.de.
hznet.de.               86400   IN      NS      ns1.hznet.de.
hznet.de.               86400   IN      NS      ns-ext.nlnetlabs.nl.
----

Because this name server is not authoritative for the domain in question, the
response has no answer (+ANSWER: 0+) but an authority section.
The authority section contains the full qualified domain names (FQDN) of
all authoritative name servers for the domain in question. +
That's the best information the +de.+ servers are aware of and is called a
delegation.
In the additional section (not shown here) the IP addresses of the name
servers are provided as long as space in the UDP packet is available.

== Zone Transfer

One authoritative name server per domain is not enough. A second or third
or even more name servers are usually configured as authoritative name
servers (ANS) for a domain. +
But only one of them manages the source file for the zone.

* This one is called the ``primary'' ANS.
* All other NS are named ``secondary'' ANS. footnote::[Formaly those were called
``Master'' and ``Slave'' server, but this is rather a racism term.]

How is the content of a zone synchronized between the authoritative  name
servers of a zone?

ifdef::backend-html5,backend-xhtml11[image::zone-transfer.svg[]]
ifndef::backend-html5,backend-xhtml11[]
include::zone-transfer.a2s[]
endif::backend-html5,backend-xhtml11[]

ifdef::false[]

	ANS		       NOTIFY (Serial 6)	ANS
	(primary)	    --------------------->	(secondary)

	In memory Zone:		  IXFR (diff 5->6)	In memory Zone:
	SOA  5 ....		<------------------>	SOA  5 ....
	horst   AAAA 2001:db8::1			horst   AAAA 2001:db8::1

	^
	|  reload

	Zonefile:
	SOA 6 ...
	horst   AAAA 2001:db8::2

endif::[]

.AXFR
To replicate the zone database (a plain text file) to all secondary NS, the
second DNS-protocol message format is used: A zone transfer (AXFR).

A zone transfer uses TCP as transport protocol, and is initiated by each
secondary NS at regular intervals (refresh time).
It starts always with a SOA serial number comparison.

The SOA serial number is an integer within the header of a zone used for
versioning of the zone.

.A SOA Record
=====
 $ dig +noall +answer SOA +multi hkn.hznet.de
 hkn.hznet.de.           6012 IN SOA ns1.hznet.de. hostmaster.hznet.de. (
                                2021051803 ; serial
                                43200      ; refresh (12 hours)
                                1800       ; retry (30 minutes)
                                1209600    ; expire (2 weeks)
                                900        ; minimum (15 minutes)
                                )
====
Whenever a change on the primary NS is made on a zone file, the serial
number MUST be incremented.  A zone transfer to a secondary NS takes place
only if the serial number on the primary is higher than the one on the
secondary NS.

.NOTIFY
To speed up the transfer of a zone to the secondaries, the DNS protocol is
supplemented by NOTIFY messages (RFC1996) to tell a secondary NS that
something has changed on the primary.

A Notify message is a bit like a SOA query for a zone, except that the DNS
opcode is +NOTIFY+ and that it is send by the authoritative primary server
to all secondary servers.
The secondary response to the NOTIFY ``query'' with a response to signal
that it is informed about the change.

The secondary NS initiate than a zone transfer in the same way as the
timely triggered zone transfer.

.IXFR
A second improvement made to the DNS protocol is a partial, so called
``incremental'' zone transfer (IXFR).

With IXFR only that part of a zone is transfered to the secondary which has
changed between the zone version on the secondary and the one on the
primary.
The primary holds a journal file to know what has been changed which each
version of the zone.

All this is needed to speed up the distribution of a zone change to all authoritative
name servers, and helps the third kind of DNS protocol messages.

== Updates

* Dynamic Update (RFC2136) is a mechanism to change the content of a zone
  via DNS messages.
* The destination of a DNS update message is always one of the
  authorititative NS (usually the master NS) of a zone.
* Dynamic updates use UDP or TCP as transport protocol The DNS messages
  opcode is 5 (UPDATE).
* These messages should use some kind of authentication (RFC3007).
  - Shared Secrets (TSIG HMAC or GSS-TSIG)
  - Public Keys (SIG0)

ifdef::backend-html5,backend-xhtml11[image::dyn-upd.svg[]]
ifndef::backend-html5,backend-xhtml11[]
include::dyn-upd.a2s[]
endif::[]

=== Policy

On the primary server, the zone is configured as dynamic zone and a
+update-policy+ directive defines who is allowed to update what kind of
resource.

.BIND Update policy
====
 zone "example.net" {
     type master;   file "example.net.dyn";
     max-zone-ttl 43200;			<1>
     serial-update-method date;			<2>
     update-policy {
         //   identity ruletype name types
         grant ddns-key zonesub      ANY ;			<3>
         grant EX.NET   krb5-self .  A(1) AAAA(3) TXT(2) SSHFP(10) HIP(2) KEY(2) IPSECKEY(2);	<4>
         grant *        self      .  A(1) AAAA(3) TXT(2) SSHFP(10) HIP(2) KEY(2) IPSECKEY(2);	<5>
     };
}
====

<1> The maximum TTL value of the zone
<2> Format of the SOA serial number, in this case:  +yyyymmddnn+ e.g. `2021052500`
<3> The owner of the key "local-ddns" can change any record in the zone and
    all sub zones
<4> Each Kerberos host principal of the realm "EX.NET" can add/del/modify the address,
    txt and several key resource records
<5> The same as above for TSIG HMAC and SIG0 keys

Beside a +grant+ permission also a +deny+ configuration is possible to
restrict a more general grant.

The +self+, +krb-self+ and +ms-self+ rules are almost identical and are
used to authenticate hosts via it's TSIG or SIG0 keyname, via it's Kerberos host
principal (+host/fqdn@REALM+) or via the Windows machine name (+fqdn$@REALM+).

If the ruletype in the grant directive above is changed from +self+ (or
+krb5-self+) to +selfsub+ (or +krb5-selfsub+ respectively) than the identiy
can also add subdomains of it's name (e.g. +horst.example.net+ can also add
an address or key for a name like +int1.host.example.net+).

The +zonesub+ directive allows the owner of the key with the name
+local-ddns+ to change anything in the zone.

The resource records are there to restrict the grant to specific record
types.
An number in parenthesis restricts the number of records of this type.

=== Authentication

There are primary three authentication mechanism available:

. Shared Secret
. Public Key
. Third party

The shared secret method requires the exchange of the key via a secure
channel and a configuration of the key on the primary name server and the
client as well.
The key is defined within the +named.conf+ file with a key directive.

.BIND key specification
====
 key "ddns-key" {
	algorithm hmac-sha256;
	secret "DwyeTCqKBHlSrkuTVphG9cfr8hMvzlDA8q8nPNQB0AE=";
};
====

A copy of this is placed in a file on the system from which +nsupdate+ will
be run.
The command +ddns-confgen+ generates a `hmac-sha256` key like this one.

In case of Public Key authentication the key could be generated with the
`dnssec-keygen` command.
----
$ dnssec-keygen -n HOST -T KEY -a RSASHA256 -b 2048 horst.example.net
Generating key pair......................+++++
................................................................+++++
Khorst.example.net.+008+00566

$ ls -l Khorst.example.net.+008+00566.*
-rw-rw-r-- 1 hoz hoz  389 Mai 25 18:49 Khorst.example.net.+008+00566.key
-rw------- 1 hoz hoz 1776 Mai 25 18:49
Khorst.example.net.+008+00566.private

$ cat Khorst.example.net.+008+00566.key
horst.example.net. IN KEY 512 3 8 AwEAAd5Oq0T/sOGAc.......ln2bX7tRnlE=
----

Now the public part of the key, the content of the file with extension
+.key+ must be placed into the zone in question.
The private key is then used by the +nsupdate+ command.

Kerberos is a third party authentication system.  All hosts and services
are added with a key to the Kerberos Key Distribution Center (KDC).  The
primary name server gets a service principal like +DNS/fqdn@REALm+ and
every host a host principal +host/fqdn@REALM+.

=== Updates

To send a update to 
