# Dynamic DNS with BIND and ISC DHCP server



## kpa (Aug 8, 2012)

*Dynamic DNS with BIND and ISC DHCP SERVER*


I decided to write a HOWTO about RFC 2136 dynamic DNS updates with  BIND DNS server and ISC DHCP server. Automatic registration of DHCP client hostnames to DNS is something that is almost taken for granted nowadays. However, there are not too many good articles on how to set it up with just the standard tools, a DNS server like BIND (included in base in FreeBSD) and a DHCP server like net/isc-dhcp44-server.


I'm assuming you already have both BIND and the DHCP server running and serving clients, this HOWTO doesn't cover installing and configuring them for standard  (non-DDNS) use.
I'm also assuming that you have at least a basic understanding of how DNS and DHCP work.


*0. Prerequisites*

The DNS server serving the local network must be an authoritative server for the domain, this is an absolute requirement.

*1. Creating a key for DDNS updates*

The DDNS updates should be allowed only to the DHCP server serving DCHP leases on the local network(s), that's why a cryptographic key for authentication is needed.

The key is created with ddns-confgen(8). The key is created using the MD5 hash algorithm. The dhcpd(8) daemon doesn't support any other hash algorithms than MD5 at the moment even if use of other algorithms is possible with nsupdate(1). Note that rerunning the key generation will result in a different key every time. This and all other examples involving commands run on the command line assume that they are run as the root user.

`# ddns-confgen -a hmac-md5 -z mydomain`

Output will be like this (I'm using longrandomstring in place of the real key here):


```
# To activate this key, place the following in named.conf, and
# in a separate keyfile on the system or systems from which nsupdate
# will be run:
key "ddns-key.mydomain" {
    algorithm hmac-md5;
    secret "longrandomstring";
};

# Then, in the "zone" definition statement for "mydomain",
# place an "update-policy" statement like this one, adjusted as
# needed for your preferred permissions:
update-policy {
      grant ddns-key.mydomain zonesub ANY;
};

# After the keyfile has been placed, the following command will
# execute nsupdate using this key:
nsupdate -k <keyfile>
```

Copy the key -statement and save it in a file called ddns-key.mydomain. Make sure the file is only root readable.



*2. Configuring BIND for dynamic updates.*

First thing to do is to move the zone files of the to be dynamically updated zones from /etc/namedb/master to /etc/namedb/dynamic, the bind user has no write permissions to the master -directory but does have them to the dynamic -directory. Adjust the zone definitions in named.conf(5) accordingly.


```
zone "mydomain" {
    type master;
    file "/etc/namedb/dynamic/forward-zone-file";
};


zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/namedb/dynamic/reverse-zone-file";
};
```


Add the ddns-key.mydomain key to  /etc/namedb/named.conf.


```
key "ddns-key.mydomain" {
    algorithm hmac-md5;
    secret "longrandomstring";
};
```

Modify the zone definitions in /etc/namedb/named.conf to have an update-policy -section:



```
zone "myzone" {
    type master;
    file "/etc/namedb/dynamic/forward-zone-file";
    update-policy {
        grant ddns-key.mydomain zonesub any;
    };
};

zone "1.168.192.in-addr.arpa" {
    type master;
    file "/etc/namedb/dynamic/reverse-zone-file";
    update-policy {
        grant ddns-key.mydomain zonesub any;
    };
};
```

Note that I have changed the instances of "ALL" to "any" because newer versions of BIND seem to reject "ALL" and "any" seems to work instead.

Add logging directives to /etc/namedb/named.conf to catch update and update-security messages in to a separate log file. Note that named(8) runs chroot(8)ed under /var/named by default so the log files are actually found in /var/named/var/log/named. Make sure this path exists before adding the logging statement below.



```
logging {
    ...
    channel update_log {
        file "/var/log/named/bind-updates.log";
        severity debug;
        print-category yes;
        print-severity yes;
        print-time yes;
    };
    ...
    category update {
        update_log;
    };
    category update-security {
        update_log;
    };
    ...
};
```

Restart the DNS server.
`# service named restart`

Note about editing dynamic zones manually

If you have to edit the zone files of dynamic zones manually while the DNS server is running, you'll have to freeze the zones with `# rndc freeze <myzone>` before editing and unfreeze them with `# rndc thaw <myzone>` after editing. This is because named(8) has internal state information and external journal files attached to  dynamic zones that have to be kept in sync with the zone files.


*3. Testing dynamic DNS updates*

The dynamic DNS updates can be tested without the DHCP server using the  nsupdate(1) tool. If you saved the ddns-key.mydomain into a separate file with the same name the following should add a new A record testhost.mydomain with address 192.168.1.200. Note that this assumes that the NS record of the domain is pointing to the server where the updates are supposed to be sent. If this is not the case you need to add `server <ip>` as the first line of the following transcript before the `update` line:


```
# nsupdate -k ddns-key.mydomain
> update add testhost.mydomain 3600 A 192.168.1.200
> send
> ^D
```

This should now return 192.168.1.200.
`# dig testhost.mydomain.`

Remove the testhost so it doesn't cause problems later.


```
# nsupdate -k ddns-key.mydomain
> update delete testhost.mydomain
> send
> ^D
```


*4. Configuring the DHCP server for dynamic updates.*

Tell the  DHCP server to use the key created earlier to send its updates to the DNS server. Add this to dhcpd.conf(5):


```
# Key for DDNS updates
key ddns-key.myzone {
    algorithm hmac-md5;
    secret "longrandomstring";
};
```

Next add update instructions for every zone that is going to updated automatically to dhcpd.conf(5):


```
zone myzone. {
    primary 127.0.0.1;
    key ddns-key.myzone;
}

zone 1.168.192.in-addr.arpa. {
    primary 127.0.0.1;
    key ddns-key.myzone;
}
```

The [FONT=Courier New]primary <address>[/FONT] line tells dhcpd(8) where to send updates for the zone. The [FONT=Courier New]key <key>[/FONT] line tells it which key to use. In this example the DNS server and the DHCP server are on the same host and the updates are sent to localhost but it's not a requirement for dynamic DNS updates to work, the DHCP server could be running on another host. In such case the [FONT=Courier New]primary <address>[/FONT] would have the address of the DNS server on the local network.

Don't forget to also turn on ddns updates in dhcpd.conf(5). Add/change the following line:

```
ddns-update-style interim
```

Make sure that dhcpd.conf(5) is not world readable.

`#  chmod 640 /usr/local/etc/dhcpd.conf`

Restart the DHCP server.

`# service isc-dhcpd restart`


*5. Testing updates with the DHCP server running*

TODO.


----------



## johnblue (Aug 18, 2012)

Could you please post your howto in the forum instead of using an external source?

Thanks!


----------



## kpa (Aug 19, 2012)

I would if there was an automatic conversion from google drive to BB code  Exporting it as plain text would strip all the mark up and I don't want that.


----------



## johnblue (Aug 20, 2012)

kpa said:
			
		

> Exporting it as plain text would strip all the mark up and I don't want that.


Welp, you do know that your current markup it is not very useful to the community in general as is, right?



How do you expect mods to be able to correct any mistakes?  For example, it is nsupdate(1)() as opposed to nsupdate(8)().  That being said, why would you want to go to the trouble of including man references, if they are not clickable and/or correctable?  The other thing to consider is that currently your document is not searchable inside of the forums.  What if someone is having a problem with ddns-confgen?  Just saying .. 

Listen bro, I think you did a great job with your HOWTO.  Choosing to entomb your work *inside* of the freebsd.org forums is, IMHO, a much better option.

Your welcome.


----------



## kpa (Aug 20, 2012)

I guess you're right. I was trying to avoid writing it in a single use format by using google drive but it's really not much better than just writing it here using BB code  I'll try find some time to write it here in proper way


----------



## johnblue (Aug 20, 2012)

kpa said:
			
		

> I'll try find some time to write it here in proper way


Dude.

Just open the text file I attached previously, ctrl-a, edit your first post, ctrl-v.  I've done the work for ya.

:e


----------



## kpa (Aug 20, 2012)

I just did it my way  There were few things I wanted to change anyway.


----------



## SirDice (Aug 20, 2012)

Looks good kpa!


----------



## dekizugi (Nov 27, 2012)

hello all, I just want to make sure, this dynamic update will write the records in the zone file? an example if I have a client with hostname Alex and got IP Address from DHCP Server, dhcp will update to the zone file? thanks.











# sory for my english


----------



## kpa (Nov 27, 2012)

The updates are written to the zone file but not right away. There is a small amount of time when the updates are held only in temporary database files. The named(8) periodically updates the zone files to reflect the changes stored in the temporary files.


----------



## dekizugi (Nov 27, 2012)

ooh I see, U mean the updates not written to zone file directly, and written to the journal files? like a 'someofname.jnl'??? CMIIW


----------



## kpa (Nov 27, 2012)

Yes the .jnl are the temporary journal files. The updates will be written to the actual zone files eventually.  Just to repeat what I have written above in howto, if you need to edit the zone files manually you'll have to freeze zones before editing and unfreeze them afterwards with rdnc freeze/unfreeze [zone].


----------



## dekizugi (Nov 29, 2012)

kpa said:
			
		

> Yes the .jnl are the temporary journal files. The updates will be written to the actual zone files eventually.  Just to repeat what I have written above in howto, if you need to edit the zone files manually you'll have to freeze zones before editing and unfreeze them afterwards with rdnc freeze/unfreeze [zone].



thanks bro, my problem solved now, and I can sleep without worried.. hehe :e


----------



## SirDice (Nov 29, 2012)

kpa said:
			
		

> Yes the .jnl are the temporary journal files. The updates will be written to the actual zone files eventually.  Just to repeat what I have written above in howto, if you need to edit the zone files manually you'll have to freeze zones before editing and unfreeze them afterwards with rdnc freeze/unfreeze [zone].



And don't forget to update the serial number of the zone


----------



## kpa (Nov 29, 2012)

That's only needed if you have slave servers. On set ups where you have just the primary it doesn't matter what the serial numbers are.


----------



## SirDice (Nov 29, 2012)

I'm not so sure about that. Especially if you have dynamic zones. It won't hurt anyway.


----------



## kpa (Sep 9, 2018)

Updated this one a bit, certain characters were mangled on one of the forum upgrades and some information was out of date.


----------

