HOWTO Configure Dynamic DNS

HOWTO Configure Dynamic DNS

From Consultancy.EdVoncken.NET

Jump to: navigation, search

In this example, we will set up a DNS Master and DNS Slave server, on 192.168.123.1 and 192.168.123.2 respectively.

The configuration will also allow for Dynamic DNS updates from our DHCP servers.

Contents

Installation

Install the following packages, for example using yum:

 bind
 bind-chroot
 bind-utils

This example is based on bind-9.3.4-10.P1.el5_3.1.

Configuration

The configuration and data files for the chroot()-ed BIND DNS server can be found under /var/named/chroot/. Under /etc, you will find a symlink pointing to /var/named/chroot/etc/named.conf.

DNS Keys

For Dynamic DNS to work, the updates need to be "signed" using a transaction key. Since this is a symmetric key, it has to be shared between DNS and DHCP. It must be protected to prevent unauthorized changes being made to your DNS zones. The key has to be available on both DHCP servers. Generate the key as follows:

 # cd /tmp
 # dnssec-keygen -a HMAC-MD5 -b 512 -n HOST ddns-update

These commands generate a set of .key and .private files in the current working directory. Move these files to a better name and location:

 # mv Kddns-update.*.key /etc/ddns-update.key
 # cat /etc/ddns-update.key 
 ddns-update. IN KEY 512 3 157 K3EaOD3IysiC/D7lIXp+4hrYGDLyIq6la[...]9oE4kZ3O1ZFxKSMHfwG5YvUkYE7gxMHCmCg==
 
 # mv Kddns-update.*.private /etc/ddns-update.private
 # cat /etc/ddns-update.private 
 Private-key-format: v1.2
 Algorithm: 157 (HMAC_MD5)
 Key: K3EaOD3IysiC/D7lIXp+4hrYGDLyIq6la[...]9oE4kZ3O1ZFxKSMHfwG5YvUkYE7gxMHCmCg==

Note that the actual private and public keys are identical for HMAC-MD5. This is normal. The .key and .private files are needed by the nsupdate utility, later on.

We now need create a configuration file in a different format, for use by the DHCP and DNS servers- we will call this file /etc/ddns-update.dnskey. The syntax is identical to the /etc/rndc.key file. We need to set the key name and the key value properly:

 # cat /etc/ddns-update.dnskey 
 key "ddns-update" {
       algorithm	hmac-md5;
       secret "K3EaOD3IysiC/D7lIXp+4hrYGDLyIq6la[...]9oE4kZ3O1ZFxKSMHfwG5YvUkYE7gxMHCmCg==";
 };

Make sure it has the proper ownership and permissions:

 # ls -l /etc/ddns-update.dnskey
 -rw-r----- 1 root named 145 Jul  9 12:25 ddns-update.dnskey

On the Primary DHCP / Master DNS server, the key needs to be available both as /etc/ddns-update.dnskey (for DHCP) and /var/named/chroot/etc/ddns-update.dnskey (for DNS). Creating a symlink will not work due to the SElinux policy; you will have to copy the file instead, so each copy has its own SElinux context:

 # cp /etc/ddns-update.dnskey /var/named/chroot/etc/
 # ls -lZ /etc/ddns-update.dnskey /var/named/chroot/etc/ddns-update.dnskey 
 -rw-r-----  root root  root:object_r:etc_t              /etc/ddns-update.dnskey
 -rw-r-----  root named root:object_r:named_conf_t       /var/named/chroot/etc/ddns-update.dnskey

DNS Master configuration

On the Master, we will define all zones that we are authoritative for. We will also allow DNS updates to these zones from our DHCP servers.

 # ISC BIND Configuration File
 #
 # Purpose:
 #   Configure BIND as caching/forwarding nameserver with authority
 #   for local networks as well as support for Dynamic DNS Updates
 #
 # File $Id: named.conf,v 1.4 2009/07/07 12:59:12 root Exp root $
 
 options {
       directory "/etc";
       pid-file "/var/run/named/named.pid";
       forwarders {
               // Put your ISP's DNS servers here
               66.159.123.200;
               66.159.123.201;
       };
       allow-query { localhost; localnets; };
 };
 
 # Key used by DHCP servers for Dynamic DNS Updates
 include "/etc/ddns-update.dnskey";
 
 zone "example.local" {
       type master;
       file "/var/named/data/example.local.zone";
       allow-transfer { 192.168.123.2; };
       allow-update { key "ddns-update"; };
 };
 
 zone "123.168.192.in-addr.arpa" {
       type master;
       file "/var/named/data/192.168.123.zone";
       allow-transfer { 192.168.123.2; };
       allow-update { key "ddns-update"; };
 };
 
 # EOF
SELinux Note: On the DNS Master, use the "data" sub-directory to store zone files.
Otherwise, you will see errors while trying to create journal files on the Master.

DNS Slave configuration

You can have multiple DNS Slave servers. Each will perform a zone transfer regularly, keeping the data in sync.

Dynamic DNS updates, originating from our DHCP servers are sent to the DNS Master only.

 # ISC BIND Configuration File
 #
 # Purpose:
 #   Configure BIND as caching/forwarding slave nameserver
 #
 # File $Id: named.conf,v 1.4 2009/07/08 02:02:19 root Exp $
 
 options {
       directory "/etc";
       pid-file "/var/run/named/named.pid";
       forwarders {
               // Put your ISP's DNS servers here
               66.159.123.200;
               66.159.123.201;
       };
       allow-query { localhost; localnets; };
       allow-notify { 192.168.123.2; };
 };
 
 # Dynamic DNS Updates are only sent to the Primary DNS
 
 zone "example.com" {
       type slave;
       masters { 192.168.123.1; };
       file "/var/named/slaves/example.com.zone";
 };
 
 zone "123.168.192.in-addr.arpa" {
       type slave;
       masters { 192.168.123.1; };
       file "/var/named/slaves/192.168.123.zone";
 };

The "allow-notify" option prevents BIND from generating error messages as it apparently tries to notify itself of updates. Go figure ;-)

SELinux Note: On the DNS Slave, use the "slaves" sub-directory to store data from the DNS Master.
Otherwise, you will get a "permission denied" error on the Slave while trying to transfer the zones from the Master.

DNS Zone files

On the DNS Master, we create a minimal set of zone files (forward and reverse zones). Entries will be managed either by DHCP or nsupdate.

/var/named/data/example.local.zone:

 ; DO NOT EDIT MANUALLY - use the "nsupdate" utility to prevent data loss
 ;
 $ORIGIN example.local.
 $TTL 86400	; 1 day
 @		IN SOA	ns1.example.local. hostmaster.example.local. (
 				2009074711 ; serial
 				7200       ; refresh (2 hours)
 				300        ; retry (5 minutes)
 				604800     ; expire (1 week)
 				60         ; minimum (1 minute)
 				)
 		IN	NS	ns1.example.local.
 		IN	NS	ns2.example.local.
 ns1		IN	A	192.168.123.1
 ns2		IN	A	192.168.123.2

/var/named/data/192.168.123.zone:

 ; DO NOT EDIT MANUALLY - use the "nsupdate" utility to prevent data loss
 ;
 $ORIGIN 123.168.192.in-addr.arpa.
 $TTL 86400	; 1 day
 @		IN	SOA	ns1.example.local. hostmaster.example.local. (
 				2009074711 ; serial
 				7200       ; refresh (2 hours)
 				300        ; retry (5 minutes)
 				604800     ; expire (1 week)
 				60         ; minimum (1 minute)
 				)
 		IN	NS	ns1.example.local.
 		IN	NS	ns2.example.local.
 1		IN	PTR	ns1.example.local.
 2		IN	PTR	ns2.example.local.

Miscellaneous

Client configuration

On RHEL/CentOS/Fedora clients, you should edit /etc/sysconfig/network-scripts/ifcfg-eth0 and set the DHCP_HOSTNAME variable to the short hostname of your machine. The client will now send its hostname to the DHCP server during IP address negotiation. The DHCP_HOSTNAME is used for updating Dynamic DNS. Sample:

 # Sample Network Device
 DEVICE=eth0
 HWADDR=00:16:de:ad:be:ef
 ONBOOT=yes
 BOOTPROTO=dhcp
 DHCP_HOSTNAME=demo01

Using nsupdate to add or remove DNS entries

Adding a host (A and PTR records)

 # nsupdate -k /etc/ddns-update.key
 > update add gateway.example.local 38400 A 192.168.123.254
 > 
 > update add 254.123.168.192.in-addr.arpa. 38400 PTR gateway.example.local.
 >
 > quit

Note: The empty line is necessary, it sends the update to DNS. Since we are adding records to two different zones, we need to send two separate updates.

Deleting a host (A and PTR records)

 # nsupdate -k /etc/ddns-update.key 
 > update delete gateway.example.local IN A 192.168.123.254
 > 
 > update delete 254.123.168.192.in-addr.arpa PTR gateway.example.local.
 > 
 > quit

Adding a mail-host (MX records)

The domain "example.local" wishes to use "mail.example.local" as their primary mail host.

We first need to add the standard A and PTR records for the mailhost (TTL 86400 seconds), followed by the MX record for the domain:

 # nsupdate -k /etc/ddns-update.key 
 > update add mail.example.nl 86400 IN A 192.168.123.25
 > 
 > update add 25.123.168.192.in-addr.arpa. 86400 PTR mail.example.local.
 > 
 > update add example.local 86400 MX 10 mail.example.local.
 > 
 > quit

Note: The mailhost should of course be accessible from the Internet and use a routable IP address instead of an RFC1918 address.

Verify the results using 'dig':

 # dig example.local MX
 
 ; <<>> DiG 9.3.4-P1 <<>> example.local MX
 ;; global options:  printcmd
 ;; Got answer:
 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15733
 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3
 
 ;; QUESTION SECTION:
 ;example.local.			IN	MX
 
 ;; ANSWER SECTION:
 example.local.		86400	IN	MX	10 mail.example.local.
 
 ;; AUTHORITY SECTION:
 example.local.		86400	IN	NS	ns2.example.local.
 example.local.		86400	IN	NS	ns1.example.local.
 
 ;; ADDITIONAL SECTION:
 mail.example.local.	86400	IN	A	192.168.123.25
 ns1.example.local.	86400	IN	A	192.168.123.1
 ns2.example.local.	86400	IN	A	192.168.123.2
 
 ;; Query time: 1 msec
 ;; SERVER: 127.0.0.1#53(127.0.0.1)
 ;; WHEN: Fri Jul 31 11:34:29 2009
 ;; MSG SIZE  rcvd: 134

Deleting a mail-host (MX records)

If we wish to remove the mail-host, just delete the MX, A and PTR records:

 # nsupdate -k /etc/ddns-update.key 
 > update delete example.local MX 10 mail.example.local.
 > 
 > update delete mail.example.local IN A 192.168.123.25
 > 
 > update delete 25.123.168.192.in-addr.arpa PTR mail.example.local.
 > 
 > quit

Note: Mail may continue to be delivered to the old mailhost until the TTL expires!

Debugging

During development, you may want to enable some extra logging in /etc/named.conf:

 logging {
       channel update_debug {
               file "/var/named/data/named-update.log";
               severity  debug 3;
               print-category yes;
               print-severity yes;
               print-time     yes;
       };
 
       channel security_info    {
               file "/var/named/data/named-auth.log";
               severity  debug 3;
               print-category yes;
               print-severity yes;
               print-time     yes;
       };
 
       category update { update_debug; };
       category security { security_info; };
 };

Starting the service

On both Master and Slave DNS, start the BIND nameserver:

 # chkconfig named on
 # service named start

References

See Also

Navigation