We have example.com server with bing9 server.
At home we have a server with dynamic IP.
Pin the dynamic IP to your own server. -> home.example.com


The document asserts a working BIND setup already in place. Installing and configuring BIND is out of scope here.

Creating a key-pair

To create a key-pair, we’ll be using dnssec-keygen.

server$ dnssec-keygen -a HMAC-SHA512 -b 512 -n USER home.example.com.

This creates two files, which will be named differently based on individual runs.

server$ file Khome.example.com.+157+62567.*
Khome.example.com.+157+62567.key:     ASCII text
Khome.example.com.+157+62567.private: ASCII text

Notice that the Key: field in the .private file is simply the concatenated key from the .key file.

Key File

Next created a key file at /etc/bind/keys.conf.

key home.example.com. {
    algorithm HMAC-SHA512;
    secret "Mprj8I76jDiEldj3SgF7/Ph5bWm4eHYZu0nOcUB1vT4wU5PjbYNnp8T9 cb8XqmE0ANotnw+FBBbr3lA8O5uJ8A==";

Then add the following line to /etc/bind/named.conf.local to include the new key.

include "/etc/bind/keys.conf";

Dynamic Zone

The key is situated on the server, all that remains is to add a zone for BIND. This is my entry further down in /etc/bind/named.conf.local:

zone "home.example.com" {
    type master;
    file "/etc/bind/dyndns/home.example.com";
    update-policy {
      grant home.example.com. name home.example.com. A TXT;

We have to create the directory /etc/bind/dyndns, give bind permission to write to it, and place the zone home.example.com there.

server$ sudo mkdir /etc/bind/dyndns
server$ sudo chgrp bind /etc/bind/dyndns
server$ sudo chmod g+w /etc/bind/dyndns

Lastly put the /etc/bind/dyndns/home.example.com file into place.

$TTL 14400      ; 4 hours
home.example.com         IN SOA  ns1.example.com. root.example.com. (
                                9          ; serial
                                604800     ; refresh (1 week)
                                86400      ; retry (1 day)
                                2419200    ; expire (4 weeks)
                                604800     ; minimum (1 week)
                        NS      ns1.example.com.

Restart BIND with a simple service bind9 restart and it’s time for the client side.


First transfer the .key and .private files down to the client system via your transport mechanism of choice. Once situated, chmod each file to 0400.

-r-------- 1 user user 128 Jan 26 17:58 Khome.example.com.+157+62567.key
-r-------- 1 user user 229 Jan 26 17:58 Khome.example.com.+157+62567.private

Update Script

The nsupdate tool in the `dnsutils`ddns-scripts_nsupdate package will perform the update. I wrote a simple wrapper script in bash to run the update for me.

# -----------------------------------------------------------
# update the dynamic dns for home system
# usage: do-nsupdate
# -----------------------------------------------------------

EXT_IP=$(wget -qO- http://ifconfig.co/ip)

cat <<EOF | nsupdate -k "$KEY"
server example.com
zone example.com
update delete home.example.com. A
update add home.example.com. 600 A $EXT_IP

Running the do-nsupdate script manually will show whether everything is working correctly.


  • https://github.com/int0x80/notes/wiki/Linux:-Dynamic-DNS-with-BIND-and-DNSSEC
  • https://dnns.no/dynamic-dns-with-bind-and-nsupdate.html