Authoritative name server : nsd

You absolutely can host the authoritative server for your own zone, one step further to independence 😏. That is exactly the purpose of NSD available in OpenBSD base install.

Configuring NSD

To configure nsd, edit "/var/nsd/etc/nsd.conf".

server:
        hide-version: yes
        zonesdir: "/var/nsd/zones"
        ip-address: 192.168.1.2
        ip-address: 2001:db8:1:1::2
        debug-mode: no
        verbosity: 2
## master zones
zone:
        name: "athome.tld"
        zonefile: "master/athome.tld"

We will follow this structure : zones are categorized wether the server is authoritative (master) or secondary (slave). Each zone is a file with the name of the corresponding domain. As example "/var/nsd/zones/master/athome.tld". Or cours you can choose to do things differently i fyou prefer.

Do not forget to adjust the above example with your own IP.

Once setup, start nsd as usual :

rcctl enable nsd
rcctl start nsd

Remember to open (and redirect) port 53 (domain) UDP and TCP since it's used by nsd.

Once your nsd is up, you can set in the registrar your server's public ip in the list of authoritative servers for your zone.

An nsd example is available at the end of this documentation.

Sign a domain with DNSSEC

A few notes about DNS zone signing

DNSSEC requires two king of keys : ZSK (Zone Signing Key) light and short time living, and KSK (Key Signing Key) bigger with a long time usage.

Why such differences ?

It is recommended to renew KSK regularly -- about monthly, some do it weekly. However, it is quite annoying to update this monthly in the registrar.

That's why we created another kind of key to sign the firsts, but used only for this task. Those should be stronger, heavier since they are less used with a longer lifetime. Those will be recorded in the registrar.

Actually, we won't record KS in the registrar but a checksum instead in the upper zone. It's the same idea with each zone publishing their NS in the upper zone.

Keep in mind changes won't propagate instantly. There is TTL, lifetime and validity of keys and signatures, so you can't expect to see things working right away.

Especially, You must publish early keys that will be used in the near future. That's why many administrators have 2 ZSK in the meantime : one currently used and another that will be used when the first has expired. That's what we'll do below. KSK are also published in advande, however rarely two in the same time.

Setup with ldnscripts

Signing your DNS zone ensure its integrity.

You have to do it periodically since signature have an expiration date. You'll need a tool to sign and a bit of automation.

We will describe how to use ldnscripts designed for this task (thanks to 22decembre).

Note there are tools more complete/complicated such as OpenDNSSEC or KNOT.

With ldnscripts, you'll only need the package "ldns" :

# pkg_add ldns-utils

Automation relay on tools already available on OpenBSD, I mean scripts /etc/weekly, /etc/monthly...

Let's follow ldnscripts' author's intructions :

$ cd /tmp
$ ftp https://framagit.org/22decembre/ldnscripts/-/archive/master/ldnscripts-master.tar.gz
$ tar xvzf ldnscripts-master.tar.gz
$ cd ldnscripts-master* 
# make install

Configure ldnscripts in the file "/etc/ns/ldnscripts.conf". There is an example in the previous archive. Configuratoin should look like this :

# repository where to find unsigned zone file and specific conf
NS_REP=/etc/ns
# serial : unixtime
SERIAL=unixtime
# algorithm to use. They are listed : ldns-keygen -a list
ALG=ECDSAP384SHA384
# length of the zsk
ZSK_BITS=1024
KSK_BITS=2048
# validity of signatures in days
VALIDITY=9
#NSEC3
NSEC3_ALG=SHA-384
RUN=24
# Verbose - set to 1 if needed
VERBOSE=1

If you want, you can set a configuration file per domain : they should be named "/etc/ns/domain-name.tld.conf".

That's it for configuration 😊

To actually start using ldnscript, run with "init" parameter to create everything required : first keys, directories...

# ldnscript init athome.tld

You can read such output (below, VERBOSE is enabled):

This script will initialize your zone athome.tld with the general configuration or the
one set at /etc/ns/athome.tld.conf.
If you are not happy with it, modify your configuration (by copying the conf file to /etc/ns/athome.tld.conf and then editing it) and run this script again.
The script will create one KSK and two ZSK and finally sign the zone (which will triger a reload of your NSD server on the athome.tld zone).
The key Kathome.tld.+010+25115 has been generated with these arguments : -a RSASHA512 -b 1024 athome.tld
The key Kathome.tld.+010+34655 has been generated with these arguments : -a RSASHA512 -b 1024 athome.tld
The key Kathome.tld.+010+12321 has been generated with these arguments : -k -a RSASHA512 -b 2048 athome.tld
A new KSK key has been generated.
Make sure to update the DS record in your registrar quickly.
The key is Kathome.tld.+010+12321
DS content : 
athome.tld. IN      DS      12321 10 2 f6f91afd522680a3c459e1956e75f8eda078f99b8cf07114f0d299161bff0145
create a complete zone file for athome.tld with the current time as SOA
Signing zone
Zone is verified and complete

A directory "/var/ldnscripts/athome.tld/" is created, containing ZSK and KSK.

Signed zone file is in /var/nsd/zones/signed/athome.tld. Adjust nsd configuration to serve it :

server:
	zonesdir: "/var/nsd/zones"
	...
## master zones
zone:
    name: "athome.tld"
    zonefile: "signed/athome.tld"

Notice nsd is a static server, that's why ldnscript will reload it's configuration.

Warning, you must publish in your registrar public keys you can find in "/var/ldnscript/athome.tld/ksk" with ".key" extension. Depending on your registrar, you may have to publish DS records in ".ds" files (not at GANDI).

It's not over yet, we will set up a signing process with key renewal when necessary. Everything is ready, don't worry 😊.

ldnscript offers those actions :

Let's do this. First, edit "/etc/monthly.local" to add the rollover :

/usr/local/sbin/ldnscript rollover all

Then, make sure signatures are renewes before the end of VALIDITY parameter in configuration file. Above, we set 9 days so you can sign each week 2 day early. Edit "/etc/weekly.local" :

/usr/local/sbin/ldnscript sign all

Finally, every year, you will create a new KSK :

/usr/local/sbin/ldnscript ksk athome.tld

To remember, you can add a new crontab to send you a message every May the 2nd:

# crontab -e
0 0 2 5 * echo 'renew ksk' | mail -s "KSK ALERT" root

Remember to publish this new key in the registrar. The script rollover will delete the old key automatically. At this point, you may remove its record in the registrar.

That's it, enough!. Everything esle is handled by ldnscript, si it requires some efforts only the first time.

Notice in the example, you deal with multiples zones automatically.

Add or remove keys in the registrar

When you renew KSKs, you must add in your registrar the public key. Make sure to do it early enough si it is correctly propagated before the old one is dismissed.

Ldnscript will display the number of the new key (keytag) and its checksum (DS) useful to record it in the registrar.

The public key is located at "/var/ldnscripts/zones/athome.tld/ksk/Kathome.tld*.key".

Once a key is dismissed, you can delete the previous DS record.

Add a secondary DNS server

Sometimes called "slave", a secondary server (NS) can serve your zone in case the primary (master) is unreachable for reasons : network unreachable, NSD daemon crashed, meteor shower, frog invasion or worse : pancakes shortage.

You could ask a friend with a domain name server (not necessarily OpenBSD nor NSD either, even if it's what we describe here) to host your zone as a slave on your domain. You can even install a secondary server on your own -- on a VM rented at openbsd.amsterdam as example 😊. It's important that the secondary server is in another network, and even the same area : a few hundreds of kilometers are a good plan to mitigate power outage or network issues 😉.

Note you can absolutely set up secondary servers for your friend's domain, being mutually the slave of the other's domain name server.

We will describe both side of the picture. You could be administrator of master server, secondary server or both at the same time.

First, we prepare a little bit of authentication.

Yes, I know, it's hard work. But we want to do things right 😉? Here, we ensure our zone is updated by a legitimate server.

We will create a shared secret key, identical on both primary and secondary.

WIP \_o>

We use ldns-keygen command available in ldns-utils package you already have installed if you followed the previous part. It will create a keypair with a "secret" code inside :

$ cd /tmp
$ ldns-keygen -a hmac-sha256 -b 160 athome.tld

You have two new files, display the content of the private key :

$ cat Kathome.tld.+159+54791.private
Private-key-format: v1.2
Algorithm: 159 (HMAC_SHA256)
Key: H8D/Ka9RerEtmC0jN5hSQeATxNI=

Copy "Key" string in nsd configuration for master and slave servers in a "secret:" parameter. Remember to adjust with the proper algorithm:

key:
        name: "transfer"
        algorithm: hmac-sha256
        secret: "H8D/Ka9RerEtmC0jN5hSQeATxNI="

The "name:" parameter -- "transfer" here -- doesn't matter. It's just a mark.

You can delete previously created files in /tmp now.

On the master server :

In the configuration of the domain name server, you add two lines to alert the slave server so it retrieve the zone. For this purpose, you add instructions "notify" and "provide-xfr" :

# master zone 
zone:
       name: "athome.tld"
       zonefile: "signed/athome.tld"  
       notify: 192.0.2.1 transfer
       provide-xfr: 192.0.2.1 transfer
key:
        name: "transfer"
        algorithm: hmac-sha256
        secret: "H8D/Ka9RerEtmC0jN5hSQeATxNI="

Everytime you update the zone on your primary domain name server, it will alert the server on the address 192.0.2.1 so the latter update the zone.

Many online services -- such as registrars -- offer to host your zone as slaves for free. In this case, it is not necessary to notify : servers get the zone on schedule. Keep the "provide" without authentication : NOKEY in place of the key name.

To see how to use secondary server of GANDI, follow this link.

You can find GANDI's slave server :

$ dig ns6.gandi.net +short
217.70.177.40

Now add in your zone and in the registrar the secondary servers for your zone (NS) :

$ORIGIN athome.tld.
$TTL 86400
@           IN SOA    master.athome.tld. hostmaster.athome.tld. (
                        2014110502      ;
                        86400           ; refresh
                        7200            ; retry
                        3600000         ; expire
                        172800 )        ; negative
@               IN NS       master.athome.tld.
@               IN NS       secondairy.athome.tld.
@               IN NS       other.domain.tld.    ; a friend is
                                                 ; helping
maitre          IN A        192.0.2.2
maitre          IN AAAA     2001:db8:1:1::2
secondaire      IN A        192.0.2.3

On the secondary server now:

Just add a bit of configuration for nsd:

# slave zone 
zone:
       name: "athome.tld"
       zonefile: "slave/athome.tld"
       allow-notify: 192.0.2.2 transfer
       request-xfr: 192.0.2.2 transfer
key:
        name: "transfer"
        algorithm: hmac-sha256
        secret: "H8D/Ka9RerEtmC0jN5hSQeATxNI="

Notice both transfer keys share exactly the same configuration on each server.

Zones files should stay untouched on the secondary server. They will be updated automatically when needed. Edit the nsd configuration if you need to change their location : zones will be fetched again.

You can check if zones are in sync with "dig":

$ dig -q @master.athome.tld athome.tld
$ 192.0.2.10
â€Ļ
$ dig -q @secondairy.athome.tld athome.tld
$ 192.0.2.10

Make sure you added secondary servers in the name servers lists in your registrar.