NAME

wtdns - What the DNS?

SYNOPSIS

WtDNS is a master DNS server coupled with utilities for maintaining adynamic DNS system.

DESCRIPTION

WtDNS is a system that consists of a small authoritative DNS server (WtDNSd), a DNS record updater that gets updates requests via a webserver (or something else) without having to be started for each update request and a DNS record maintainer that replaces or deletes records when they haven’t been update for a set duration.

WtDNSd works with zone records stored on a one-type-per-file basis, wich makes it simple to configure, easy to update, and efficient for systems with very frequent updates (such as a dynamic DNS service). You do not have to restart, reload or refresh WtDNSd for updates since any updates are immediately available in the file system. WtDNS is not a caching or recursive DNS server and has no built in resolver.

The DNS resource records are stored in files named

/var/lib/wtdns/#XX/fqdn.hostname.domain/TYPE

or (when not using hashes)

/var/lib/wtdns/fqdn.hostname.domain/TYPE

where fqdn.hostname.domain is a lower case full domain name, or an IP address for PTR lookups, XX is a upper case hexadecimal hash of the domain name, and TYPE is a upper case DNS RR type. An entry such as “*.example.com” will return results as expected.

The records can be created with the wtdnsadd utility, or edited with a text editor. The wtdnshash utility can be used to create and find the directories, or alternatively WtDNS can be told to omit the hash part of the path.

WtDNSd does not do error checking on the records and will answer with their contents even if they are bogus as long as it manages to format them according to the standards.

Lookups

WtDNSd does lookups in lower case. All host name directories and and host names in file contents must be in lower case. File base names (query types) are in upper case.

Wild card records are specified by creating a record for a hostname where the first part is an asterisk ‘*’. A record for “*.example.com” will be served for “one.example.com”, “other.example.com” etc, unless they have the record in question.

wtdnsd considers itself authoritative for all domain names for wich it can locate an an SOA record. For both NS and SOA records, an entry for a domain is valid for all domains below it. For example, if you create an SOA record for the domain example.edu, then that SOA record is used for the domain www.example.edu, ftp.henry.example.edu, as well as user1.lab.chemistry.example.edu. On the other hand a separate SOA record can be created for lab.chemistry.example.edu, applying to all domains “*.lab.chemistry.example.edu”, “*.*.lab.chemistry.example.edu” etc. This works because when checcking or adding to the authority section, WtDNSd searches for NS and SOA records by iteratively deleting the text up to the front most-dot until a nameserver is found.

Message Size

If not using EDNS, WtDNSd does not send UDP results longer than the mandated 512 bytes. If using EDNS, WtDNSd does not send unsecure UDP results longer 1280 bytes or secured DNS records longer than 4096 bytes.

WtDNSd does not send results longer than 4096 bytes over TCP.

If there is too much data to fit in the message, then trailing records are omitted to keep within the limit, and the packet format will be valid. Administrators should ensure that their site is not so complex that large packets need to be sent.

WtDNSd does not serve recieved UDP or TCP messages longer than 1280 bytes. If a received message is too long, WtDNSd answers “refused”.

Zones

WtDNSd has no concept of zones. The system simply serves (autoritatively) whatever records it finds in tne record store, wether it really should be responsible for the domain or not.

Since WtDNS has no concept of zones, WtDNSd cannot do zone transfers. A slave WtDNSd can be kept in sync using an efficient file syncronizer such as rsync. Since WtDNSd serves records from disk, it is very suitable for this. For fast slave syncronization, a file change monitor such as Lsyncd can be used.

DNSSEC

WtDNS supports signing and serving for DNSSEC-bis. Signing can be done with the wtdnssign utility wich saves records in the format used by WtDNSd, or with other tools followed by manual conversion of the record formata.

DNSSEC processing automatically adds some records to responses from WTDNSd:

Resource record signatures

RRSIG RRs are added, if found, for each record in the response.

Next secure

NSEC RRs are added, if found, whenever an exact match for a domain name could not be found (including when a wildcard match was found). When looking for NSEC records, wtdnsd will only look in the domain and it’s parents. When using wtdnssign to sign a domain, a fake NSEC (in violation of strict DNSSEC) is created to avoid problems caused by this.

Delegation signer

DS RRs are added, if found, for SOA and NS record is included in the answers and authority sections.

Resource Records

Each resource record file contains one or more newline separated strings. There should be no leading newlines, and zero or one trailing newline. The maximum size of a resource file is 1024 bytes.

When records contain more than one, those fields can be separated by ’;’ and/or ’:’. A string can be enclosed in ‘“’,”’“,”[]" or “{}” to avoid separation. Enclosing ‘“’ and”’" will be stripped from the string, while “[]” and “{}” will be left where they are. To prevent any special characters from having any effect escape it with ’'. For example:

[field:one];" field;two"; field three:field four :{field\}five};field\\six:' field seven'

would give the following fields:

[field:one]
field;two
fieldthree
fieldfour
{field}five}
field\six
fieldseven
A records

In A records the strings are IPv4 addresses, for example “192.0.2.1”. You can have multiple lines per file. If there are several addresses in the file, they are order-randomized before return.

AAAA records

In AAAA records, the strings are IPv6 addresses, for example “2001:DB8:4F0B:1F1D:6795:941A:7E73:CFA6”. If no AAAA record file is found but there is an A6 record file, records with zero-length prefixes from the A6 record file are used. You can have multiple lines per file. If there are several addresses in the file, they are order-randomized before return.

A6 records

In A6 records, the strings are either IPv6 addresses or a prefix length, followed by a IPv6 address, followed by domain name, for example “2001:DB8:4F0B:1F1D:6795:941A:7E73:CFA6” or “8; 2001:DB8:4F0B:1F1D:6795:941A:7E73:CFA6; ns.example.net”. For obvious reasons the fields can not be separated with ’:’. If no A6 record file is found but there is an AAAA record file, records from the AAAA record file are used. You can have multiple lines per file. If there are several addresses in the file, they are order-randomized before return.

PTR and CNAME records

The string is a host-name. You must have only one entry in each file.

NS records

The strings are host-names. An entry for a domain is valid for all domains below it. You can have multiple lines per file.

MX records

The strings are host-names. You can have multiple lines per file. The first entry in the file is given a priority of 10, the second 20, and so on.

SRV records

The strings contains a hostname and port, for example “voip.example.com:5060”. You can have multiple lines per file. The first entry in the file is given a priority of 10, the second 20, and so on. All entries are given the weight 0.

SOA records

The string is a host-name, optionally followed by an email address. For example “ns.example.net” “ns.example.net:admin.example.com”. An entry for a domain is valid for all domains below it. You must have only one entry in each file.

The modified time of the file counts as the serial-number, and the contents as the name-server and administrator email address. If no email address has been specified, the address returned is just the name-server prepended with “hostmaster”. Any ‘@’ in the email address will be replaced with a ’.’. The remaining fields are hardcoded to reasonable default values. Note that time fields for SOA records are only used for zone transfers hence are irrelevant here.

TXT records

TXT records contain arbitrary text. When sent they will be split into chunks of at most 255 characters each. If a TXT record equals a macro string, it will be replaced with the expanded macro.

SPF records

SPF records are basically TXT records but must follow the SPF specifications and can’t contain macros.

HINFO records

A HINFO record should contain two fields, a CPU identifier followed by a system (OS) identifier.

DNSKEY records

A DNSSEC public key record contains four fields. The key flags, key protocol and key algorithm as decimal integers, followed by the key data encoded with Base64. Note that as with other records, the whole record must be on one line, so the Base64 data must not be line-broken. You can have multiple lines per file.

DS records

A DNSSEC delegation signer record contains four fields. The key tag and key algorithm, for the referenced key, and the digest type, as decimal integers, followed by the key digest in hexadecimal format. You can have multiple lines per file.

RRSIG records

A RRSIG record contains 8 fields. The key algorithm, the count of labels in the signed domain name and the TTL of the signed record as decimal integers, the spiration time and inception time in the format YYYYMMDDhhmmss, the key tag as a decimal integer and the key owner domain name, followed by the signature encoded with Base64. Note that as with other records, the whole record must be on one line, so the Base64 data must not be line-broken. RRSIG record file names differ from other records, being a concatenation combination of the signed records RR type and RRSIG separated with a’;’. You can have multiple lines per file.

TXT Macros

A TXT record (one line in a TXT record file) can be replaced with a macro. For this to be done the line must consist only and totally of the macro, wich has the following syntax:

%%wtdns:macrotag%%

where “macrotag” is the name of the macro. For a list of defined macros, see wtdnsd(8). There could be an example TXT record file with macros installed to your WtDNS documentations var directory.

PROGRAMS

wtdnsd(8)

The actual name server daemon that answer queries from remote systems.

wtdnsinfo(8)

Query a running wtdnsd for status infromation.

wtdnsadd(8)

Manually add resource records to the data store.

wtdnssign(8)

Sign record setss and zones according to DNSSEC-bis.

wtdns-fromlog(8)

A dynamic DNS updater intended to be used with an authenticating web server, but can be used with anything that can give it log lines in the correct format.

wtdns-maintain(8)

Deletes and replaces old records in the dynamic domain name system.

wtdnshash(8)

Find and create hash directories in the data store for host names.

wtdns-deepen(8)

Convert a data store not using hash directories to one using them.

wtdns-flatten(8)

Convert a data store using hash directories to one not using them.

FILES

/var/lib/wtdns

All resource records are stored in this directory.

/etc/wtdns/wtdns.ini

The global configuration file.

/etc/wtdns/apache.conf

Example configuration for dynamic DNS update service.

BUGS

If you find any, please send a report to jonas@truls.org.

NOTES

The WTDNS server and hasher is a fork of SheerDNS. SheerDNS was written by Paul Sheer.

Updated WtDNS packages could be available at http://whatever.truls.org/.

EXAMPLE

These examples show how you can create records manually, and serves as examples of how you may implement record creating in your own scrips. For more simple updating of records, you can use the wtdnsadd utility.

The examples assume that you have already invoked wtdnsd, that you know what kind of records are appropriate to create, that you do not guess, and that you realize that the examples are merely shown for demonstration and not as a recommendation for the kinds of records really required.

Add a wildcard entry for “*.example.com”. Note that quotes around the asterisk wich are needed because the filename has an asterisk in it:

echo 192.0.2.1 > /var/lib/wtdns/`wtdnshash '*'.example.com`/'*'.example.com/A
dig @localhost A lsdjkfhalsdfkjh.example.com

Add mutiple A records for “example.com” for round robin sharing:

echo 192.0.2.1 > /var/lib/wtdns/`wtdnshash example.com`/example.com/A
echo 192.0.2.2 >> /var/lib/wtdns/`wtdnshash example.com`/example.com/A
echo 192.0.2.3 >> /var/lib/wtdns/`wtdnshash example.com`/example.com/A
dig @localhost A example.com
dig @localhost A example.com
dig @localhost A example.com

Add a PTR records for “example.com”:

echo example.com > /var/lib/wtdns/`wtdnshash 192.0.2.1`/192.0.2.1/PTR
echo example.com > /var/lib/wtdns/`wtdnshash 192.0.2.2`/192.0.2.2/PTR
echo example.com > /var/lib/wtdns/`wtdnshash 192.0.2.3`/192.0.2.3/PTR
echo ns.example.net > /var/lib/wtdns/`wtdnshash 192.0.2`/192.0.2/NS
dig @localhost PTR 1.2.0.192.in-addr.arpa

Add an MX record for example.com with both its forward, reverse, and nameserver lookups:

echo mail.example.com > /var/lib/wtdns/`wtdnshash example.com`/example.com/MX
echo 192.0.2.99 > /var/lib/wtdns/`wtdnshash mail.example.com`/mail.example.com/A
echo mail.example.com > /var/lib/wtdns/`wtdnshash 192.0.2.99`/192.0.2.99/PTR
echo ns.example.net > /var/lib/wtdns/`wtdnshash example.com`/example.com/NS
dig @localhost MX example.com

Add an SOA record for “example.com” with the default administrator email address “hostmaster@example.net”, and one for “division.example.com” with administrator email address “divmaster@example.com”. Note that although SOA records are only required for zone transfers, some institutions may demand them. The only configurable data items in the SOA record are the authoritative nameserver and administrator email address, wich are inserted as follows:

echo ns.example.net > /var/lib/wtdns/`wtdnshash example.com`/example.com/SOA
echo ns.example.net:divmaster.example.com > /var/lib/wtdns/`wtdnshash division.example.com`/division.example.com/SOA
dig @localhost SOA example.com
dig @localhost SOA division.example.com

Add a CNAME record for “www.example.com”. If you use a CNAME, you should only have one line in the CNAME file, and it should be the only file in the domain’s directory, and the CNAME should not appear anywhere as the text of any other records.

# Remove existing records for www.example.com
rm -f /var/lib/wtdns/`wtdnshash www.example.com`/www.example.com/*
# Check if some other record points to www.example.com
grep -w 'www[.]test[.]com' `find /var/lib/wtdns/ -type f` && echo "This DNS setup is broken"
# Add the record
echo example.com > /var/lib/wtdns/`wtdnshash www.example.com`/www.example.com/CNAME
dig @localhost A www.example.com

Using WtDNS as a root nameserver. Note that for root domains, the hash is especially omitted:

> /var/lib/wtdns/NS
> /var/lib/wtdns/SOA
for i in  \\
 a:198.41.0.4     h:128.63.2.53     c:192.33.4.12     g:192.112.36.4    \\
 f:192.5.5.241    b:128.9.0.107     j:192.58.128.30   k:193.0.14.129    \\
 l:198.32.64.12   m:202.12.27.33    i:192.36.148.17   e:192.203.230.10  ; do
    N=`echo $i | cut -f1 -d:`.root-servers.net
    echo $i | cut -f2 -d: > /var/lib/wtdns/`wtdnshash $N`/$N/A
    echo $N >> /var/lib/wtdns/NS
    echo $N >> /var/lib/wtdns/SOA
done
dig @localhost SOA .
dig @localhost NS .

SEE ALSO

wtdns.ini(8), wtdnsinfo(8), wtdnsadd(8), wtdnssign(8), wtdnshash(8), wtdns-deepen(8), wtdns-flatten(8), wtdnsd(8), wtdns-fromlog(8), wtdns-maintain(8), dig(1)