DNS Overview
DNS is a UDP (optionally TCP) based client/server protocol using port 53 on
server side. There are mainly four
[There is also the now obsolete Invers Query, a Status message
type, and the quite new DSO (DNS stateful operations) opcode]
DNS-protocol messages types, each of it related to a dedicated application.
-
DNS Queries (recursive / non-recursive)
-
Zone transfer, full or incremental
-
Notify (A SOA query like DNS message)
-
DNS updates (Usually authenticated)
There are three different types of DNS name server:
-
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)
-
$ 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.
$ 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.
$ 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.
[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?
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.
$ 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.
[This is the most common mistake done by dns
admins: Forget to increment the serial number after a change in a zone]
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.
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)
-
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.
zone "example.net" {
type master; file "example.net.dyn";
max-zone-ttl 43200;
serial-update-method date;
update-policy {
// identity ruletype name types
grant ddns-key zonesub ANY ;
grant EX.NET krb5-self . A(1) AAAA(3) TXT(2) SSHFP(10) HIP(2) KEY(2) IPSECKEY(2);
grant * self . A(1) AAAA(3) TXT(2) SSHFP(10) HIP(2) KEY(2) IPSECKEY(2);
};
}
The maximum TTL value of the zone | |
Format of the SOA serial number, in this case: yyyymmddnn e.g. 2021052500
| |
The owner of the key "local-ddns" can change any record in the zone and all sub zones | |
Each Kerberos host principal of the realm "EX.NET" can add/del/modify the address, txt and several key resource records | |
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.
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
-
Shared secrets (TSIG) as already used for zone transfers
-
Asymmetric keys (SIG0) or
-
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.
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.
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 <keyfile>
The <keyfile< is the name of file withe the shared secret or the private part of an asymmetric (SIG0) keyfile.
For Kerberos authentication the option -g
of nsupdate
is used (take a
look at the ddnsupd
script for a more detailed explanation how gss
authentication works).
There are a lot more nsupdate commands available, but for adding or
deleting an IP address this is almost all what is needed.
If the nsupdate(1)
programm has difficulties to find the primary
authoritative server of a domain, than the server
command is useful.
Also setting a default ttl with e.g. ttl 18000
can be helpful if the
record doesn’t have a ttl value.
For a more detail explanation take a look at the man page of nsupdate(1)
.
Example
A real live example setup.
-
Install the BIND software
This is needed because thensupdate
(anddig
) command is part of the BIND distribution. Some Unix/Linux distros may have a separate DNS “client” package, e.g.bind9-dnsutils
.
This is sufficient on the dynamic dns clients where theddnsupd
script runs. -
Setup a BIND authoritative name server
There are a lot of HowTo’s in the internet explaining the setup of BIND -
Configure a domain for dynamic updates and reconfig your name server.
Here it is shown with the domainmip6.de
.# part of named.conf zone "mip6.de." in { type master; file "mip6.de.ddb"; allow-transfer { <your-secondary-server-list-acl>; }; max-zone-ttl 18000; // max ttl is 5h serial-update-method unixtime; // this is good for dynamic zones update-policy { grant <your-master-hmac-key-name> 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
-
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. -
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/
-
Create a SIG0 key on the client.
Make sure that your hostname is set correct. If not, use option-h
whenever you runddnsupd
.$ 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
-
Put the KEY record for the dynamic host into the domain
$ sed -e "s/^/add /" -e '$a send' Khost*.key |
> ssh ns1 nsupdate -k <your-master-hmac-key-file-name> $ dig +noall +answer KEY host.mip6.de host.mip6.de. 7165 IN KEY 16896 3 8 [key id = 35565]
This kind of sed
call works with GNU sed(1) onlyThe key material is suppressed here, because dig
runs with option+nocrypto
(set within~/.digrc
). -
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]