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.

Setting up a DHCP server on Ubuntu 12.04 (Precise Pangolin) server

This is my updated installation log of how I installed and configured a DHCP server on the Ubuntu 12.04 Precise Pangolin server.

If you are using an older version of Ubuntu then you might want to check out the old guide that was written for Ubuntu 8.04.

1: Make sure that the latest version is installed:

sudo apt-get install isc-dhcp-server

Note: Don’t be alarmed if the startup fails; that’s because you haven’t configured it yet.

2.1: Enable the DCHP server on your network interface (in my case eth0):

sudo nano /etc/default/isc-dhcp-server

2.2: Set INTERFACES=”” to the name of the network interface that you want to enable the DHCP server on:

INTERFACES="eth0"

3.1: Edit the DHCP server configuration:

sudo nano /etc/dhcp/dhcpd.conf

3.2: The contents of my configuration file, for me the comments already in the file was what I needed to make the necessary changes:

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# 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;

# 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;
}

4: Restart the DHCP server (it should now start without problems):

sudo service isc-dhcp-server restart

Done 🙂

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

Updated version

This is my updated step by step procedure that I took to setup my local dns server for our local network at home using Ubuntu 12.04. If you have an older version of Ubuntu you might want to instead check out the old guide, that was written for Ubuntu 8.04.

Step by step instructions

1: Make sure that the latest version of bind9 is installed (that’s the dns-server software):
sudo apt-get install bind9

2.1: Configure the DNS to cache requests and forward unknown requests to other DNS servers:
sudo nano /etc/bind/named.conf.options

2.2: Uncomment or add the forwarders section and replace the x:es with the ip-address to the primary and secondary dns of your isp:

forwarders {
        x.x.x.x;
        x.x.x.x;
};

Tip: I use OpenDNS as my forwarders, currently 208.67.222.222 and 208.67.220.220.

3.0: Make the server use its own DNS for look-ups:
How to specify which DNS server to use depends on if you are using a dynamic or static ip address:

3.DYNAMIC.1: Edit dhclient.conf:
sudo nano /etc/dhcp/dhclient.conf

3.DYNAMIC.2: Uncomment or add the following line:
prepend domain-name-servers 127.0.0.1;

Note: 127.0.0.1 points to the local machine, making the DNS requests go through our DNS server that we are setting up.

[OPTIONAL]
You might want to also add a search directive to eliminate the need of typing the FQDN when looking up local records. But you should only do this if you cannot control this information in the DHCP server. If you setup the DHCP server as well, then you should make sure that the DHCP server provides the search directive. It would then be automatically used by the DHCP client.

supersede domain-name "home.lan";

3.STATIC.1: Edit /etc/network/interfaces:
sudo nano /etc/network/interfaces

3.STATIC.2: Change or add the dns-nameserver, dns-search and dns-domain directives:

# The primary network interface
auto eth0
iface eth0 inet static
        address 192.168.0.2
        netmask 255.255.255.0
        gateway 192.168.0.1
        network 192.168.0.0
        broadcast 192.168.0.255
        dns-nameservers 127.0.0.1
        dns-search home.lan
        dns-domain home.lan

Note 1: home.lan is the domain name of our local network in this guide. A DNS search directive is used to eliminate the need of typing the FQDN when looking up local records.

Note 2: This setup must also be done for other Ubuntu clients that use a static IP. But then it should point to the IP of our DNS server. If you have a DHCP server you should specify your DNS IP in its settings, as well as the search domain.

4.1: Define the zones for the local domain:
sudo nano /etc/bind/named.conf.local

4.2: Add a zone for the local domain:

zone "home.lan" IN {
    type master;
    file "/etc/bind/zones/home.lan.db";
};

4.3: Also add a zone for reverse dns lookups for the local network:

zone "0.168.192.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/rev.0.168.192.in-addr.arpa";
};

Note: Make sure that it’s literal quotes that are used, so that they aren’t converted if you copy and past them to the terminal. You get literal quotes on a Swedish keyboard by pressing “Shif+2”, on an English keybord it might be “Shif+,” ?

5: Create the zones directory:
sudo mkdir /etc/bind/zones

6.1: Configure the local domain:
sudo nano /etc/bind/zones/home.lan.db

6.2: Example settings, change to match your host names and ip-addresses:

; Use semicolons to add comments.
; Host-to-IP Address DNS Pointers for home.lan
; Note: The extra “.” at the end of the domain names are important.

; The following parameters set when DNS records will expire, etc.
; Importantly, the serial number must always be iterated upward to prevent
; undesirable consequences. A good format to use is YYYYMMDDII where
; the II index is in case you make more that one change in the same day.
$ORIGIN .
$TTL 86400      ; 1 day
home.lan. IN SOA ubuntu.home.lan. hostmaster.home.lan. (
    2008080901 ; serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)

; NS indicates that ubuntu is the name server on home.lan
; MX indicates that ubuntu is (also) the mail server on home.lan
home.lan. IN NS ubuntu.home.lan.
home.lan. IN MX 10 ubuntu.home.lan.

$ORIGIN home.lan.

; Set the address for localhost.home.lan
localhost    IN A 127.0.0.1

; Set the hostnames in alphabetical order
print-srv    IN A 192.168.0.9
router       IN A 192.168.0.1
server       IN A 192.168.0.5
ubuntu       IN A 192.168.0.2
xbox         IN A 192.168.0.3

7.1: Create and edit the reverse lookup configuration file:
sudo nano /etc/bind/zones/rev.0.168.192.in-addr.arpa

7.2: Example settings, reversed of the above:

; IP Address-to-Host DNS Pointers for the 192.168.0 subnet
@ IN SOA ubuntu.home.lan. hostmaster.home.lan. (
    2008080901 ; serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)
; define the authoritative name server
           IN NS ubuntu.home.lan.
; our hosts, in numeric order
1         IN PTR router.home.lan.
2         IN PTR ubuntu.home.lan.
3         IN PTR xbox.home.lan.
5         IN PTR server.home.lan.
9         IN PTR print-srv.home.lan.

8.0: Restart services to use the new settings:
8.1: Restart bind:
sudo service bind9 restart

8.2: Restart the network interface that you changed in step 3:
sudo nohup sh -c "ifdown eth0 && ifup eth0"Note that networking restart has been deprecated, see this post for more information.

9.0 Test that everything works as expected.
9.1: Test that the dns look-ups works with the local server:
host ping.sunet.se

The response should be:
ping.sunet.se has address 192.36.125.18
ping.sunet.se has IPv6 address 2001:6b0:7::18

9.2: Test that all of your computers are listed with the following command:
host -l home.lan

The output should list all of your entered hosts:
home.lan name server ubuntu.home.lan.
localhost.home.lan has address 127.0.0.1
print-srv.home.lan has address 192.168.0.9
router.home.lan has address 192.168.0.1
server.home.lan has address 192.168.0.5
ubuntu.home.lan has address 192.168.0.2
xbox.home.lan has address 192.168.0.3

9.3: Test that the reverse lookup works:

 host 192.168.0.1

Response:
1.0.168.192.in-addr.arpa domain name pointer ubuntu.home.lan.

Final words

  • You should have a firewall between this server and the internet and make sure that the dns port (53) is not forwarded to your Ubuntu server. Otherwise your dns server will be open for anyone in the world to use. With this setup it is only intended to be used within your local network.
  • Do not forget to update the serial every time you make any changes to a zone file.

Generate a ssh key and disable password authentication on the Ubuntu 12.04 (Precise Pangolin) server

Foreword

This is an updated guide for Ubuntu 12.04. You might want to check out the old guide if you are using an older version of Ubuntu. The old guide was written for Ubuntu 8.04.

This new version is updated with the command “service ssh reload” instead of “/etc/init.d/ssh reload”. And I have also learned of better way to test connecting via ssh without using the key file (-o PubkeyAuthentication=no, for testing purposes).

Ubuntu ssh step by step guide

1. Generate the ssh key pair on your client computer:
ssh-keygen

2. Copy the public key to the server:
scp ~/.ssh/id_rsa.pub user@10.10.10.1:

3. Connect to the server:
ssh user@10.10.10.1

4. Append the public key to authorized_keys and remove the uploaded copy:
cat id_rsa.pub >> ~/.ssh/authorized_keys
rm id_rsa.pub

5. Edit the ssh server configuration to make sure that public key authentication is enabled (it should be enabled by default):
sudo nano /etc/ssh/sshd_config

5.1 These entries must be set to yes:
RSAAuthentication yes
PubkeyAuthentication yes

6. Reload the configuration:
sudo service ssh reload

7. Disconnect from the server:
exit

8. Try connecting without the need to give the password to the ssh-client:
ssh user@10.10.10.1

You might need to give a password now to access your private key file, but you should not need to give the password to the ssh program.

9. Disable password authentication:
sudo nano /etc/ssh/sshd_config

9.1 The following settings should be set to no:
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

9.2. Reload the configuration:
sudo service ssh reload

10. Test that password authentication really is disabled:
10.1 Disconnect from the server:
exit

10.2 Try to reconnect to the server with key file authentication disabled:

ssh user@10.10.10.1 -o PubkeyAuthentication=no

This should produce a permission denied message: “Permission denied (publickey).”

Done 🙂

Troubleshooting

If you ran into any problems it might help to check out the pointers in the comments of the old guide. I highly value the constructive comments that I have received, as I often learn something new from them.

 

Change to static ip on the Ubuntu 12.04 (Precise Pangolin) server

This is an updated guide for Ubuntu 12.04 Server on how to set a static ip, as the approach has changed a bit since my previous guide for Ubuntu 8.04.

1 Setup a static ip address
1.1: Edit /etc/network/interfaces:
sudo nano /etc/network/interfaces

1.2: Change from dhcp to static:
Note that the changes below are edits, not the complete file. We change the word on the first line from dhcp to static. The rest of the file should be kept intact with the loopback interface settings.

- iface eth0 inet dhcp
+ iface eth0 inet static
+        address 192.168.0.2
+        netmask 255.255.255.0
+        gateway 192.168.0.1
+        network 192.168.0.0
+        broadcast 192.168.0.255
+        dns-nameservers 208.67.222.222 208.67.220.220
+        dns-search home.lan
+        dns-domain home.lan

2: Remove old configuration files used to generate resolv.conf:
The file resolv.conf should no longer be edited by hand. It is updated by the resolvconf script. To prevent resolvconf to still generate our resolv.conf file with our old dhcp settings we have to delete these two files:
sudo rm /run/resolvconf/interface/eth0.dhclient
sudo rm /run/resolvconf/interface/original.resolvconf

3: Uninstall the dhcp client (otherwise it will overwrite our changes on the next renew cycle):
sudo apt-get remove isc-dhcp-client

4: Restart the network to use the new settings:
The command “networking restart” has been deprecated. We can instead bring the interface down with ifdown and back up again with ifup to reload the settings. If we do it over an ssh connection we will lose connectivity when we bring the interface down. To solve this problem we can chain the two commands together. But doing so will prevent us from seeing the messages outputted from the commands, which can be useful in case something went wrong. We can then use the nohup command to direct the output to the file nohup.out:

sudo nohup sh -c "ifdown eth0 && ifup eth0"

The result can be check with the cat command:
sudo cat nohup.out

It should look something like this:
ssh stop/waiting
ssh start/running, process 2889

5. Check that everything is working ok:
5.1 The resolv.conf should now only contain the dns settings that we provided for our interface (eth0), check with:
sudo cat /etc/resolv.conf

The result should look like this:
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 208.67.222.222
nameserver 208.67.220.220
search home.lan

5.2 Check that the correct ip address has been set:
ifconfig eth0 | grep 'inet addr'

Result:
inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0

5.3 Check that dns lookup works:
nslookup lani.nu

Result:
Server: 208.67.222.222
Address: 208.67.222.222#53

Non-authoritative answer:
Name: lani.nu
Address: 194.9.94.85
Name: lani.nu
Address: 194.9.94.86

Note that address in the reply might have changed after this was written.

5.4 And if we have gotten this far we have most likely set our gateway and other network parameters correctly and should also be able to reach the internet:
ping ping.sunet.se

Result:
PING ping.sunet.se (192.36.125.18) 56(84) bytes of data.
64 bytes from ping.sunet.se (192.36.125.18): icmp_req=1 ttl=249 time=7.94 ms
64 bytes from ping.sunet.se (192.36.125.18): icmp_req=2 ttl=249 time=6.94 ms
64 bytes from ping.sunet.se (192.36.125.18): icmp_req=3 ttl=249 time=8.14 ms
64 bytes from ping.sunet.se (192.36.125.18): icmp_req=4 ttl=249 time=6.99 ms

Done 🙂

GNOME Auto login in Ubuntu 9.10 Karmic Koala Alpha 3

Ubuntu 9.10 alpha 3 comes with the latest GDM (The GNOME Display Manager, which is the default login manager shipped with Ubuntu). Unfortunately the latest version, 2.27.4, is an unstable version that still is heavily under development and still lacks a graphical configuration dialog.

So if you, like me, decided that you actually wanted to login automatically in GNOME instead of the manual login that you choose in the installation process, or vice versa. Well then it’s back to the configuration files. The default configuration values used by GDM is located in the XML file named ‘/etc/gdm/gdm.schema’. The documentation does however state that any changes to the default values should be made to the ‘/ect/gdm/custom.conf’ file, which is in keyfile format.

Configure GDM to auto login a specific user

  1. Open the ‘Run Application’ dialog by pressing:
     Alt+F2
  2. Open/create the custom.conf file with gedit:
    gksu gedit /etc/gdm/custom.conf
  3. Enter the configuration values that you want to override:
    [daemon]
    AutomaticLoginEnable=true
    AutomaticLogin=lani
  4. Reboot your system, and viola – you’re automatically logged in to GNOME! 🙂

Configuration explanation

Note that the [deamon] directive must be included in the file, it tells GDM in what section we want to override the keys. The AutomaticLoginEnable key  can be set to either true or false, to disable or enable the automatic login into GNOME. And finally the AutomaticLogin key should be set to the username of the user that should be loged into GNOME automatically, in the example above my username is lani.

References

GNOME Display Manager Reference Manual

Fix Marvel Yukon sky2 driver in Ubuntu Jaunty

EDIT: THIS DID NOT WORK FOR ME!

I thought that it worked at first, I did several tests, downloading in 100 mbit from the internet using 10 different connections and transfering files from my server in 275 mbit. But today the network connection has dropped twice for me. If this works for you, then I’m happy for you. If you have another solution, please leave a comment. Thank you.

I have an on-board Marvell Yukon 88E8053 PCI-E gigabit ethernet controller (rev 15), which kept dropping the network connection during heavy load using the sky2 driver. I tried to compile the sk98lin driver instead, but I couldn’t get it to compile successfully on my system. That’s when I found out that MSI might not be correctly implemented, fortunately the MSI feature can be easily turned off in the latest sky2 driver using the disable_msi option.

Permanently disable MSI

1. Open the /etc/modules file for editing:

sudo gedit /etc/modules

2. Add the following new line:

sky2 disable_msi=1

3. Restart your computer. And viola, hopefully your NIC will now have stopped dropping your connection all the time.

Temporarily disable MSI

If you would like to test if the diable_msi option works for you before disabling it “permanently”, or to avoid a restart. Then you can unload the sky2 driver manually and load it with the disable_msi=1 option.

sudo rmmod sky2
sudo modprobe sky2 disable_msi=1

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.

Setting up a DHCP server on Ubuntu Hardy Heron

Update: There is now an updated version of this guide for Ubuntu 12.04: Setting up a DHCP server on Ubuntu 12.04 (Precise Pangolin) server.

This is my really short installation log of how I installed and configured a DHCP server on Ubuntu Hardy Heron.

1: Make sure that the latest version is installed:

sudo apt-get install dhcp3-server

Note: Don’t be alarmed if the startup fails; that’s because you haven’t configured it yet.

2.1: Edit the DHCP server configuration:

sudo nano /etc/dhcp3/dhcpd.conf 

2.2: The contents of my configuration file, for me the comments already in the file was what I needed to make the necessary changes:

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# 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;

# 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;
}

3: Start the DHCP server (it should now start without problems):

sudo /etc/init.d/dhcp3-server start

Done 🙂

Setting up a DNS for the local network on the Ubuntu Hardy Heron server

There is now an updated guide for Ubuntu 12.04: Setting up a DNS for the local network on the Ubuntu 12.04 (Precise Pangolin) server

Condensed version

This is my really condensed step by step procedure that I took to setup my local dns for our local network at home. It really isn’t more than just a shorter version of the great guides posted by Sam Davis:

BIND Caching Name Server Setup
BIND Master Server Setup

I really recommend that you read his two post to get some more information, then you can check my pointers and maybe my configurations posted below if you want yet another example to look at.

Step by step instructions

1: Make sure that the latest version of bind9 is installed (that’s the dns-server software):
sudo apt-get install bind9

2.1: Configure the DNS to cache requests:
sudo nano /etc/bind/named.conf.options

2.2: Uncomment or add the forwarders section and replace the x:es with the ip-address to the primary and secondary dns of your isp:

forwarders {
        x.x.x.x;
        x.x.x.x;
};

3.1: Make the server use its own DNS for lookups:
sudo nano /etc/resolv.conf

3.2: Change or add the nameserver directive to point to the local machine:
nameserver 127.0.0.1

3.3: You can also add a search directive, to that you don’t have to type the whole fully qualified domain name every time, just the computer name instead:
search home.lan

Note: This must also be done for other Ubuntu clients that use a static IP. But then it should point to the IP of the DNS server. If you have a DHCP server you should specify your DNS IP in its settings, as well as the search domain.

4.1: Define the zones for the local domain:
sudo nano /etc/bind/named.conf.local

4.2: Add a zone for the local domain:

zone "home.lan" IN {
    type master;
    file "/etc/bind/zones/home.lan.db";
};

4.3: Also add a zone for reverse dns lookups for the local network:

zone "10.10.10.in-addr.arpa" {
    type master;
    file "/etc/bind/zones/rev.10.10.10.in-addr.arpa";
};

Note: Make sure that it’s literal quotes that is used, so that they not are converted if you copy and past them to the terminal. You get literal quotes on a Swedish keyboard by pressing “Shif+2”, on an English keybord it might be “Shif+,” ?

5: Create the zones directory:
sudo mkdir /etc/bind/zones

6.1: Configure the local domain:
sudo nano /etc/bind/zones/home.lan.db

6.2: My settings, change to your match your host names and ip-addresses:

; Use semicolons to add comments.
; Do NOT add empty lines.
; Host-to-IP Address DNS Pointers for home.lan
; Note: The extra “.” at the end of addresses are important.
; The following parameters set when DNS records will expire, etc.
; Importantly, the serial number must always be iterated upward to prevent
; undesirable consequences. A good format to use is YYYYMMDDII where
; the II index is in case you make more that one change in the same day.
home.lan. IN SOA ubuntu.home.lan. hostmaster.home.lan. (
    2008080901 ; serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)
; NS indicates that ubuntu is the name server on home.lan
; MX indicates that ubuntu is (also) the mail server on home.lan
home.lan. IN NS ubuntu.home.lan.
home.lan. IN MX 10 ubuntu.home.lan.
; Set the address for localhost.home.lan
localhost    IN A 127.0.0.1
; Set the hostnames in alphabetical order
print-srv    IN A 10.10.10.9
router       IN A 10.10.10.10
server       IN A 10.10.10.5
ubuntu       IN A 10.10.10.1
xbox         IN A 10.10.10.2

7.1: Create and edit the reverse lookup configuration file:
sudo nano /etc/bind/zones/rev.10.10.10.in-addr.arpa

7.2: My settings, reversed of the above:

; IP Address-to-Host DNS Pointers for the 10.10.10.0 subnet
@ IN SOA ubuntu.home.lan. hostmaster.home.lan. (
    2008080901 ; serial
    8H ; refresh
    4H ; retry
    4W ; expire
    1D ; minimum
)
; define the authoritative name server
           IN NS ubuntu.home.lan.
; our hosts, in numeric order
1         IN PTR ubuntu.home.lan.
2         IN PTR xbox.home.lan.
5         IN PTR server.home.lan.
9         IN PTR print-srv.home.lan.
10        IN PTR router.home.lan.

8: Restart bind to use the new settings:
sudo /etc/init.d/bind9 restart

9: Test that the dns lookups works with the local server:
host ping.sunet.se

The response should be:
ping.sunet.se has address 192.36.125.18
ping.sunet.se has IPv6 address 2001:6b0:7::18

10: Test that all of your computers are listed with the following command:
host -l home.lan

The output should list all of your entered hosts:

home.lan name server ubuntu.home.lan.
localhost.home.lan has address 127.0.0.1
print-srv.home.lan has address 10.10.10.9
router.home.lan has address 10.10.10.10
server.home.lan has address 10.10.10.5
ubuntu.home.lan has address 10.10.10.1
xbox.home.lan has address 10.10.10.2

11: Test that the reverse lookup works:

 host 10.10.10.1

Response:
1.10.10.10.in-addr.arpa domain name pointer ubuntu.home.lan.

Final words
Do not forget to update the serial every time you make any changes to a zone file.

Referenses:
BIND Caching Name Server Setup
BIND Master Server Setup