Back to basics – Setting up a local (internal) DNS server

Today’s “back to basics” post is all about setting up a local internal DNS server. Though there are a number of applications out there which will ease the process of setting up DNS and/or DHCP services, I am sticking with what would be used in the enterprise environment and also focusing on doing things manually.

Why manually?? Well, it has been a while since I’ve had to configure named from scratch and so it’s good to remind me how it all fits together. Plus, by knowing how the internals are working (as far as the configuration is concerned) it means if I run into problems, then I’m better placed to fix the issue sooner and with less searching.

So for DNS that would be (IMHO) BIND.  BIND has been around for a very long time and for those of you with an interest in it’s history, take a look at; BIND – Wikipedia.  In CentOS and RHEL you have two options the base BIND packages or an additional package which configures BIND to run in a chroot jail.

Because I am only setting this up for the purpose of a lab, I will not be making use of the chroot version (though in all honesty it doesn’t require much additional effort) and will stick
instead with the base package.  HOWEVER, IF you are going to use BIND on a server which has a public facing interface onto the big
, bad Internet, then without doubt, MAKE SURE YOU USE THE CHROOT package too.  There is no reason not to in my opinion!

Back to the lab installation

[root@rhc-server ~]# yum install bind -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Resolving Dependencies
--> Running transaction check
---> Package bind.x86_64 32:9.9.4-14.el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

Package                     Arch                          Version                                   Repository                        Size
bind                        x86_64                        32:9.9.4-14.el7                           baselocal                        1.8 M

Transaction Summary
Install  1 Package

Total download size: 1.8 M
Installed size: 4.3 M
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : 32:bind-9.9.4-14.el7.x86_64                                                                                              1/1
Verifying  : 32:bind-9.9.4-14.el7.x86_64                                                                                              1/1

bind.x86_64 32:9.9.4-14.el7


OK, so now we have it installed we need to create a zone file which will contain all of our required internal DNS zone information.  Zone files are stored in the /var/named/data directory (or if using chroot version of bind /var/named/chroot/var/named/data).  As you can see currently there are no zone files in this location;

[root@rhc-server data]# pwd
[root@rhc-server data]# ls
[root@rhc-server data]#

For my internal DNS I’m going setting up a zone called “” and the zone file looks more or less as follows;

[root@rhc-server data]# cat
$TTL 1d
@        IN    SOA (
2016022100    ; Serial
1h        ; Refresh
15m        ; Retry
10d        ; Expire (10 days should be enough in the lab)
1h )        ; Negative Cache
; Name Servers
IN    NS
; MX Records (Mail eXchange)
; CNAME (Canonical Name a.k.a. Aliases)
provision    IN    CNAME
; A Records (IPv4 addresses)
ns        IN    A
rhc-server    IN    A

; AAAA Records (IPv6 Records)
; - Not used yet but at a later stage in the lab

As you can probably spot, I am using the IPv4 address as the primary IP address for my server.

The next step is to updated the /etc/named.conf file so that it is listening on the right ip address and also to define the zone I have just created.

// named.conf
// Provided by Red Hat bind package to configure the ISC BIND named(8) DNS
// server as a caching only nameserver (as a localhost DNS resolver only).
// See /usr/share/doc/bind*/sample/ for example named configuration files.

options {
listen-on port 53 {; };
//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     { any; };

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/";
session-keyfile "/run/named/session.key";

logging {
channel default_debug {
file "data/";
severity dynamic;

zone "." IN {
type hint;
file "";

zone "" IN {
type master;
file "data/";

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";

To maintain a level of sanity, lets just do a couple of checks to make sure everything is, as it should be.

[root@rhc-server etc]# named-checkzone /var/named/data/
zone loaded serial 2016022100
[root@rhc-server etc]# named-checkconf
[root@rhc-server etc]# echo $?
[root@rhc-server etc]#

And now time to enable the service, start it and then test that I have got everything right.  Also as part of this step I have installed bind-utils so that I can confirm the zone is active by way of querying the name server.;

[root@rhc-server etc]# systemctl enable named
ln -s '/usr/lib/systemd/system/named.service' '/etc/systemd/system/'
[root@rhc-server etc]# systemctl start named.service
[root@rhc-server etc]# yum install bind-utils -y
[root@rhc-server etc]# ping -c 5
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=64 time=0.021 ms
64 bytes from icmp_seq=2 ttl=64 time=0.093 ms
64 bytes from icmp_seq=3 ttl=64 time=0.091 ms
64 bytes from icmp_seq=4 ttl=64 time=0.053 ms
64 bytes from icmp_seq=5 ttl=64 time=0.093 ms

--- ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4002ms
rtt min/avg/max/mdev = 0.021/0.070/0.093/0.029 ms
[root@rhc-server etc]# dig

; <<>> DiG 9.9.4-RedHat-9.9.4-14.el7 <<>>
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56872
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

; EDNS: version: 0, flags:; udp: 4096
;        IN    A

;; ANSWER SECTION:    86400    IN    A

;; AUTHORITY SECTION:    86400    IN    NS

;; Query time: 0 msec
;; WHEN: Sun Feb 21 18:50:48 GMT 2016
;; MSG SIZE  rcvd: 81

The only thing that I had done ahead of time was to make sure that my /etc/resolv.conf file was updated to reflect the correct search and nameserver parameters.  So all in all looking good.

Till next time.


Err, well.  That’s embarrassing!  So as part of the above post though it work, somethings will not.  More specifically, if you try to perform a reverse look up it will fail miserably.  So to complete the picture, you can see what I did with regards the reverse zone here.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.