Make your DHCP server dynamically update your DNS records on Ubuntu Hardy Heron

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 Hardy Heron server.

Before continuing
These steps assumes that you already have a working copy of dhcp3-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 Hardy Heron server
Setting up a DHCP server on Ubuntu Hardy Heron

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 anybody to be able to update our DNS, so we need to create a secret, a 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 "10.10.10.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.10.10.10.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/dhcp3/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 10.10.10.in-addr.arpa. {
  primary 127.0.0.1;
  key DHCP_UPDATER;
}

# This is a very basic subnet declaration.
subnet 10.10.10.0 netmask 255.255.255.0 {
  range 10.10.10.100 10.10.10.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, so lets remove the general read rights from them:

sudo chmod o-r /etc/bind/named.conf.local
sudo chmod o-r /etc/dhcp3/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 /etc/init.d/bind9 restart
sudo /etc/init.d/dhcp3-server restart

7 Testing the setup

7.1 If you have an Ubuntu client that uses DHCP you can restart its network to make the DHCP-client request a new ip-address from the server:

sudo /etc/init.d/networking restart

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

host lani-desktop

Result:
lani-desktop.home.lan has address 10.10.10.100

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

host 10.10.10.100

Result:
100.10.10.10.in-addr.arpa domain name pointer lani-desktop.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 stop the bind service before making any changes to the database files, otherwise they might be overwritten by bind.

Examples of how to stop and start the bind service:

sudo /etc/init.d/bind9 stop
sudo /etc/init.d/bind9 start

The only way that I can think of to avoid this problem is to 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 for me. Please let me know if you know of a better solution.

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.

31 thoughts on “Make your DHCP server dynamically update your DNS records on Ubuntu Hardy Heron

  1. Ian Barton

    Thanks for the tutorial. I had almost got this working, but was banging my head against errors by bind trying to create files in /etc/bind. I see it’s all app armour’s fault:) Moving my zone files to /var/lib/bind fixed my problem.

    Ian.

    Reply
  2. Sebastian Carneiro

    I just want to say… thanks so much for this howto!!! It is excellent, and by following it I do make my DNS/DHCP servers work with dynamic updates.

    Best Regards.
    Sebastian.

    Reply
  3. Jason Ayres

    Must note that this also works on Gentoo from a working Bind and Named config.
    Finally got this working. Just notes, in my setup, I have a /var/bind directory to store my zone files in.

    Reply
  4. Trey

    I was at the end of my rope with this issue until I came across your how-to. Thank you so much.

    Reply
  5. lani78 Post author

    Thank you everybody for your nice comments, it’s nice to know that the guide is appreciated.

    Reply
  6. Phil

    Thanks for the helpful writeup. I found this post on Ubutu forums on DHCP with Dynamic DNS . It looks like the same basic setup as your, except that post doesn’t deal with the AppArmor issue.

    One thing mentioned in that post is using ‘rndc freeze’ and ‘rndc unfreeze’ to allow you o edit the zone files without stopping bind. Thoughts?

    Reply
    1. lani78 Post author

      Thank you Phil for your comment. I didn’t know about the commands that you posted, but it sure sounds intresting. Thank you for the tip, maybe i’ll try it out on a rainy day.

      Reply
  7. Pingback: DNS « The Crane Has Landed

  8. rabryn

    First, let me say thanks for the great articles.

    I noticed a minor issue. In your “Setting up a DNS for the local network on the Ubuntu Hardy Heron server” article, step 4.2 you have ‘zone “home.lan” IN {‘ in the /etc/bind/named.conf.local file. However, in this article, step 3.2, for the same line in the same file you have, ‘zone “home.lan” {‘. Note the missing “IN” in this article.

    Thanks again for the articles!
    rabryn

    Reply
    1. lani78 Post author

      I’m glad that you like the articles.

      And thank you for reporting your findings regarding the missing IN. It does however seams like it works both with and without the IN “keyword”.

      The man page for named.conf specifies that the position in the configuration where IN is is supposed to be an “optional class”, I do however not know what that means. I checked my server and it runs fine without IN. I also tried to change my configuration to include IN and then checked the configuration with the “named-checkconf” command, and no errors were reported, so I restarted bind and so far it still runs fine 🙂

      Reply
  9. Pingback: Buckycomputing.net » Comcast Informational Networking Organizations Security Server bash » Configuration of Ubuntu with Comcast and Bind9 DNS

  10. arun

    Hi,
    I am new in this dns configuration and trying to learn, I went through your website and trying to configure the dns along with the dhcp, the forwards lookup is working but the reverse is not working please help.
    Down below are the configuration files.
    tftpadmin@bbnldmn:/etc/bind$ cat named.conf.local
    //
    // Do any local configuration here
    //
    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 “4zK3Lgn1xcJ4dysiyT9F5w==”;
    };
    // Consider adding the 1918 zones here, if they are not used in your
    // organization
    //include “/etc/bind/zones.rfc1918”;
    zone “bbnl.in” IN {
    type master;
    file “/var/lib/bind/bbnl.in.db”;
    allow-update { key DHCP_UPDATER; };
    };
    zone “0.168.192.in-addr.arpa” {
    type master;
    file “/var/lib/bind/rev.0.168.192.in-addr.arpa”;
    allow-update { key DHCP_UPDATER; };
    };
    tftpadmin@bbnldmn:/etc/bind$

    tftpadmin@bbnldmn:/var/lib/bind$ cat bbnl.in.db
    $ORIGIN .
    $TTL 86400 ; 1 day
    bbnl.in IN SOA bbnldmn.bbnl.in. hostmaster.bbnl.in. (
    2008080916 ; serial
    28800 ; refresh (8 hours)
    14400 ; retry (4 hours)
    2419200 ; expire (4 weeks)
    86400 ; minimum (1 day)
    )
    NS bbnldmn.bbnl.in.
    MX 10 bbnldmn.bbnl.in.
    $ORIGIN bbnl.in.
    bbnldmn A 192.168.0.1
    bzr CNAME bbnldmn
    localhost A 127.0.0.1
    tftpadmin@bbnldmn:/var/lib/bind$

    tftpadmin@bbnldmn:/var/lib/bind$ cat rev.0.168.192.in-addr.arpa
    $ORIGIN .
    $TTL 86400 ; 1 day
    0.168.192.in-addr.arpa IN SOA bbnldmn.bbnl.in. hostmaster.bbnl.in. (
    2008080905 ; serial
    28800 ; refresh (8 hours)
    14400 ; retry (4 hours)
    2419200 ; expire (4 weeks)
    86400 ; minimum (1 day)
    )
    NS bbnldmn.bbnl.in.
    $ORIGIN 0.168.192.in-addr.arpa.
    1 PTR bbnldmn.bbnl.in.
    tftpadmin@bbnldmn:/var/lib/bind$

    Nov 8 22:54:31 bbnldmn dhcpd: DHCPOFFER on 192.168.1.10 to 00:0c:29:6f:c1:d2 (tftpadmin-desktop) via eth0.12
    Nov 8 22:54:31 bbnldmn named[17347]: client 192.168.0.1#44709: updating zone ‘bbnl.in/IN’: adding an RR at ‘tftpadmin-desktop.bbnl.in’ A
    Nov 8 22:54:31 bbnldmn named[17347]: client 192.168.0.1#44709: updating zone ‘bbnl.in/IN’: adding an RR at ‘tftpadmin-desktop.bbnl.in’ TXT
    Nov 8 22:54:31 bbnldmn dhcpd: Added new forward map from tftpadmin-desktop.bbnl.in to 192.168.1.10
    Nov 8 22:54:31 bbnldmn dhcpd: unable to add reverse map from 10.1.168.192.in-addr.arpa to tftpadmin-desktop.bbnl.in: timed out
    Nov 8 22:54:31 bbnldmn dhcpd: DHCPREQUEST for 192.168.1.10 (192.168.1.1) from 00:0c:29:6f:c1:d2 (tftpadmin-desktop) via eth0.12
    Nov 8 22:54:31 bbnldmn dhcpd: DHCPACK on 192.168.1.10 to 00:0c:29:6f:c1:d2 (tftpadmin-desktop) via eth0.12

    Please do let me know as to where i am going wrong,
    Thanks in advance
    Arun

    Reply
  11. Linus

    Hi, try to name the file “/var/lib/bind/rev.0.168.192.in-addr.arpa”; same as the
    zone “0.168.192.in-addr.arpa”
    e.g. /var/lib/bind/0.168.192.in-addr.arpa
    this should help
    br
    Linus

    Reply
  12. Alok

    Great article. Struggled with other howtos without success. Followed this guide and it worked first time for me. Thank you!

    Reply
  13. Soeren Hedemand

    I followed your instructions to the letter as well as I could, and everything is working. Thanks.
    However, there is a problem; the dhcp server no longer starts automatically. I think it tries to start, but can’t because the dns server locks the files or something.
    Any help, please?
    /Søren

    Reply
    1. lani78 Post author

      Hi Sören. Thank you for your comment. I think I experienced the same thing, but I do not have a solution I’m afraid. I can only hope that someone else will answer you question or that google can help you. You are happy to share your solution here if you find it.

      Reply
      1. Soeren Hedemand

        I finally figured it out. Solution is to change the owner of the dhcpd.conf file from root:root to dhcpd:dhcpd. This worked on two machines running 10.04 and 11.10.
        /Søren

      2. lani78 Post author

        Thank you very much for taking your time to comment with your solution. It is very much appreciated. I will try it myself and update the original post with this information when I get the time.

  14. Pingback: Laxdal.org · Basic gateway using CentOS

  15. Sven

    Great tutorial! I’ve never made it for the last few years, but with your tutorial it was piece of cake to set it up.
    Thank you

    Reply
  16. Curzon

    Thanks for this great tutorial.

    One note about DNS update for clients using host declaration and fixed-address.
    I had the problem that clients using a fixed ip address are not updated.

    Solution:
    If you use fixed-address client declaration like this:

    # My Clients
    subnet 192.168.1.0 netmask 255.255.255.0 {
    range dynamic-bootp 192.168.1.100 192.168.1.200;

    # My Clients with static IP
    group {
    # Client01
    host myclient01 {
    hardware ethernet 01:02:03:04:05:01;
    fixed-address 192.168.1.12;
    }
    # Client02
    host myclient02 {
    hardware ethernet 01:02:03:04:05:02;
    fixed-address 192.168.1.13;
    }
    }
    }

    you need to add

    update-static-leases on;

    within your global or subnet declaration, otherwise dhcpd will not update the DNS for those clients which gets a static ip from host declaration.

    Reply
  17. Afifim

    thank you very much for the amazing guide. it worked perfectly on ubuntu 18.4.1 server with latest updates as of December 9 2018.

    Reply

Leave a reply to beze Cancel reply

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