A Slightly Longer Guide to Setting up a Caching / Forwarding Name Server

Setting up a caching server on RHEL6, by default, works out of the box for a RHEL-type distributions. From there, it is just the matter of adding additional changes to make it either a forwarding, master or slave name server.

Of course, in our case, there were glitches.

Reviewing through Michael Jang’s RHCE prep book, the instructions for setting up the caching name server goes as following:

1) Install bind-*

2) Enable named with “chkconfig named on”

3) Start up named with “service named start”

That worked.

What did not work was this:

[]{}rndc status

That returned with the following message:

[]{}[root@localhost \~]# rndc status

[]{}rndc: neither /etc/rndc.conf nor /etc/rndc.key was found


As it turns out, rndc.key was not generated when we installed bind.So let’s try to resolve this. While we are on the task, we will go and setup some ACLs and forwarding as well.

First, fixing the immediate problem involves running a command to generate a new key:

[]{}rndc-confgen -a


Which will put in a new rndc.key file by default into /etc.

However, even though it defaults to a key length of 128, a generating the key on the a virtual machine took a long while. So in the interest of time as well as looking to try something new, we bypassed it by using the OS’s random generator:

[]{}rndc-confgen -r /dev/urandom -a


(Note: you probably wouldn’t want to do this in a mission critical environment).

With the file generated:

[]{}[root@localhost etc]# cat /etc/rndc.key

[]{}key “rndc-key” {

[[ []{}]{}]{}algorithm hmac-md5;

[[]{} []{}]{}secret “WxQEDQ8KY+SII48TfeV92w==”;

[]{}};

We will next need to give it the appropriate permissions and ownership:

[]{}chown root:named rndc.key

[]{}chmod 644 rndc.key

[]{}chcon -u system_u -t etc_t rndc.key


What we have done here is put the group ownership under named group and then make it readable to the named user can read it. Then afterward, we used selinux to give it the appropriate security context for named.

With that done, we insert the following line in at the end of the named.conf file.

[]{}include “/etc/rndc.key”;

We will also need to setup the forwarders somewhere in the options { } section.

[]{}forwarders { 192.168.15.200; };


And disable the following lines as well, since we are not using dnssec in our network, otherwise, we will not get a response back for our internal domains:

[]{}#[]{}dnssec-enable yes;

[]{}#[]{}dnssec-validation yes;

[]{}#[]{}dnssec-lookaside auto;

[]{}#[]{}bindkeys-file “/etc/named.iscdlv.key”;


(In real life, dnssec is highly recommend for managing DNS in order to avoid DNS poisoning. For now, we’ll work on that another time)

While we are at it, lets add some ACLs to named.conf:

[]{}controls {

[]{}inet 127.0.0.1 allow {localhost;};

[]{}};

Now we restart named and run the original rndc status command:

[]{}[root@localhost etc]# rndc status

[]{}version: 9.7.3-P3-RedHat-9.7.3-2.el6_1.P3.2

[]{}CPUs found: 1

[]{}worker threads: 1

[]{}number of zones: 19

[]{}debug level: 0

[]{}xfers running: 0

[]{}xfers deferred: 0

[]{}soa queries in progress: 0

[]{}query logging is OFF

[]{}recursive clients: 0/0/1000

[]{}tcp clients: 0/100

[]{}server is up and running

To ensure that our caching server works, we added the following as the first line in /etc/resolv.conf

[]{}nameserver 127.0.0.1

If your server is on a DHCP network and you are using dhclient (like mine), you can have added to the resolver file by adding following line in the file dhclient.conf (in my case,/etc/dhcp/dhclient-eth0.conf):

[]{}prepend domain-name-servers 127.0.0.1;

With that done, let’s do a test. We will run the following command to query for an internal domain:

[]{}dig @127.0.0.1 kvm0001.monzell.com


While on the DNS server, we will monitor DNS traffic from the client (which in this case, 192.168.15.33).

The result? On the client:

[]{}[root@localhost data]# dig @127.0.0.1 kvm0001.monzell.com

[]{}; <<>> DiG 9.7.3-P3-RedHat-9.7.3-2.el6_1.P3.2 <<>> @127.0.0.1 []{}kvm0001.monzell.com

[]{};(1 server found)

[]{};; global options: +cmd

[]{};; Got answer:

[]{};; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45507

[]{};; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

[]{};; QUESTION SECTION:

[]{};kvm0001.monzell.com.[]{}IN[]{}A

[]{};; ANSWER SECTION:

[]{}kvm0001.monzell.com.[]{}56[]{}IN[]{}A[]{}192.168.15.31

[]{};; AUTHORITY SECTION:

[]{}monzell.com.[]{}41[]{}IN[]{}NS[]{}ns.monzell.com.

[]{};; ADDITIONAL SECTION:

[]{}ns.monzell.com.[]{}56[]{}IN[]{}A[]{}192.168.15.200

[]{};; Query time: 0 msec

[]{};; SERVER: 127.0.0.1#53(127.0.0.1)

[]{};; WHEN: Sun Sep 11 14:11:56 2011

[]{};; MSG SIZE rcvd: 86


On the DNS server:

[]{}[root@centos log]# tcpdump -i eth0 port 53 and src host 192.168.15.33

[]{}tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

[]{}listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

[]{}14:19:31.219035 IP 192.168.15.33.27877 > centos.monzell.com.domain: 10966+ [1au] A? kvm0001.monzell.com. (48)


So we know that the client has queried the DNS and retrieved the correct IP. Now lets see if the client had it cached now. We run the command the again:

[]{}[root@localhost data]# dig @127.0.0.1 kvm0001.monzell.com

[]{}; <<>> DiG 9.7.3-P3-RedHat-9.7.3-2.el6_1.P3.2 <<>> @127.0.0.1 []{}kvm0001.monzell.com

[]{}; (1 server found)

[]{};; global options: +cmd

[]{};; Got answer:

[]{};; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5672

[]{};; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1

[]{};; QUESTION SECTION:

[]{};kvm0001.monzell.com.[]{}IN[]{}A

[]{};; ANSWER SECTION:

[]{}kvm0001.monzell.com.[]{}5[]{}IN[]{}A[]{}192.168.15.31

[]{};; AUTHORITY SECTION:[]{}

[]{}monzell.com.[]{}5[]{}IN[]{}NS[]{}ns.monzell.com.

[]{};; ADDITIONAL SECTION:

[]{}ns.monzell.com.[]{}5[]{}IN[]{}A[]{}192.168.15.200

[]{};; Query time: 0 msec

[]{};; SERVER: 127.0.0.1#53(127.0.0.1)

[]{};; WHEN: Sun Sep 11 14:15:56 2011

[]{};; MSG SIZE rcvd: 86


Again, we got the correct IP returned. Did it work?

Yes, because on the DNS server, we did not receive query from the client:

[]{}[root@centos log]# tcpdump -i eth0 port 53 and src host 192.168.15.33

[]{}tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

[]{}listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

[]{}14:19:31.219035 IP 192.168.15.33.27877 > centos.monzell.com.domain: 10966+ [1au] A? kvm0001.monzell.com. (48)

[]{}14:21:07.437358 IP 192.16


In fact, we did not see any output until we retried the same dig command a few minutes later:

[]{}[root@centos log]# tcpdump -i eth0 port 53 and src host 192.168.15.33

[]{}tcpdump: verbose output suppressed, use -v or -vv for full protocol decode

[]{}listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

[]{}14:19:31.219035 IP 192.168.15.33.27877 > centos.monzell.com.domain: 10966+ [1au] A? kvm0001.monzell.com. (48)

[]{}14:21:07.437358 IP 192.168.15.33.55693 > centos.monzell.com.domain: 22604+ [1au] A? kvm0001.monzell.com. (48)



At this point, we have verified that caching server works. We are done here.