How to install and configure DNS (bind) server in RHEL7

Let’s create the VM first:

[root@rhel7 ~]# virt-install \
> --hvm \
> --name ns1 \
> --ram 1024 \
> --disk path=/kvm/ns1.img,size=50 \
> --vcpus 1 \
> --os-type linux \
> --os-variant rhel7 \
> --network bridge=virbr0 \
> --graphics none \
> --location 'http://192.168.122.3/rhel7' \
> --extra-args "ks=http://192.168.122.3/ksfiles/rhel7-minimal-ks.cfg \
> console=tty0 console=ttyS0,115200 SERVERNAME=ns1.jefrey.io IPADDR=192.168.122.5"

Starting install...
...
...
[root@ns1 ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.122.5  netmask 255.255.255.0  broadcast 192.168.122.255
        inet6 fe80::5054:ff:fe99:e7b8  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:99:e7:b8  txqueuelen 1000  (Ethernet)
        RX packets 15194  bytes 3061536 (2.9 MiB)
        RX errors 0  dropped 8  overruns 0  frame 0
        TX packets 4869  bytes 719542 (702.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@ns1 ~]#
[root@ns1 ~]# vi /etc/sysconfig/network
[root@ns1 ~]# cat !$
cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=ns1.jefrey.io
GATEWAY=192.168.122.1
GATEWAYDEV=eth0
[root@ns1 ~]#

Now, let’s install the bind and bind-utils then add DNS to firewall:

[root@ns1 ~]# yum -y install bind bind-utils
[root@ns1 ~]# 
[root@ns1 ~]# firewall-cmd --add-service=dns --permanent
[root@ns1 ~]# firewall-cmd --reload

Next is to set the DNS server configurations:

[root@ns1 ~]# vi /etc/named.conf
[root@ns1 ~]# cat /etc/named.conf
//
// 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 { 127.0.0.1; 192.168.122.5; };
    listen-on-v6 port 53 { none; };
    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     { localhost; 192.168.122.0/24; };
    allow-transfer    { localhost; 192.168.122.6/24; };

    /* 
     - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
     - If you are building a RECURSIVE (caching) DNS server, you need to enable 
       recursion. 
     - If your recursive DNS server has a public IP address, you MUST enable access 
       control to limit queries to your legitimate users. Failing to do so will
       cause your server to become part of large scale DNS amplification 
       attacks. Implementing BCP38 within your network would greatly
       reduce such attack surface 
    */
    recursion yes;

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

zone "." IN {
    type hint;
    file "named.ca";
};

zone "jefrey.io" IN {
    type master;
    file "jefrey.io.forward";
    allow-update { none; };
};

zone "122.168.192.in-addr.arpa" IN {
    type master;
    file "jefrey.io.reverse";
    allow-update { none; };
};

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

[root@ns1 ~]#

Next is to create my forward and reverse zones:

[root@ns1 ~]# vi /var/named/jefrey.io.forward 
[root@ns1 ~]# cat /var/named/jefrey.io.forward 
$TTL 86400
@       IN SOA  ns1.jefrey.io. root.jefrey.io. (
            2015062101      ; serial
            3600    ; refresh
            1800    ; retry
            604800  ; expire
            86400   ; minimum
)
@                IN      NS      ns1.jefrey.io.
@                IN      NS      ns2.jefrey.io.
@                IN      A       192.168.122.5
@                IN      A       192.168.122.6
@                IN      A       192.168.122.3
@                IN      A       192.168.122.4
@                IN      A       192.168.122.7
@                IN      A       192.168.122.8
@                IN      A       192.168.122.70
@                IN      A       192.168.122.71
@                IN      A       192.168.122.72
ns1                IN      A       192.168.122.5
ns2                IN      A       192.168.122.6
www                IN      A       192.168.122.3
ntp                IN      A       192.168.122.4
mx1                IN      A       192.168.122.7
nfs                IN      A       192.168.122.8
wiki            IN      A       192.168.122.9
nagios            IN      A       192.168.122.10
rhev-m1            IN      A       192.168.122.70
rhev-h1            IN      A       192.168.122.71
rhev-h2            IN      A       192.168.122.72
[root@ns1 ~]# 
[root@ns1 ~]# vi /var/named/jefrey.io.reverse 
[root@ns1 ~]# cat /var/named/jefrey.io.reverse 
$TTL 86400
@       IN SOA  ns1.jefrey.io. root.jefrey.io. (
            2015062101      ; serial
            3600    ; refresh
            1800    ; retry
            604800  ; expire
            86400   ; minimum
)
@                IN      NS      ns1.jefrey.io.
@                IN      NS      ns2.jefrey.io.
@                IN      PTR     jefrey.io.
ns1                IN      A       192.168.122.5
ns2                IN      A       192.168.122.6
www                IN      A       192.168.122.3
ntp                IN      A       192.168.122.4
mx1                IN      A       192.168.122.7
nfs                IN      A       192.168.122.8
wiki            IN      A       192.168.122.9
nagios            IN      A       192.168.122.10
rhev-m1         IN      A       192.168.122.70
rhev-h1         IN      A       192.168.122.71
rhev-h2         IN      A       192.168.122.72
5                 IN      PTR     ns1.jefrey.io.
6                 IN      PTR     ns2.jefrey.io.
3                 IN      PTR     www.jefrey.io.
4                 IN      PTR     ntp.jefrey.io.
7                 IN      PTR     mx1.jefrey.io.
8                 IN      PTR     nfs.jefrey.io.
9                 IN      PTR     wiki.jefrey.io.
10                 IN      PTR     nagios.jefrey.io.
70                 IN      PTR     rhev-m1.jefrey.io.
71                 IN      PTR     rhev-h1.jefrey.io.
72                 IN      PTR     rhev-h2.jefrey.io.
[root@ns1 ~]#

Use this server and the upcoming slave as the new DNS server:

[root@ns1 ~]# vi /etc/resolv.conf
[root@ns1 ~]# cat /etc/resolv.conf 
search jefrey.io
nameserver 192.168.122.5
nameserver 192.168.122.6
[root@ns1 ~]#

Enable and start the service then try ping www.google.com:

[root@ns1 ~]# systemctl enabled named.service
[root@ns1 ~]# systemctl start named.service
[root@ns1 ~]# 
[root@ns1 ~]# ping -c3 www.google.com
PING www.google.com (74.125.68.106) 56(84) bytes of data.
64 bytes from 74.125.68.106: icmp_seq=1 ttl=41 time=15.7 ms
64 bytes from 74.125.68.106: icmp_seq=2 ttl=41 time=18.5 ms
64 bytes from 74.125.68.106: icmp_seq=3 ttl=41 time=27.8 ms

--- www.google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 15.727/20.704/27.818/5.162 ms
[root@ns1 ~]#

Let’s test the resolution:

[root@ns1 ~]# dig www.jefrey.io

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

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.jefrey.io.            IN    A

;; ANSWER SECTION:
www.jefrey.io.        86400    IN    A    192.168.122.3

;; AUTHORITY SECTION:
jefrey.io.        86400    IN    NS    ns2.jefrey.io.
jefrey.io.        86400    IN    NS    ns1.jefrey.io.

;; ADDITIONAL SECTION:
ns1.jefrey.io.        86400    IN    A    192.168.122.5
ns2.jefrey.io.        86400    IN    A    192.168.122.6

;; Query time: 0 msec
;; SERVER: 192.168.122.5#53(192.168.122.5)
;; WHEN: Sat Apr 25 01:55:31 SGT 2015
;; MSG SIZE  rcvd: 126

[root@ns1 ~]#

It’s working! Time to create the slave.

[root@rhel7 ~]# virt-install \
> --hvm \
> --name ns2 \
> --ram 1024 \
> --disk path=/kvm/ns2.img,size=50 \
> --vcpus 1 \
> --os-type linux \
> --os-variant rhel7 \
> --network bridge=virbr0 \
> --graphics none \
> --location 'http://192.168.122.3/rhel7' \
> --extra-args "ks=http://192.168.122.3/ksfiles/rhel7-minimal-ks.cfg \
> console=tty0 console=ttyS0,115200 SERVERNAME=ns2.jefrey.io IPADDR=192.168.122.6"

Starting install...
...
...
[root@ns2 ~]# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.122.6  netmask 255.255.255.0  broadcast 192.168.122.255
        inet6 fe80::5054:ff:fe39:914b  prefixlen 64  scopeid 0x20<link>
        ether 52:54:00:39:91:4b  txqueuelen 1000  (Ethernet)
        RX packets 10016  bytes 2484328 (2.3 MiB)
        RX errors 0  dropped 9  overruns 0  frame 0
        TX packets 1273  bytes 170347 (166.3 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

[root@ns2 ~]#
[root@ns2 ~]#
[root@ns2 ~]# vi /etc/sysconfig/network
[root@ns2 ~]# cat !$
cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=ns2.jefrey.io
GATEWAY=192.168.122.1
GATEWAYDEV=eth0
[root@ns2 ~]# 
[root@ns2 ~]# yum -y install bind bind-utils
[root@ns2 ~]# 
[root@ns2 ~]# firewall-cmd --add-service=dns --permanent
[root@ns2 ~]# firewall-cmd --reload
[root@ns2 ~]# 
[root@ns2 ~]# vi /etc/named.conf
[root@ns2 ~]# cat /etc/named.conf 
//
// 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 { 127.0.0.1; 192.168.122.6; };
    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     { localhost; 192.168.122.0/24; };

    /* 
     - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion.
     - If you are building a RECURSIVE (caching) DNS server, you need to enable 
       recursion. 
     - If your recursive DNS server has a public IP address, you MUST enable access 
       control to limit queries to your legitimate users. Failing to do so will
       cause your server to become part of large scale DNS amplification 
       attacks. Implementing BCP38 within your network would greatly
       reduce such attack surface 
    */
    recursion yes;

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

zone "." IN {
    type hint;
    file "named.ca";
};

zone "jefrey.io" IN {
    type slave;
    file "slaves/jefrey.io.forward";
    masters { 192.168.122.5; };
};

zone "122.168.192.in-addr.arpa" IN {
    type slave;
    file "slaves/jefrey.io.reverse";
    masters { 192.168.122.5; };
};

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
[root@ns2 ~]#
[root@ns2 ~]# systemctl enabled named.service
[root@ns2 ~]# systemctl start named.service
[root@ns2 ~]#
[root@ns2 ~]# systemctl status named.service -l
named.service - Berkeley Internet Name Domain (DNS)
   Loaded: loaded (/usr/lib/systemd/system/named.service; disabled)
   Active: active (running) since Sat 2015-04-25 01:37:44 SGT; 21min ago
  Process: 1942 ExecStart=/usr/sbin/named -u named $OPTIONS (code=exited, status=0/SUCCESS)
  Process: 1940 ExecStartPre=/usr/sbin/named-checkconf -z /etc/named.conf (code=exited, status=0/SUCCESS)
 Main PID: 1944 (named)
   CGroup: /system.slice/named.service
           └─1944 /usr/sbin/named -u named

Apr 25 01:37:45 ns2.jefrey.io named[1944]: transfer of '122.168.192.in-addr.arpa/IN' from 192.168.122.5#53: Transfer completed: 1 messages, 15 records, 370 bytes, 0.001 secs (370000 bytes/sec)
Apr 25 01:37:45 ns2.jefrey.io named[1944]: zone 122.168.192.in-addr.arpa/IN: sending notifies (serial 2015042501)
Apr 25 01:37:45 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'pdns196.ultradns.co.uk/A/IN': 2001:7fe::53#53
Apr 25 01:37:45 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'pdns196.ultradns.co.uk/AAAA/IN': 2001:7fe::53#53
Apr 25 01:37:45 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'pdns196.ultradns.biz/A/IN': 2001:500:3682::12#53
Apr 25 01:37:45 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'pdns196.ultradns.org/A/IN': 2001:502:4612::e8#53
Apr 25 01:44:14 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'www.google.com.dlv.isc.org/DLV/IN': 2001:502:2eda::23#53
Apr 25 01:44:14 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'www.google.com.dlv.isc.org/DLV/IN': 2001:502:ad09::23#53
Apr 25 01:44:14 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'www.google.com.dlv.isc.org/DLV/IN': 2001:500:71::29#53
Apr 25 01:44:14 ns2.jefrey.io named[1944]: error (network unreachable) resolving 'www.google.com.dlv.isc.org/DLV/IN': 2001:500:60::29#53
[root@ns2 ~]#
[root@ns2 ~]# 
[root@ns2 ~]# vi /etc/resolv.conf 
[root@ns2 ~]# cat /etc/resolv.conf 
search jefrey.io
nameserver 192.168.122.5
nameserver 192.168.122.6
[root@ns2 ~]# 
[root@ns2 ~]# 
[root@ns2 ~]# ping -c3 www.google.com
PING www.google.com (74.125.68.104) 56(84) bytes of data.
64 bytes from 74.125.68.104: icmp_seq=1 ttl=42 time=14.8 ms
64 bytes from 74.125.68.104: icmp_seq=2 ttl=42 time=22.4 ms
64 bytes from 74.125.68.104: icmp_seq=3 ttl=42 time=21.0 ms

--- www.google.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 14.843/19.442/22.445/3.306 ms
[root@ns2 ~]# 
[root@ns2 ~]# dig ntp.jefrey.io

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

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ntp.jefrey.io.            IN    A

;; ANSWER SECTION:
ntp.jefrey.io.        86400    IN    A    192.168.122.4

;; AUTHORITY SECTION:
jefrey.io.        86400    IN    NS    ns1.jefrey.io.
jefrey.io.        86400    IN    NS    ns2.jefrey.io.

;; ADDITIONAL SECTION:
ns1.jefrey.io.        86400    IN    A    192.168.122.5
ns2.jefrey.io.        86400    IN    A    192.168.122.6

;; Query time: 0 msec
;; SERVER: 192.168.122.5#53(192.168.122.5)
;; WHEN: Sat Apr 25 02:00:58 SGT 2015
;; MSG SIZE  rcvd: 126

[root@ns2 ~]#

NOTE: Don’t forget to update the serial everytime you make any zone change!!!