Pages

Sunday, January 23, 2011

DNS & DHCP

DNS & DHCP

This weekend I setup my DNS and DHCP again (updated to new version and changed the software). I am currently using the DNS and DHCP from ISC. There is nothing special about it, just the usual stuff. This configuration example will allow you to setup a normal DNS for caching and with a forward and reverse lookup zone, incl. access for rndc and updates from DHCP. The DHCP server will be configured with a small range of IP's and with access to update the DNS.
The domain will be karellen.local but you can use whatever you want. The DNS and DHCP server will be the same machine. It's name in this article is dns01. The network size is from 192.168.1.0 - 192.168.1.255, obviously the netmask is 255.255.255.0. The IP's from 192.168.1.1 - 192.168.1.199 I want to use as static IP's for my servers to play around. The IP's from 192.168.1.200 - 192.168.1.220 I want to use as DHCP range. Also the DNS acts caching, that means that all addresses that are not locally available will be externally resolved.

DNS

First create a dnssec key for rndc:

# dnssec-keygen -a hmac-md5 -b 64 -n HOST dns01.karellen.local
Kdns01.karellen.local.+157+19236


Run ls to check if the key was generated:

# ls
...
Kdns01.karellen.local.+157+19236.key
Kdns01.karellen.local.+157+19236.private
...


Where Kdns01.karellen.local.+157+19236.key is the public key and Kdns01.karellen.local.+157+19236.private is the private key. Run cat on the public key and note the key:

# cat Kdns01.karellen.local.+157+19236.key
dns01.karellen.local. IN KEY 512 3 157 o9EZuz8xSMk=


The key itself is o9EZuz8xSMk= (with the trailing =).
Now you're ready to configure named (all leading "spaces" must be "tabs"):

# vi /etc/named.conf
// GENERIC
options {
        directory "/var/named";
        forward first;
        forwarders {
                58.6.115.43;
        };
};

// KEYS
key "rndc_key" {
        algorithm hmac-md5;
        secret "o9EZuz8xSMk=";
};

// RNDC
controls {
        inet 127.0.0.1 allow { localhost; } keys { rndc_key; };
};

// ZONES
zone "0.0.127.in-addr.arpa" {
        type master;
        file "zones/0.0.127";
};

zone "karellen.local" {
        type master;
        notify no;
        file "zones/karellen.local";
};

zone "1.168.192.in-addr.arpa" {
        type master;
        notify no;
        file "zones/1.168.196";
};


The configuration file above has some basic option in the beginning followed by the rndc key.
Then configure the rndc:

# vi /etc/rndc.conf
key rndc_key {
        algorithm "hmac-md5";
        secret "o9EZuz8xSMk=";
};

options {
        default-server localhost;
        default-key    rndc_key;
};


There is nothing special about it, just the key and the server to control.
After that the 3 zone files must be created. First create the zones directory:

# mkdir -p /var/named/zones

Then create the zones file for localhost (all leading "spaces" must be "tabs"):

# vi /var/named/zones/0.0.127
$TTL 28800
@       IN      SOA     dns01.karellen.local.       root.karellen.local. (
                                1
                                8H
                                2H
                                4W
                                1D
                                )
                NS      dns01.karellen.local.
1               PTR     localhost.


Then the forward zone file for karellen.local (all leading "spaces" must be "tabs"):

# vi /var/named/zones/karellen.local
$TTL 28800
karellen.local             IN SOA  dns01.karellen.local. root.karellen.local. (
                                199804070
                                28800
                                7200
                                2419200
                                86400
                                )
                        NS      dns01.karellen.local.
                        A       192.168.1.20
                        MX      10 mail01.karellen.local.
dns01                   A       192.168.1.20
mail01                  A       192.168.1.23
kdc01                   A       192.168.1.26


The file above has some basic options about refresh etc. It also holds the NS record and the MX record. This is for the name server (dns01) and the mail exchanger (mail01). The last entry is a sample server (kdc01) with a A record and an IP.
The last file is the reverse zone file for karellen.local (all leading "spaces" must be "tabs"):

# cat /var/named/zones/1.168.196
$TTL 28800
1.168.192.in-addr.arpa  IN SOA  dns01.karellen.local. root.karellen.local. (
                                199803389
                                28800
                                7200
                                2419200
                                86400
                                )
                        NS      dns01.karellen.local.
20                      PTR     dns01.karellen.local.
23                      PTR     mail01.karellen.local.
26                      PTR     kdc01.karellen.local.


The reverse file just holds the NS again and the server from above.
Start named with the following command:

# /usr/sbin/named

Check if it is running:

# pgrep -fl named
8212 /usr/sbin/named


When it's not up and running, then check the logs. These can be /var/log/syslog, /var/log/messages or maybe /var/named/named.run. But this depends on your system.
Every time you add a host to your zones you need to reload the configuration:

# rndc reload
server reload successful


If you're running Slackware then make the RC script executable and start named with the RC script:

# chmod 755 /etc/rc.d/rc.bind
# /etc/rc.d/rc.bind start
...


DHCP

Before you start create a new denssec key so dhcpd can update your dns:

# dnssec-keygen -a hmac-md5 -b 64 -n HOST dns01.karellen.local
Kdns01.karellen.local.+157+39622


Run cat on the .key file and note the key again:

# cat Kdns01.karellen.local.+157+39622.key
dns01.karellen.local. IN KEY 512 3 157 xtOjYrrGcCw=


The new is xtOjYrrGcCw= and will be used to update the dns zones every time when a host requests a new IP via dhcp.
The configuration file for dhcpd is much smaller then the DNS configuration above. First create the dhcpd configuration file:

# vi /etc/dhcpd.conf
# GENERIC
default-lease-time 86400;
max-lease-time 604800;

# DDNS
ddns-update-style interim;
ddns-domainname "karellen.local";
update-static-leases true;
key dhcp_key {
        algorithm hmac-md5;
        secret "xtOjYrrGcCw=";
}

# ZONES
zone karellen.local. {
        primary 127.0.0.1;
        key dhcp_key;
}

zone 1.168.192.in-addr.arpa. {
        primary 127.0.0.1;
        key dhcp_key;
}

# LEASES
subnet 192.168.1.0 netmask 255.255.255.0 {
        option domain-name-servers 192.168.1.20;
        option domain-name "karellen.local";
        range 192.168.1.200 192.168.1.220;
        option routers 192.168.1.69;
}


The configuration above is very simple. It begins with the lease times and continues with section how to update the DNS. The last section defines the DHCP leases for the clients itself like the netmask, the DNS etc.
Before the dhcpd can update the dns the named configuration file has to updated once more with the new dhcp key:

# vi /etc/named.conf
...
// KEYS
key "rndc_key" {
        algorithm hmac-md5;
        secret "o9EZuz8xSMk=";
};

key "dhcp_key" {
        algorithm hmac-md5;
        secret "xtOjYrrGcCw=";
};
...


Next reload the named configuration:

# rndc reload
server reload successful


Now start the dhcp server and check if it's running:

# /usr/sbin/dhcpd
...
# pgrep -fl dhcpd
15295 /usr/sbin/dhcpd


If it is not up and running, check the logs again.
If you're running Slackware then create the following RC script:

# vi /etc/rc.d/rc.dhcpd
#!/bin/bash
bin="/usr/sbin/dhcpd"
pid_file="/var/run/dhcpd.pid"

function start_dhcpd {
  echo "Starting dhcpd: $bin -pf $pid_file"
  $bin -pf $pid_file
}

function stop_dhcpd {
  if [[ -f $pid_file ]]; then
    kill -15 `cat $pid_file`
    sleep 1
    if [[ `ps -ef | grep "$bin" | grep \`cat $pid_file\`` == "" ]]; then
      rm $pid_file
    else
      kill -9 `cat $pid_file`
      rm $pid_file
    fi
  fi
}

case "$1" in
  'start')
    start_dhcpd
    ;;
  'stop')
    stop_dhcpd
    ;;
  'restart')
    stop_dhcpd
    start_dhcpd
    ;;
  *)
    echo "usage $0 start|stop|restart"
    ;;
esac


Make it executable and start it:

# chmod 755 /etc/rc.d/rc.dhcpd
# /etc/rc.d/rc.dhcpd start
...


To start rc.dhcpd automatically during boot add it to /etc/rc.d/rc.inet2 right after eg. rc.bind:

# vi /etc/rc.d/rc.inet2
...
# Start the BIND name server daemon:
if [ -x /etc/rc.d/rc.bind ]; then
  /etc/rc.d/rc.bind start
fi

# Start dhcpd:
if [ -x /etc/rc.d/rc.dhcpd ]; then
  /etc/rc.d/rc.dhcpd start
fi
...


To test if the DHCP server is working in general, run nmap with the dhcp-discover script:

# nmap --script broadcast-dhcp-discover

Starting Nmap 7.40 ( https://nmap.org ) at 2011-01-23 12:46 CET
Pre-scan script results:
| broadcast-dhcp-discover:
|   Response 1 of 1:
|     IP Offered: 192.168.1.220
|     DHCP Message Type: DHCPOFFER
|     Server Identifier: 192.168.1.2
|     IP Address Lease Time: 5m00s
|     Subnet Mask: 255.255.255.0
|     Router: 192.168.1.69

|     Domain Name Server: 192.168.1.20
|_    Domain Name: karellen.local
WARNING: No targets were specified, so 0 hosts scanned.
Nmap done: 0 IP addresses (0 hosts up) scanned in 3.81 seconds


If you request an IP over DHCP now then the DHCP server updates the DNS with the leased IP and the hostname of the client:

# dhcpcd eth0
...


# nslookup nb001
Server:         192.168.1.20
Address:        192.168.1.20#53

Name:   nb001.karellen.local
Address: 192.168.1.200


And check your /etc/resolv.conf:

# cat /etc/resolv.conf
# Generated by dhcpcd from eth0
# /etc/resolv.conf.head can replace this line
domain karellen.local
nameserver 192.168.1.20
# /etc/resolv.conf.tail can replace this line


Or just use dig:

# dig +search kdc01
...
;; QUESTION SECTION:
;kdc01.karellen.local.           IN      A
;; ANSWER SECTION:
kdc01.karellen.local.    28800   IN      A     192.168.1.26
;; AUTHORITY SECTION:
karellen.local.          28800   IN      NS    dns01.karellen.local.
;; ADDITIONAL SECTION:
dns01.karellen.local.    28800   IN      A     192.168.1.20
...

# dig -x 192.168.1.26
...
;; QUESTION SECTION:
;26.1.168.192.in-addr.arpa.      IN      PTR
;; ANSWER SECTION:
26.1.168.192.in-addr.arpa. 28800 IN      PTR   kdc01.karellen.local.
;; AUTHORITY SECTION:
1.168.192.in-addr.arpa.    28800 IN      NS    dns01.karellen.local.
;; ADDITIONAL SECTION:
dns01.karellen.local.      28800 IN      A     192.168.1.20
...


Updated 03/27/2014: nearly complete rewritten

1 comment: