Installing,configuring DNS,DHCP and Dynamic DNS on CENTOS 7

Posted: May 28, 2015 in Linux

In this article i will show you how to set-up DNS and DHCP server,and how to configure Dynamic DNS.

So,let’s jump in !

We’ll install DNS server in secluded environment.

The chroot is a process of creating a virtualized environment in Linux, separating it from operating system and directory structure. This creates a confined space, with its own root directory, to run software programs. Software program run in this environment cannot access files outside of that directory tree. This confined virtual environment is often called a “chroot jail”.

Install packages:

yum install bind-chroot bind-utils -y

Then edit /etc/named.conf.file

acl “allowed” {//create acl named allowed,to specify who can search our DNS server
192.168.122.0/24;
localhost;};
options {
listen-on port 53 { 192.168.122.200;127.0.0.1; };  //On which interfaces bind server will listen for requests
listen-on-v6 port 53 { ::1; };
directory “/var/named”;
dump-file “/var/named/data/cache_dump.db”;
statistics-file “/var/named/data/named_stats.txt”;
memstatistics-file “/var/named/data/named_mem_stats.txt”;
allow-query { allowed; };
forwarders {8.8.8.8;}; //forward all requests to Google server
recursion yes; //(the default) the server will always provide recursive query  if requested by the client
allow-recursion {allowed;}; //who can access DNS server cache
dnssec-enable no;   // disable maintaining the data integrity of DNS responses.
dnssec-validation no; //disable DNS query validation
dnssec-lookaside auto;

/* Path to ISC DLV key */
bindkeys-file “/etc/named.iscdlv.key”;

managed-keys-directory “/var/named/dynamic”;

pid-file “/run/named/named.pid”;
session-keyfile “/run/named/session.key”;
};

logging {
channel default_debug {
file “data/named.run”;
severity dynamic;
};
};

zone “.” IN {
type hint;
file “named.ca”;
};
include “/etc/named.rfc1912.zones”;
include “/etc/named.root.key”;
zone “122.168.192.in-addr.arpa” IN {
//this is our reverse lookup zone (translate IP address to names)
type master;         //it takes reverse IP of our network (192.168.122.)
file “/var/named/chroot/etc/named/reverse.example.com.db”;
//this is zone file we will created later
allow-update {none;};   //don’t allow dynamic zone updates (default) we will enable it later
};
zone “example.com” IN {  //forward lookup zone (example.com)
type master;
file “/var/named/chroot/etc/named/example.com.db”;
//zone file name and location,will be created latter
allow-update {none;};  //no Dynamic DNS
};

check config files for typo errors:

[root@server1 dhcpd]# named-checkconf /etc/named.conf

of course,at this moment it’ll throw errors that files example.com and reverse.example.com.db

cannot be found,they don’t exist (yet).

It’s high time now to create these files.

Template zone file is located at /usr/share/doc/bind-9.9.4/sample/var/named/named.localhost

we can use it as a template for our zone files.

Copy that file to /var/named/chroot/etc/named/ and save as example.com.db

cp  /usr/share/doc/bind-9.9.4/sample/var/named/named.localhost /var/named/chroot/etc/named/example.com.db

open example.com.db file in your favorite text editor and start editing:

@ IN SOA server1.example.com. root.example.com. (

2015052601 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum

@ IN NS server1.example.com.
server1 IN A 192.168.122.200

Lets’s “decipher” these entries

@ means this zone

SOA:The SOA record stores information about the name of the server that supplied the data for the zone

root.example.com. (don’t forget period at the end) is mail address resposibile person for zone

(although it dosen’t seems as e-mail address),remeber @ means “this zone in this case 🙂

2015052601 is serial zone number.It’s purpose in DNS zone files is to provide a way for the server to verify that the contents of a zone file are up-to-date. If the serial number in a zone file hasn’t changed since that zone was last loaded, named figures that it can ignore the file.I put datetime as number,followed with 01 at the end,you can put any number you like

Refresh: Indicates the time when the slave will try to refresh the zone from the master (if we have another DNS server which transfers zone files from master server)

Retry:Defines the time between retries if the slave (secondary) fails to contact the master when refresh (above) has expired

Expire:Indicates when the zone data are considered incorrect by slave server,then slave tries to get update from master server

Minimum: defines the duration in seconds that the record may be cached

We don’t have slave server so accept default values

@ IN NS server1.example.com. don’t forget period at the end,if you ommit it then server name would

be appended at the end (server1.example.com.server1-is Name server for zone (our server)
server1 IN A 192.168.122.200  host (A) record our server

Copy that file as reverse.example.com.db (zone file for our reverse lookup zone)
@ IN SOA server1.example.com. root.example.com. (
2015052601 ; serial
1D ; refresh
1H ; retry
1W ; expire
3H ) ; minimum
@ IN NS server1.example.com.
server1 IN A 192.168.122.200
200 IN PTR server1.example.com

200 IN PTR server1.example.com is PTR record for our server (last octet of IP address 192.168.122.200)

Check both files for errors

[root@server1 dhcpd]# named-checkconf /var/named/chroot/etc/named/example.com.db

named-checkconf /var/named/chroot/etc/named/reverse.example.com.db

Open firewall port (53)

[root@server1 dhcpd]#firewall-cmd –zone=public –add-service=dns –permanent

[root@server1 dhcpd]#firewall-cmd –reload

set folder permissons

[root@server1 dhcpd]#chown named:named -Rf /var/named/chroot/etc/named/

[root@server1 dhcpd]#chmod 775 -Rf /var/named/chroot/etc/named/

restart named service

[root@server1 dhcpd]#systemctl restart named

and check if service listens on port 53:

Untitled5

Point client computer to our DNS server:

Edit interface file in /etc/sysconfig/network-scripts/

TYPE=”Ethernet”
BOOTPROTO=”static”
DEFROUTE=”yes”
IPADDR=192.168.122.100
NETMASK=255.255.255.0
GATEWAY=192.168.122.1
IPV4_FAILURE_FATAL=”no”
IPV6INIT=”yes”
IPV6_AUTOCONF=”yes”
IPV6_DEFROUTE=”yes”
IPV6_FAILURE_FATAL=”no”
NAME=”ens3″
DNS1=192.168.122.200
UUID=”405213a0-56f5-4d45-b21e-244b19f7c3ef”
ONBOOT=”yes”
HWADDR=”52:54:00:14:3f:47″
PEERDNS=”yes”
PEERROUTES=”yes”
IPV6_PEERDNS=”yes”
IPV6_PEERROUTES=”yes”

restart network service and test DNS server:

[root@localhost ~]# dig skins.be

; <<>> DiG 9.9.6-RedHat-9.9.6-4.fc21 <<>> skins.be
;; global options: +cmd
;; Got answer:
;; ->>HEADER< ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 13, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;skins.be. IN A

;; ANSWER SECTION:
skins.be. 3547 IN A 213.131.234.8

—-output cut———-

search our zone,example,com:

[root@localhost ~]# dig example.com

; <<>> DiG 9.9.6-RedHat-9.9.6-4.fc21 <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER< ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;example.com. IN A

;; AUTHORITY SECTION:
example.com. 10800 IN SOA server1.example.com. root.example.com. 2015052607 86400 3600 604800 10800

;; Query time: 1 msec
;; SERVER: 192.168.122.200#53(192.168.122.200)
;; WHEN: Wed May 27 18:53:21 EDT 2015
;; MSG SIZE rcvd: 89

So far so good,

Lets now

Install and configure DHCP server:

Install dhcp package

yum install dhcp -y

Then copy dhcpd.conf.example in /etc/dhcp folder:

cp  /usr/share/doc/dhcp-4.2.5/dhcpd.conf.example /etc/dhcp/dhcpd.conf

Here is dhcpd.conf file:

dhcpd.conf
#
# Sample configuration file for ISC dhcpd
#

# option definitions common to all supported networks…
option domain-name “example.com”;
option domain-name-servers 192.168.122.200;

default-lease-time 600;
max-lease-time 7200;

# Use this to enble / disable dynamic dns updates globally.
#ddns-update-style none;

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

# No service will be given on this subnet, but declaring it helps the
# DHCP server to understand the network topology.

#subnet 10.152.187.0 netmask 255.255.255.0 {
#}

# This is a very basic subnet declaration.

#subnet 10.254.239.0 netmask 255.255.255.224 {
# range 10.254.239.10 10.254.239.20;
# option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
#}

# This declaration allows BOOTP clients to get dynamic addresses,
# which we don’t really recommend.

#subnet 10.254.239.32 netmask 255.255.255.224 {
# range dynamic-bootp 10.254.239.40 10.254.239.60;
# option broadcast-address 10.254.239.31;
# option routers rtr-239-32-1.example.org;
#}

# A slightly different configuration for an internal subnet.
subnet 192.168.122.0 netmask 255.255.255.0 {   //our subnet
range 192.168.122.10 192.168.122.20;         //range
option domain-name-servers 192.168.122.200;
option domain-name “example.com”;
option routers 192.168.122.1;
option broadcast-address 192.168.122.255;
default-lease-time 600;
max-lease-time 7200;

}

# Hosts which require special configuration options can be listed in
# host statements. If no address is specified, the address will be
# allocated dynamically (if possible), but the host-specific information
# will still come from the host declaration.

host passacaglia {
hardware ethernet 0:0:c0:5d:bd:95;
filename “vmunix.passacaglia”;
server-name “toccata.fugue.com”;
}

# Fixed IP addresses can also be specified for hosts. These addresses
# should not also be listed as being available for dynamic assignment.
# Hosts for which fixed IP addresses have been specified can boot using
# BOOTP or DHCP. Hosts for which no fixed address is specified can only
# be booted with DHCP, unless there is an address range on the subnet
# to which a BOOTP client is connected which has the dynamic-bootp flag
# set.

host fantasia {
hardware ethernet 08:00:07:26:c0:a5;
fixed-address fantasia.fugue.com;
}

# You can declare a class of clients and then do address allocation
# based on that. The example below shows a case where all clients
# in a certain class get addresses on the 10.17.224/24 subnet, and all
# other clients get addresses on the 10.0.29/24 subnet.

class “foo” {
match if substring (option vendor-class-identifier, 0, 4) = “SUNW”;
}

shared-network 224-29 {
subnet 10.17.224.0 netmask 255.255.255.0 {
option routers rtr-224.example.org;
}
subnet 10.0.29.0 netmask 255.255.255.0 {
option routers rtr-29.example.org;
}
pool {
allow members of “foo”;
range 10.17.224.10 10.17.224.250;
}
pool {
deny members of “foo”;
range 10.0.29.10 10.0.29.230;
}
}

check file for errors:
[root@server1 dhcpd]# dhcpd -cf /etc/dhcp/dhcpd.conf

If you didn’t installed this server on KVM switch (and set virtual adapter to receive address from host DHCP),you can start DHCP service.

Othervise,we must first disable DHCP service on interface,othervise,our client won’t receive DHCP DIscover and DHCP offer packets from our DHCP server but from KVM host,and our log file will be receiving

“Unknown lease” .

in terminal,type

root@host # virsh

virsh # net-destroy yournetwork
virsh # net-edit yournetwork
[remove the element, save, exit]
virsh # net-start yournetwork

Restart your Virtual machine and then start dhcp service on KVM virtual machine (server1.example.com)

[root@server1 dhcpd]# systemctl restart dhcpd

Configure client to receive address from our DHCP server:

Edit interface file:

TYPE=”Ethernet”
BOOTPROTO=“dhcp”
DEFROUTE=”yes”
IPV4_FAILURE_FATAL=”no”
IPV6INIT=”yes”
IPV6_AUTOCONF=”yes”
IPV6_DEFROUTE=”yes”
IPV6_FAILURE_FATAL=”no”
NAME=”ens3″
UUID=”405213a0-56f5-4d45-b21e-244b19f7c3ef”
ONBOOT=”yes”
HWADDR=”52:54:00:14:3f:47″
PEERDNS=”yes”
PEERROUTES=”yes”
IPV6_PEERDNS=”yes”
IPV6_PEERROUTES=”yes”

restart network,and type ifconfig:

root@localhost ~]# ifconfig

ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.122.11 netmask 255.255.255.0 broadcast 192.168.122.255
inet6 fe80::5054:ff:fe14:3f47 prefixlen 64 scopeid 0x20 ether 52:54:00:14:3f:47 txqueuelen 1000 (Ethernet)
RX packets 676 bytes 72259 (70.5 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2222 bytes 142855 (139.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

we got address from our range (192.168.122.10-192.168.122.20)

Switch to server and check log file:

Untitled

Now we can finally set Dynamic DNS Updates

DNS client computers can use dynamic update to register and dynamically update their resource records with a DNS server whenever changes occur. This reduces the need for manual administration of zone records, especially for clients that frequently move or change locations and use Dynamic Host Configuration Protocol (DHCP) to obtain an IP address,to do it securely, wee need to first create a secret key. This secret key will be used to authenticate our dns update clients with the dns server.

First,generate the key:

[root@server1 dhcpd]#dnssec-keygen -a hmac-md5 -b 128 -n USER dhcpupdate

Kdhcpupdate.+157+06009

The output is the file prefix. If you do ls Kdhcpupdate.+157+06009*   will see two files. The .key file is most useful,open the .key file:

The selected part will be used for authentication:

Untitled8

Let’s configure our dhcp server for Secure DNS updates:

make changes to dhcpd.conf file (I bold updates)

# dhcpd.conf
#
# Sample configuration file for ISC dhcpd
#

# option definitions common to all supported networks…
option domain-name “example.com”;
option domain-name-servers 192.168.122.200;

default-lease-time 600;
max-lease-time 7200;

# Use this to enble / disable dynamic dns updates globally.
ddns-update-style interim; //interim: allows your DHCP server to update a DNS server whenever it hands //out a lease. Allows your DNS server to know which IP addresses are associated with which computers in //your network. Requires that your DNS server support DDNS (Dynamic DNS)

//none: to disable dynamic DNS updates or DNS is not supporting DDNS.
update-static-leases-on;          
key dhcp_updater {       //we here defined key called dhcp_updater and configured it’s
algorithm hmac-md5;      //properties (algorithm and secret key (created with dnssec-keygen
secret kfc1r6C2VwHGnKMi/NHt6w==;    

}
zone 122.168.192.in-addr.arpa {
primary 192.168.122.200;
key dhcp_updater;  //use this key to update zone
}
zone example.com {
primary 192.168.122.200;
key dhcp_updater;      //use this key to update zone
}
# 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;

# No service will be given on this subnet, but declaring it helps the
# DHCP server to understand the network topology.

#subnet 10.152.187.0 netmask 255.255.255.0 {
#}

# This is a very basic subnet declaration.

#subnet 10.254.239.0 netmask 255.255.255.224 {
# range 10.254.239.10 10.254.239.20;
# option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
#}

# This declaration allows BOOTP clients to get dynamic addresses,
# which we don’t really recommend.

#subnet 10.254.239.32 netmask 255.255.255.224 {
# range dynamic-bootp 10.254.239.40 10.254.239.60;
# option broadcast-address 10.254.239.31;
# option routers rtr-239-32-1.example.org;
#}

# A slightly different configuration for an internal subnet.
subnet 192.168.122.0 netmask 255.255.255.0 {
range 192.168.122.10 192.168.122.20;
option domain-name-servers 192.168.122.200;
option domain-name “example.com”;
option routers 192.168.122.1;
option broadcast-address 192.168.122.255;
default-lease-time 600;
max-lease-time 7200;

}

# Hosts which require special configuration options can be listed in
# host statements. If no address is specified, the address will be
# allocated dynamically (if possible), but the host-specific information
# will still come from the host declaration.

host passacaglia {
hardware ethernet 0:0:c0:5d:bd:95;
filename “vmunix.passacaglia”;
server-name “toccata.fugue.com”;
}

# Fixed IP addresses can also be specified for hosts. These addresses
# should not also be listed as being available for dynamic assignment.
# Hosts for which fixed IP addresses have been specified can boot using
# BOOTP or DHCP. Hosts for which no fixed address is specified can only
# be booted with DHCP, unless there is an address range on the subnet
# to which a BOOTP client is connected which has the dynamic-bootp flag
# set.

host fantasia {
hardware ethernet 08:00:07:26:c0:a5;
fixed-address fantasia.fugue.com;
}

# You can declare a class of clients and then do address allocation
# based on that. The example below shows a case where all clients
# in a certain class get addresses on the 10.17.224/24 subnet, and all
# other clients get addresses on the 10.0.29/24 subnet.

class “foo” {
match if substring (option vendor-class-identifier, 0, 4) = “SUNW”;
}

shared-network 224-29 {
subnet 10.17.224.0 netmask 255.255.255.0 {
option routers rtr-224.example.org;
}
subnet 10.0.29.0 netmask 255.255.255.0 {

option routers rtr-29.example.org;
}
pool {
allow members of “foo”;
range 10.17.224.10 10.17.224.250;
}
pool {
deny members of “foo”;
range 10.0.29.10 10.0.29.230;
}
}

Lease info is written in leases files in /var/lib/dhcpd folder:

[root@server1 dhcpd]# ls
dhcpd6.leases dhcpd.leases dhcpd.leases~

Now edit named.conf:

(Changes bolded)

acl “allowed” {
192.168.122.0/24;
localhost;};

options {
listen-on port 53 { 192.168.122.200;127.0.0.1; };
listen-on-v6 port 53 { ::1; };
directory “/var/named”;
dump-file “/var/named/data/cache_dump.db”;
statistics-file “/var/named/data/named_stats.txt”;
memstatistics-file “/var/named/data/named_mem_stats.txt”;
allow-query { allowed; };
forwarders {8.8.8.8;};

recursion yes;
allow-recursion {allowed;};

dnssec-enable yes;
dnssec-validation yes;
dnssec-lookaside auto;

/* Path to ISC DLV key */
bindkeys-file “/etc/named.iscdlv.key”;

managed-keys-directory “/var/named/dynamic”;

pid-file “/run/named/named.pid”;
session-keyfile “/run/named/session.key”;
};

logging {
channel default_debug {
file “data/named.run”;
severity dynamic;

};

};
key dhcp_updater {
algorithm hmac-md5;
secret “kfc1r6C2VwHGnKMi/NHt6w==”;
};

zone “.” IN {
type hint;
file “named.ca”;

};
include “/etc/named.rfc1912.zones”;
include “/etc/named.root.key”;
zone “122.168.192.in-addr.arpa” IN {
type master;
file “/var/named/chroot/etc/named/reverse.example.com.db”;

allow-update {key “dhcp_updater”;};
};

zone “example.com” IN {
type master;

file “/var/named/chroot/etc/named/example.com.db”;
allow-update {key “dhcp_updater“;};
};

But,we are not done yet,

We now must configure SELinux policy to allow user named to create journal files

chcon -R -t dnssec_trigger_var_run_t ‘/var/named/chroot/etc/named/’

othervise,we’ll receive this error:

Untitled2

Check system time on the server (if it’s not synchronized with time server you won’t be able to access

the internet

Now restart named and dhcpd service on server,and network service on client and

check log file on server,client should be updated in example.com.db file:

Untitled3

$ORIGIN .
$TTL 10800 ; 3 hours
example.com IN SOA server1.example.com. root.example.com. (
2015052607 ; serial
86400 ; refresh (1 day)
3600 ; retry (1 hour)
604800 ; expire (1 week)
10800 ; minimum (3 hours)
)
NS server1.example.com.
$ORIGIN example.com.
$TTL 300 ; 5 minutes
localhost A 192.168.122.11   //this is our client
TXT “3145910aacd6ffbcd99fae801b8ffe89d5”
$TTL 10800 ; 3 hours
server1 A 192.168.122.200

Comments
  1. Chan says:

    Hi,

    Can i user this config with mikrotik as dhcp server? if yes, can you tell me how to configure dhcp server on mikrotik so it can communicate with dynamic dns in centos?

    Like

  2. Abby says:

    Hi,

    Thanks for the useful guide. However there is a slight issue, when testing the zone files you are using named-checkconf. It should be named-checkzone .

    Like

  3. These directions worked great but one little thing plagued me for ours. CentOS doesn’t appear to send the hostname along with the dhcp request. To get around this, if you add the following:

    DHCP_HOSTNAME=hostname

    to your /etc/sysconfig/network on all of your clients and reboot (or restart network services), it will all work. I ended up just adding this line to my bootup scripts so it populates both HOSTNAME and DHCP_HOSTNAME, and everything works seamlessly now. Thanks!

    Like

  4. […] Here i described how to install DNS and allow dynamic updates,i bold changes in /etc/named.conf file: […]

    Like

  5. HamidReza says:

    Thanks Mr.

    Like

Leave a comment