DNS resolution is used to lookup a domain name and resolve it to an IP address. Instead of having various systems in our network querying directly out to the Internet, we can configure a DNS caching server within our network and have other systems point to this for DNS resolution which will improve efficiency. The more systems sending queries through the caching server, the larger the cache will grow, further improving the hit rate.
The local cache of DNS records is stored closer to the systems initiating the requests, resulting in faster resolution time. These records will be cached until their TTL expires, or the cache is flushed. If any other system performs a DNS lookup for a query that resides in the cache it can be returned much faster as the caching server will not have to forward the query to some other DNS server out on the Internet.
There are many packages capable of acting as a DNS cache such as Bind, Dnsmasq and Unbound. In our example we will be working with Unbound.
The Unbound package can be installed via yum as shown below.
yum install unbound -y
Once installation has completed, enable the service so that it starts on boot, and start the service up now as shown.
[[email protected] ~]# systemctl enable unbound ln -s '/usr/lib/systemd/system/unbound.service' '/etc/systemd/system/multi-user.target.wants/unbound.service' [[email protected] ~]# systemctl start unbound
By default Unbound will only be listening for requests on localhost, that is itself. This is demonstrated below with help of the netstat command. As you can see unbound is listening on localhost for IPv4 and IPv6 on TCP and UDP port 53.
[[email protected] ~]# netstat -antpu | grep unbound tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 21026/unbound tcp6 0 0 ::1:53 :::* LISTEN 21026/unbound udp 0 0 127.0.0.1:53 0.0.0.0:* 21026/unbound udp6 0 0 ::1:53 :::* 21026/unbound
This is not very useful for us, as remote hosts will not be able to query the caching server for DNS records. To change this behavior edit the /etc/unbound/unbound.conf file with your favorite text editor and add the below entry which will configure Unbound to listen on all available network interfaces. This file is documented quite well and will be able to provide further information.
By default Unbound will also deny all recursive queries from any client unless we specifically allow an IP address or range of IP addresses, to do this add an ACL entry within the /etc/unbound/unbound.conf file as shown.
access-control: 192.168.0.0/24 allow
This will allow remote hosts in the 192.168.0.0/24 network to make recursive queries to this server, specify your IP address range here.
Next we need to create a forward zone which will specify the external DNS server to send the queries to, in this case we are going to send queries to the Google public DNS resolver 18.104.22.168. Forward zones are again created in the /etc/unbound/unbound.conf file as shown.
forward-zone: name: "." forward-addr: 22.214.171.124
By specifying “.” for the name we are saying to forward all queries, this can be changed to a specific domain name to only forward queries for that specific domain to the address set.
Save all of these changes that have been made and then restart the unbound service to apply them.
systemctl restart unbound
At this point you can optionally run netstat again to confirm that Unbound is correctly listening on 0.0.0.0:53 rather than localhost.
Finally to allow DNS queries to come in from remote hosts the firewall must be modified to allow DNS queries through, this can be set in firewalld with the below commands.
[[email protected] ~]# firewall-cmd --permanent --add-service=dns success [[email protected] ~]# firewall-cmd --reload success
Unbound is now configured to accept recursive queries from hosts in the 192.168.0.0/24 range, it will send recursive queries out to 126.96.36.199 and keep a local cache of the results. By default these cached records will be removed when the TTL expires, however we can manually clear the cache by simply reloading or restarting the service. You can alternatively remove specific names or zone types using the unbound-control command.
For example to view all contents of the cache you can use ‘unbound-control dump_cache’ which will print all cached record queries to stdout. These results can be exported to a file, this way should the cache be flushed the file can be imported and the cache will continue to exist, this is demonstrated below.
[[email protected] ~]# unbound-control dump_cache > backup [[email protected] ~]# wc -l backup 48 backup [[email protected] ~]# systemctl restart unbound [[email protected] ~]# unbound-control dump_cache START_RRSET_CACHE END_RRSET_CACHE START_MSG_CACHE END_MSG_CACHE EOF [[email protected] ~]# unbound-control load_cache < backup ok
In the above example we are dumping the contents of the cache to a file called ‘backup’, this file is shown to contain 48 lines of content just from looking up ‘google.com’ so I have not included the full 48 lines for brevity. The Unbound service is then restarted and the cache is confirmed as being empty, afterwards the cache is loaded back in from the backup file which is successful. After running ‘unbound-control dump_cache’ again it output the 48 line result again.
After installing Unbound and performing some basic configuration it is capable of caching DNS records locally, speeding up DNS resolution time for client systems that are querying it for DNS.
This post is part of our Red Hat Certified Engineer (RHCE) exam study guide series. For more RHCE related posts and information check out our full RHCE study guide.