[ login  ]
Path: Root » FreeBSD » Dynamic DNS

Dynamic Domain Name Server

Howto setup a dynamic dns (DDNS) server on FreeBSD by combining the isc (DHCP / dhcpd) and bind (DNS) daemons.

Introduction

Afther reading this howto you know how to setup a DDNS server, that is a combination of a DNS and a DHCP server. The DNS server will update the record in the DNS server when a host ask for an ip address. You should know the basis on howto setup a DNS and DHCP server.

DNS server

A DNS server comes installed with FreeBSD. All we have to do is set it up. Since the handbook covers this excellent here , so I'm not going to repeat this. All I'm going to cover is the specific configuration needed for our goals.

To have you DNS server accept commands from the DHCP server we need to modify the /etc/named/named.conf do two things:

  1. Write the key down
  2. Assign the key to certain domains.
key DHCP_UPDATER {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret pRP5FapFoJ95JEL06sv4PQ==;
};

zone "lan" {
type master;
file "lan";
allow-update { key DHCP_UPDATER; };
};

zone "31.168.192.in-addr.arpa" {
type master;
file "lan.rev";
allow-update { key DHCP_UPDATER; };
};

Now you have to restart you dns with ndc restart and you can move on the DHCP section of this article. Here I have a complete DNS configuration.

DHCP server

The first step is to install a DHCP server. I have chosen the server of ISC is used mostly and for fills my needs. If you have the portupgrade port installed you can do:

portinstall net/isc-dhcpd

Otherwise you have to do the following:

cd /usr/ports/net/isc-dhcpd
make config && make install && make clean

Since a DHCP server gives out leases on IP addresses the first thing that need to be setup up is to the leases mechanism. You need to think about how to divide the available IP addresses first. I decided to split it in to tree group: dynamic ip addresses of known clients, dynamic addresses of unknown clients and static addresses handed out in a dynamic way. The DHCP server allows the ranges to start and end from any IP as long as the later is larger then the former. You should take the domains of a firewall in account, if you have one or planning one. My ranges have a size of the number that is a power of 2.

Known client form the first group for our DHCP server. This gives you some control about what is going on your network. One use for this is to allow only trusted computers access to certain servers with sensitive data on it. Another is to prevent or limit access to the internet.

Unknown clients form the second group for our DHCP server. This could be a notebook to transfer some files to a workstation. But it could also be a cracker who likes to send spam using you SMTP server on your wireless network to send spam on you behalf.

The third and final group are certain server that require static IP addresses to function. A example of this is you only DHCP server on the network, a gateway or some other server that might be referred to by its IP-address.

When you divide the IP range you have to take in to account the way the network might grow. I expect the known clients on my network to grow in sucha way that they will be the largest group on the network. So I come to this division:

subnet 10.0.0.0 netmask 255.255.255.0 {
option domain-name "lan";
option domain-name-servers 10.0.0.1;
option routers 10.0.0.2;
option subnet-mask 255.255.255.0;
option broadcast-address 10.0.0.255;

With this we configure some common network settings. The FQDN can be formed with the domain-name set here and the hostname provided by the client. The remaining configuration tells the client where the routers and domain name server can be found and what the subnet-mask and broadcast-address is.

pool {
range 10.0.0.64 10.0.0.127;
deny known clients;
}

pool {
range 10.0.0.128 10.0.0.254;
deny unknown clients;
}
}

Unknown clients are the only ones that are allowed to use the first pool and known clients are the only ones allowed by the second pool, because of the deny statements in the pool. Did you notice that there isn't a pool for the static IP-addresses? This is because pools are only used for dynamic IP-addresses.

DDNS-update-style interim;

key DHCP_UPDATER {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret pRP5FapFoJ95JEL06sv4PQ==;
};

zone lan. {
primary 127.0.0.1;
secondary 10.0.0.2;
key DHCP_UPDATER;
}

zone 0.0.10.in-addr.arpa. {
primary 127.0.0.1;
secondary 10.0.0.2;
key DHCP_UPDATER;
}

This is key in how to make the DHCP server do updates to the DNS server! The DHCP server need to know the zones in which it needs to do updates, to which DNS they belong and the key that the DNS server requires to do updates to that zone.

group {
host StaticServer {
hardware ethernet 00:50:bf:d9:79:96;
fixed-address 10.0.0.3;
DDNS-hostname StaticServer;
}

Static IP-addresses can be configured in the DHCP server with the host block, along with a fixed hostname. The host block is identified by the MAC address of the NIC. How you can find out what the MAC address is of a NIC is beyond the scope of this article. (Two ways are to look at the output of ipconfig/ifconfig or see if its written on the NIC card it self.)

update-static-leases on;
}

Normally the DHCP server only makes updates in the DNS for hostnames that have dynamic IP addresses. The update-static-leases flags forces the DHCP server to also do updates for static IP-addresses that it hand outs. ISC doesn't recommend this because of the load it can cause on the DHCP server. They wrote in there manual: "It is not recommended because the DHCP server has no way to tell that the update has been done, and therefore will not delete the record when it is not in use. Also, the server must attempt the update each time the client renews its lease, which could have a sig- nificant performance impact in environments that place heavy demands on the DHCP server." However, without this the DHCP will give out static IP-addresses without updating the DNS. You also have to edit the DNS configuration file if you leave this out.

All that is recurred to make a working DHCP server is a startup script. These are place in the directory /usr/local/etc/rc.d/ on FreeBSD. You could create a file named isc-dhcpd.sh in this directly. You have to make sure it belongs to root and has the execution flag set. After this you can edit the file to you liking. Or you could just simple copy the sample file provided by ISC. Which is what I've done.

cd /usr/local/etc/rc.d/
cp isc-dhcpd.sh.sample isc-dhcpd.sh
chmod 755 isc-dhcpd.sh

Testing

You should now test you configuration. For this you must kill the dhcpd daemon, if you have one running, and start it again with the debug option. This forces it to run on the foreground. If you don't want this you could override this, so that the daemon still serves request when your connection is dropped.

killall dhcpd; dhcpd -d &

This is the result you should see when the DHCP server handout a static IP-address:

Added new forward map from StaticServer.lan to 10.0.0.3
added reverse map from 3.0.0.10.in-addr.arpa. to NTserver.lan
DHCPREQUEST for 10.0.0.3 from 00:50:bf:d9:79:96 via xl0
DHCPACK on 10.0.0.3 to 00:50:bf:d9:79:96 via xl0

This is the result given by the DHCP server when its handout a dynamic IP-address:

DHCPDISCOVER from 00:30:c1:61:8b:8b via xl0
DHCPOFFER on 10.0.0.128 to 00:50:bf:d9:79:96 via xl0
Added new forward map from NTserver.lan to 10.0.0..128
added reverse map from 128.0.0.10.in-addr.arpa. to NTserver.lan
DHCPREQUEST for 10.0.0.0.128 (.....) from 00:50:bf:d9:79:96 via xl0
DHCPACK on 10.0.0.128 to 00:50:bf:d9:79:96 via xl0

Configuration examles

DNS configuration

options {
directory "/etc/namedb";
allow-query { localnets; };
allow-recursion { localnets; };
allow-transfer { localnets; };
};

zone "." {
type hint;
file "named.root";
};

zone "0.0.127.IN-ADDR.ARPA" {
type master;
file "localhost.rev";
};

// RFC 3152
zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA" {
type master;
file "localhost-v6.rev";
};

key DHCP_UPDATER {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret pRP5FapFoJ95JEL06sv4PQ==;
};

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

category update { update_debug; };
category security { security_info; };
};

zone "lan" {
type master;
file "lan";
allow-update { key DHCP_UPDATER; };
};

zone "31.168.192.in-addr.arpa" {
type master;
file "lan.rev";
allow-update { key DHCP_UPDATER; };
};

DHCP configuration

DDNS-update-style interim;

key DHCP_UPDATER {
algorithm HMAC-MD5.SIG-ALG.REG.INT;
secret pRP5FapFoJ95JEL06sv4PQ==;
};

zone lan. {
primary 127.0.0.1;
secondary 10.0.0.2;
key DHCP_UPDATER;
}

zone 0.0.10.in-addr.arpa. {
primary 127.0.0.1;
secondary 10.0.0.2;
key DHCP_UPDATER;
}

subnet 10.0.0.0 netmask 255.255.255.0 {
do-forward-updates true;

option domain-name "lan";
option domain-name-servers 10.0.0.1;
option routers 10.0.0.2;
option subnet-mask 255.255.255.0;
option broadcast-address 10.0.0.255;

pool {
range 10.0.0.64 10.0.0.127;
allow unknown clients;
deny known clients;
}

pool {
range 10.0.0.128 10.0.0.254;
allow known clients;
deny unknown clients;
}
}

group {
update-static-leases on;

host StaticServer {
hardware ethernet 00:50:bf:d9:79:96;
fixed-address 10.0.0.3;
ddns-hostname StaticServer;
}
}