HOWTO Configure Dynamic DNS
From Consultancy.EdVoncken.NET
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
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 ;-)
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
- http://www.howtoforge.com/how-to-set-up-dhcp-failover-on-centos5.1
- http://www.revsys.com/writings/quicktips/bind-permission.html
- http://www.semicomplete.com/articles/dynamic-dns-with-dhcp/
- http://www.ops.ietf.org/dns/dynupd/secure-ddns-howto.html
See Also
Navigation
- HOWTO Design a fault-tolerant DHCP + DNS solution
- HOWTO Configure DHCP failover
- HOWTO Configure Dynamic DNS
- HOWTO Manage Dynamic DNS with nsupdate