--------------------------------------------------------------------- Dynamic DNS Updates --------------------------------------------------------------------- Holger Zuleger, 0.5, 11. June 2021 --------------------------------------------------------------------- Table of Contents 1. DNS Overview 2. Queries 3. Zone Transfer 4. Updates 4.1. Policy 4.2. Authentication 4.3. Updates 5. Example --------------------------------------------------------------------- 1. DNS Overview --------------------------------------------------------------------- DNS is a UDP (optionally TCP) based client/server protocol using port 53 on server side. There are mainly four ^[1] DNS-protocol messages types, each of it related to a dedicated application. 1. DNS Queries (recursive / non-recursive) 2. Zone transfer, full or incremental 3. Notify (A SOA query like DNS message) 4. DNS updates (Usually authenticated) There are three different types of DNS name server: i. Authoritative name server (ANS) These are the name servers hosting the content of a DNS domain (zone) ii. Recursive name server (RNS), also called Resolver These are used in the query process only iii. Forwarding name server (mostly useless but widespread today) Out of scope here. --------------------------------------------------------------------- 2. 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) .---------. .------. .-----. | | | | | | |hznet.de | | de | |root | ANS '---------' '------' '-----' ^ ^ ^ \ | / \ | / \ | / [iterative queries] \ | / | | | +-----------+ +---------------+ | | host.hznet.de AAAA | | | RNS | <--------------------> | Stub resolver | +-----------+ [recursive query] +---------------+ 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 recursion available (ra) flag on. DNSSEC validation was 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 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. --------------------------------------------------------------------- 3. 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. ^[2] How is the content of a zone synchronized between the authoritative name servers of a zone? ------=> +-----------+ / | | / ---=> +-----------+ | / / | | | +----------+ =-------- +-----------+ | | | |-------------->| | |-+ | ANS | NOTIFY snr 5 | ANS | | | primary |<--------------| secondary |-+ | |-------------->| | +----------+ AXFR|IXFR +-----------+ ^ | .--+--. | | |Zone | Serial |file | Number 5 |snr5 | '-----' 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. Example 1. 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. ^[3] 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. --------------------------------------------------------------------- 4. 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) +----------+ NOTIFY +-----------+ | |-------------->| | | ANS | | ANS | | primary |<--------------| secondary | | |-------------->| | +----------+ AXFR|IXFR +-----------+ ^ | +----+----+ | | .-------------------------------------------. |nsupdate | | | | |<-----|add h.example.net 7200 IN AAAA 2001:db8::e | | | |send | +---------+ '-------------------------------------------' 4.1. 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. Example 2. 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. host.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. 4.2. Authentication -------------- DNS data is typically public accessible. So everyone can send a query to an authoritative DNS server. If this is not intended the name server itself should not be reacheable. However, if the data is public, typically no authentication is needed for DNS queries. This is not necessarily the case for zone transfers. Here often the transfer of the whole data of the zone is restricted to a small number of hosts, mainly to the secondary servers. To achieve this, formerly ip access list where used, but nowadays the authorized server have to authenticates itself via TSIG shared keys. If we take a look at DNS updates, the situation is completely different. By default no one should be able to change the data within a zone. This is only allowed to entities which are able to authenticate itself. A policy says what changes are allowed for which entity. DNS uses three different authentication mechanism 1. Shared secrets (TSIG) as already used for zone transfers 2. Asymmetric keys (SIG0) or 3. third party authentication like Unix Kerberos or Windows Active Directory 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. Example 3. 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 can be used to generate a hmac-sha256 key like the example above. In case of asymmetric key authentication the key material could be generated with the dnssec-keygen command. $ dnssec-keygen -n HOST -T KEY -a RSASHA256 -b 2048 host.example.net Generating key pair......................+++++ ................................................................+++++ Khost.example.net.+008+00566 $ ls -l Khost.example.net.+008+00566.* -rw-rw-r-- 1 hoz hoz 389 Mai 25 18:49 Khost.example.net.+008+00566.key -rw------- 1 hoz hoz 1776 Mai 25 18:49 Khost.example.net.+008+00566.private $ cat Khost.example.net.+008+00566.key host.example.net. IN KEY 512 3 8 AwEAAd5Oq0T/sOGAc.......ln2bX7tRnlE= The outcome of the dnssec-keygen command is the public part of the key, stored in the file with the extension .key and the private key placed in the file with extension .private. The public part of the key is written as a KEY resource record and must be placed into the zone in question. The nsupdate client needs access to the private key file and uses this to authenticate itself. Kerberos, and so Windows Active Directory as well, 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 needs a service principal like DNS/fqdn@REALM and every host needs a host principal host/fqdn@REALM within the kerberos realm. The authentication takes place at the Key Distribution Center, and the primary DNS server has to check the policy only. 4.3. Updates -------------- To send an update to a primary nameserver the tool nsupdate, which is part of the BIND software distribution, is used. It reads from stdin the records to be updated. Each line with a resource record starts with the word add or delete. A newline or a line with the word send sends the update to the primary authoritative name server of the zone. $ { > echo "add host.example.net 7200 IN AAAA 2001:db8:10::5" > echo "send" > } nsupdate -k The ; }; max-zone-ttl 18000; // max ttl is 5h serial-update-method unixtime; // this is good for dynamic zones update-policy { grant zonesub ANY ; grant * self . A(0) AAAA(3) TXT(2) KEY(2) IPSECKEY(2); }; }; $ cat mip6.de.db $TTL 5h @ IN SOA ns1 hostmaster ( 1 ; Serial 86400 ; Refresh 1800 ; Retry 2W ; Expire 7200 ) ; Minimum IN NS ns1.hznet.de. // put your name servers here IN NS ns2.hznet.de. // add glue records if your ns are within the domain //ns1 IN A 192.0.0.2 //ns1 IN AAAA 2001:db8::53 $ cp mip6.de.db mip6.de.ddb $ rndc reconfig 4. Register the domain, so that the name server is delegated by the parent This is part of the domain registration process and depends on your registrar. 5. Download ddnsupd on the Linux or MAC OS/x client and move it to your bin directory $ wget https://www.hznet.de/tools/ddnsupd $ mv ddnsupd ~/bin/ 6. Create a SIG0 key on the client. Make sure that your hostname is set correct. If not, use option -h whenever you run ddnsupd. $ mkdir ~/keys $ cd ~/keys $ hostname host.mip6.de. $ ddnsupd createkey $ ls -l K* -rw-rw-r-- 1 hoz hoz 568 Mai 25 12:29 /home/hoz/keys/Khost.mip6.de.+008+35565.key -rw------- 1 hoz hoz 2459 Mai 25 12:29 /home/hoz/keys/Khost.mip6.de.+008+35565.private 7. Put the KEY record for the dynamic host into the domain $ sed -e "s/^/add /" -e '$a send' Khost*.key | (1) > ssh ns1 nsupdate -k $ dig +noall +answer KEY host.mip6.de host.mip6.de. 7165 IN KEY 16896 3 8 [key id = 35565] (2) (1) This kind of sed call works with GNU sed(1) only (2) The key material is suppressed here, because dig runs with option +nocrypto (set within ~/.digrc). 8. Use ddnsupd to add your current ip address $ ddnsupd showall mip6.de. 18000 IN SOA ns1.hznet.de. hostmaster.hznet.de. ( 1621949136 ; serial 43200 ; refresh (12 hours) 1800 ; retry (30 minutes) 1209600 ; expire (2 weeks) 7200 ; minimum (2 hours) ) host.mip6.de. 18000 IN KEY 16896 3 8 [key id = 35565] $ ddnsupd add $ ddnsupd showall mip6.de. 18000 IN SOA ns1.hznet.de. hostmaster.hznet.de. ( 1621949159 ; serial 43200 ; refresh (12 hours) 1800 ; retry (30 minutes) 1209600 ; expire (2 weeks) 7200 ; minimum (2 hours) ) host.mip6.de. 7200 IN AAAA 2003:2b:d31:5700:b34e:be2f:2c3d:69a2 host.mip6.de. 18000 IN KEY 16896 3 8 [key id = 35565] --------------------------------------------------------------------- ^[1] There is also the now obsolete Invers Query, a Status message type, and the quite new DSO (DNS stateful operations) opcode ^[2] Formaly those were called “Master” and “Slave” server, but this is rather a racism term. ^[3] This is the most common mistake done by dns admins: Forget to increment the serial number after a change in a zone