Make your DHCP server dynamically update your DNS records on Ubuntu 12.04 (Precise Pangolin)

Updated version
This is an updated guide for Ubuntu 12.04. If you use an older version of Ubuntu, then you might want to check out the old guide, that was written for Ubuntu 8.04.

Information
The steps in this post shows how to configure the DHCP server to automatically update the DNS records when giving out a new lease to a client computer. All on the Ubuntu 12.04 Precise Pangolin server.

Before continuing
These steps assumes that you already have a working copy of isc-dhcp-server and bind9 installed. If you don’t have that I suggest that you first read my two other posts on how to install them:

Setting up a DNS for the local network on the Ubuntu 12.04 (Precise Pangolin) server
Setting up a DHCP server on Ubuntu 12.04 (Precise Pangolin) server

Step by step instructions

1. Move the files to a directory that bind can write to

Apparently the Ubuntu server is installed with an AppArmor profile that prevents bind to write to the /etc/bind directory. The default profile suggests that these files should be put in /var/lib/bind. If you have followed the steps in my previous post you might have your zone database files in /etc/bind/zones. We will start by copying the files so we have a backup remaining if anything goes wrong:

1.1 Copy the zone database files:

sudo cp /etc/bind/zones/* /var/lib/bind/

1.2 Change the owner and group of the files to bind, so that bind will have file permissions that allows it to write to the files:

sudo chown bind:bind /var/lib/bind/*

2. Create a secret shared between the DHCP server and the DNS

We don’t wont just anybody to be able to update our DNS, so we need to create a secret key that the DCHP server must know in order to be able to update the DNS.

2.1 Generate a new key:

sudo dnssec-keygen -r /dev/urandom -a HMAC-MD5 -b 128 -n USER DHCP_UPDATER

2.2 Show the generated key:

sudo cat Kdhcp_updater.*.private|grep Key

2.3 Now copy the key to the clipboard so that you can paste it into the configuration file later on.

3 Configure the DNS

We now need to add the key to the bind configuration and tell it what zones that we want it to allow updates on. I’ve included the whole contents of my file here and marked the changes that I’ve made in bold.

3.1 Edit /etc/bind/named.conf.local:

sudo nano /etc/bind/named.conf.local

3.2 Changes are marked with bold:

# The secret key used for DHCP updates.
key DHCP_UPDATER {
    algorithm HMAC-MD5.SIG-ALG.REG.INT;

    # Important: Replace this key with your generated key.
    # Also note that the key should be surrounded by quotes.
    secret "asdasddsaasd/dsa==";
};

zone "home.lan" {
    type master;

    # Change the path of the database file to the writable copy in /var/lib/bind
    file "/var/lib/bind/home.lan.db";

    # Tell this zone that we will allow it to be updated from anyone
    # that knows the secret specified in the DHCP_UPDATER key.
    allow-update { key DHCP_UPDATER; };
};

zone "0.168.192.in-addr.arpa"  {
    type master;

    # Change the path of the database file to the writable copy in /var/lib/bind
    file "/var/lib/bind/rev.0.162.198.in-addr.arpa";

    # Tell this zone that we will allow it to be updated from anyone
    # that knows the secret specified in the DHCP_UPDATER key.
    allow-update { key DHCP_UPDATER; };
};

4 Configure the DHCP server to send updates to the DNS

4.1 Edit dhcpd.conf:

sudo nano /etc/dhcp/dhcpd.conf

4.2 Changes are marked with bold:

#
# Make sure to change the ddns update style to interim:
ddns-update-style interim;
ignore client-updates;      # Overwrite client configured FQHNs
ddns-domainname "home.lan.";
ddns-rev-domainname "in-addr.arpa.";

# option definitions common to all supported networks...
option domain-name "home.lan";
option domain-name-servers ubuntu.home.lan;

default-lease-time 600;
max-lease-time 7200;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

key DHCP_UPDATER {
    algorithm HMAC-MD5.SIG-ALG.REG.INT;

    # Important: Replace this key with your generated key.
    # Also note that the key should be surrounded by quotes.
    secret "asdasddsaasd/dsa==";
};

zone home.lan. {
  primary 127.0.0.1;
  key DHCP_UPDATER;
}

zone 0.168.192.in-addr.arpa. {
  primary 127.0.0.1;
  key DHCP_UPDATER;
}

# This is a very basic subnet declaration.
subnet 192.168.0.0 netmask 255.255.255.0 {
  range 192.168.0.100 192.168.0.200;
  option routers router.home.lan;
}

5 Tighten the permissions on the configuration files

The configuration files now contains our secret key. We should not let just anyone read our secret key. We also have to give the DHCP-server the permission to read and write it’s own file.

5.1 Remove the general read rights from the configuration files:

sudo chmod o-r /etc/bind/named.conf.local
sudo chmod o-r /etc/dhcp/dhcpd.conf

5.2: Change owner of dhcpd.conf to dhcpd:

sudo chown dhcpd:dhcpd /etc/dhcp/dhcpd.conf

We should now have a fully working dynamic dns system for our local network, lets hold our thumbs and restart the services.

6 Restart the services to reload the configuration.

sudo service bind9 restart
sudo service isc-dhcp-server restart

7 Testing the setup

7.1 If you have an Ubuntu client that uses DHCP you can release your ip address and request a renewal form the DHCP-server:

dhclient -r wlan0
sudo dhclient wlan0

7.2 You should now be able to lookup your client computer in your DNS:

host lani-laptio

Result:
lani-laptio.home.lan has address 192.168.0.100

7.3 And the reverse should now also work for your client computer address:

host 192.168.0.100

Result:
100.0.168.192.in-addr.arpa domain name pointer lani-laptio.home.lan.

8 Cleanup

8.1 Remove the generated key files:

 sudo rm Kdhcp_updater.*

8.2 Remove the old zone db files:

sudo rm -R /etc/bind/zones

Done 🙂

Some “important” pointers

Database files being rewritten by bind
The dns database files are now being rewritten by the bind service. Some people have mentioned that they think that bind messes up these files so that they are impossible to maintain. I don’t think that they are that bad and personally I don’t have any problem editing them after that bind has rewritten them. I’m not sure how often that bind rewrites these files, but at least it seems to always happen when you stop the bind service.

What I think is more important is to always freeze the zone file before editing it, otherwise they might be overwritten by bind.

Examples of how to freeze and unfreeze a zone:

sudo rndc freeze home.lan.
sudo rndc unfreeze home.lan.

Also, do not forget to change the serial in the zone file if you change anything in it.

If you want to avoid the problem with bind rewriting the files and the need to freeze and unfreeze zones, then you could split your domains into two sub domains, for example dyn.home.lan. and static.home.lan. You could then have the DCHP server to only update the dyn.home.lan domain. But I didn’t want this and I’m not going to update these files that often that it matters to me.

Key generation
When using the dnssec-keygen to generate the secret key I passed it the parameter “-r /dev/urandom”. I’ve seen some pointers about that this will generate a less secure key. But for me the dnssec-keygen would just halt without that parameter. One other suggestion that I’ve seen it that you should switch to another terminal window on the server and run some commands that make some work on the server, to make it fill up the default /dev/random. I think that I would have done this if I would set this up in a corporate environment. But for my own home network I really think that the /dev/urandom will be sufficient.

Troubleshooting
There must be many more ways to troubleshoot any problems. But I managed to get it working by checking the system log for clues when a service didn’t start or when the DHCP server didn’t update the DNS records:

tail /var/log/syslog

That’s it!
I’ve really tried to make these steps as accurate as possible, following my own steps to get this to work. Please let me know if you think that I’ve missed something. Thank you.

Acknowledgments
* Thanks to Phil who commented on the previous version of this guide with this tip on rndc freeze and unfreeze.
* Thansk to Soeren Hedemand who also commented on the previous version of this guide with information about changing the group and owner of dhcpd.conf to dhcpd to solve the problem with the dchpd sometimes not starting as it should.

23 thoughts on “Make your DHCP server dynamically update your DNS records on Ubuntu 12.04 (Precise Pangolin)

  1. john

    Lani, where would I go to make add a static entry? /var/lib/bind/ ? Do I have to unfreeze before doing so? You mentioned “Also, do not forget to change the serial in the zone file if you change anything in it.” How would I know what to change to?

    Reply
    1. lani78 Post author

      Yes if you followed this guide you would have your db file in /var/lib/bind. Edit it, for example:

      sudo nano /var/lib/bind/home.lan.db

      See example in my previous guide on setting upp the DNS:

      https://lani78.wordpress.com/2012/07/22/setting-up-a-dns-for-the-local-network-on-the-ubuntu-12-04-precise-pangolin-server/

      There this file is still located under /etc/bind/zones.

      And you should freeze first, then unfreeze. Not the other way around. Freeze it to prevent bind to overwrite your changes. Then unfreeze it to allow bind to update it again. If you forget to unfreeze it the dynamic updates won’t work.

      The serial just have to be increased. A common format is YYYYMMDDII where the II index is in case you make more that one change in the same day. You can read about this as well in my other guide that i linked to above. I hope this helps.

      Reply
  2. Adam

    I think you have a typo. In the dhcpd.conf you have “zone 0.168.182.in-addr.arpa. {” – 182 instead of 192.

    cheers!

    P.S. Thank-you for all your blog posts on configuring Ubuntu Server! You have helped me so very much!!

    Reply
    1. lani78 Post author

      Thank you for your kind words 🙂 And for pointing out the typo! I have fixed it now. I actually use 10.10.10.x at home, but changed it for this guide to make the reverse order easier to understand.

      Reply
  3. Adam

    I noticed an error in my /var/log/syslog saying that it didn’t have permission to write to /var/lib/dhcp/dhclient.leases. The file didn’t exist, so I did the following:

    sudo touch /var/lib/dhcp/dhclient.leases
    sudo chown dhcpd:dhcpd /var/lib/dhcp/dhclient.leases

    Reply
  4. Catalin

    Hi,

    Thank you very much for your guide, it’s very helpful to have these, when most of other documentation for these 2 services is pretty much outdated :(.
    After I’ve followed your directions, I’ve noticed something weird on mostly Linux clients (well, Android too) — were not receiving a DNS server from DHCP. Windows clients seem to have simply been stubborn, otherwise I’d have realized it earlier:

    in dhcpd.conf you don’t define a DNS server to send to your clients. For someone who’s having the same problem:
    “option domain-name-servers dns_server_IP;” — I’ve added this line in my subnet section.

    Running on debians here (don’t think that would make a difference, would it?).

    Cheers mate, and thanks again!

    Reply
  5. Johnny

    I really enjoy the write up. , thank you very much for your effort.

    Do you see anytime in the future to update to include IPv6 support via Blind9 + dhcp6s?

    Reply
    1. lani78 Post author

      Hi Johnny,

      Thank you for your comments.

      I have not setup IPv6 myself and does not have any current plans on this, sorry.

      /Lani

      Reply
  6. Kostas

    Thank you for your post ! I have read many guides but this one seems to have some extra information (like changing ownership back for dhcp). I am keen of going back and checking my implementation with your directions. One question though: does this guide require the client’s dhclient.conf to be modified in order to enable the FQDN option when doing a DHCP request ?From a quick look in man dhcpd.conf: if the client doesn’t provide a FQDN option, DHCP won’t update the record. What OS did your clients have ?Thank you for all the advice !

    Reply
    1. lani78 Post author

      Hi Kostas,

      Thank you for your comment. I have not had any problems with this. I have both Ubuntu, Windows XP and Windows 7 clients. The DHCP clients gets all the information that they need from the DHCP server, see my post on setting up the DHCP server.

      Reply
  7. semo163

    Thank you for your great post. It contains just everything admin needs to get DHCP+DYNDNS up and running in a couple of minutes. It helped me a lot recently.

    Reply
  8. Steven

    Can we target dns servers that are not on the same machine? I have 1 dns server and 1 dhcp server. Should I just be able to point the following field to the correct server?

    primary 192.168.1.104;

    Thanks!

    Reply
  9. Eric

    Thank you for this post, DHCP server and DNS server posts it helps me to set it up for TurnKey linux systems. One question can the DHCP server update the DNS server with “static” DHCP addresses? I have added this to /etc/dhcpd/dhcpd.conf inside the defined subnet
    host fileserver {
    hardware ethernet 00:0c:29:ad:5e:e6;
    fixed-address 192.168.137.51;
    }
    But I don’t see it in the dhcpd.leases and in the DNS server.

    Reply
  10. eric

    The solution of previous post is: add in the global section (top of file) of /etc/dhcp/dhcpd.conf the line:
    update-static-leases on;

    Reply
  11. Andre

    Hi this was great. All works well except the reverse lookup is not updated. Triple checked and can’t see what I’ve typed incorrectly

    Reply
  12. Rohan Patil

    I did exactly what you said on Ubuntu Server 14.04 and I am getting “unable to add forward map : Timed Out” error and it then says NO TSEC FOR KEY. Please help.

    Reply
  13. rgisgard

    Great post lani78, I followed it for a Centos 7.4 installation and worked great. I also tried tried to change the algorithm to HMAC-SHA512, but centos has a bug and won’t accept it. So MD5 as suggested and everything works 🙂

    Reply

Leave a reply to john Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.