Unbound cache-only DNS server setup on RHEL 7 Linux

Introduction

Unbound is a validating, recursive, and caching DNS server. Having said that, Unbound DNS server cannot be used as an authoritative DNS server, which means it cannot be used to host custom domain name records. As a result, if your goal is to build a cache-only or forwarding DNS server, Unbound may be your preferred choice, as it does just that and it does it well.

Objective

The objective is to provide quick and easy to follow installation and configuration guide for the Unbound cache-only DNS server on Redhat 7 Linux. At the end of this guide you will be able to use Unbound DNS server from all clients on your local area network.

Requirements

Privileged access to your Redhat 7 Linux server with configured standard RedHat repositories.

Difficulty

MEDIUM

Conventions

  • # – requires given linux commands to be executed with root privileges either directly as a root user or by use of sudo command
  • $ – requires given linux commands to be executed as a regular non-privileged user

Instructions

Unbound and DNS tools installation

In the first step we are going to install the actual Unbound DNS server as well as DNS tools which will be eventually used to test your DNS cache-only server configuration. Given that you have your Redhat repository configured correctly you can install both by executing the following linux command:

# yum install unbound bind-utils



Basic Unbound Configuration

Now, we are going to perform a basic configuration of the Unbound DNS caching-only server. This will be done by editing Unbound’s configuration file /etc/unbound/unbound.conf either by using text editor or using a below sed commands. First, use your preferred text editor to locate the line # interface: 0.0.0.0 and uncomment it by removing the leading # sign. Alternatively use the below sed command:

# sed -i '/interface: 0.0.0.0$/s/#//' /etc/unbound/unbound.conf

The above configuration will instruct Unbound DNS server to listen on all local network interfaces. Next, allow your LAN clients to query Unbound’s cache. Locate the relevant line change the default loopback IP address 127.0.0.0/8 to netowork address of your LAN eg. 10.0.0.0/24:

FROM:
access-control: 127.0.0.0/8 allow
TO
access-control: 10.0.0.0/24 allow

The above can also be done by sed command:

# sed -i 's/127.0.0.0\/8 allow/10.0.0.0\/24 allow/' /etc/unbound/unbound.conf

Setup DNSSEC support

Next, we instruct Unbound DNS server to generate RSA keys in order to provide DNSSEC support:

# unbound-control-setup 
setup in directory /etc/unbound
generating unbound_server.key
Generating RSA private key, 1536 bit long modulus
.................++++
.........++++
e is 65537 (0x10001)
generating unbound_control.key
Generating RSA private key, 1536 bit long modulus
.........++++
..................................++++
e is 65537 (0x10001)
create unbound_server.pem (self signed certificate)
create unbound_control.pem (signed client certificate)
Signature ok
subject=/CN=unbound-control
Getting CA Private Key
Setup success. Certificates created. Enable in unbound.conf file to use

All what remains is to check Unbound’s configuration:

# unbound-checkconf
unbound-checkconf: no errors in /etc/unbound/unbound.conf


Enable and start Unbound server

At this stage we will enable Unbound DNS server to start at the boot time:

# systemctl enable unbound
Created symlink from /etc/systemd/system/multi-user.target.wants/unbound.service to /usr/lib/systemd/system/unbound.service.

and start the actual service:

# service unbound start
Redirecting to /bin/systemctl start  unbound.service

Make sure that Unbound DNS server is running by checking its status:

[root@localhost unbound]# service unbound status
Redirecting to /bin/systemctl status  unbound.service
● unbound.service - Unbound recursive Domain Name Server
   Loaded: loaded (/usr/lib/systemd/system/unbound.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2016-12-07 10:32:58 AEDT; 6s ago
  Process: 2355 ExecStartPre=/usr/sbin/unbound-anchor -a /var/lib/unbound/root.key -c /etc/unbound/icannbundle.pem (code=exited, status=0/SUCCESS)
  Process: 2353 ExecStartPre=/usr/sbin/unbound-checkconf (code=exited, status=0/SUCCESS)
 Main PID: 2357 (unbound)
   CGroup: /system.slice/unbound.service
           └─2357 /usr/sbin/unbound -d

Dec 07 10:32:57 localhost.localdomain systemd[1]: Starting Unbound recursive Domain Name Server...
Dec 07 10:32:57 localhost.localdomain unbound-checkconf[2353]: unbound-checkconf: no errors in /etc/unbound/unbound.conf
Dec 07 10:32:58 localhost.localdomain systemd[1]: Started Unbound recursive Domain Name Server.
Dec 07 10:32:58 localhost.localdomain unbound[2357]: Dec 07 10:32:58 unbound[2357:0] warning: increased limit(open files) from 1024 to 8266
Dec 07 10:32:58 localhost.localdomain unbound[2357]: [2357:0] notice: init module 0: validator
Dec 07 10:32:58 localhost.localdomain unbound[2357]: [2357:0] notice: init module 1: iterator
Dec 07 10:32:58 localhost.localdomain unbound[2357]: [2357:0] info: start of service (unbound 1.4.20).

Open DNS firewall port

To allow your local LAN clients to connect to your new Unbound cache-only DNS server you’ll need to open a DNS port:

# firewall-cmd --permanent --add-service dns
success
# firewall-cmd --reload
success

All done, we are now ready for testing.



Testing

Finally, we have come to a point where we can perform some basic testing of our new Unbound DNS cache-only server. For this we use dig command which a a part of previously installed bind-utils package to perform some DNS queries. First, execute DNS query on the actual DNS server:

# dig @localhost example.com

; <<>> DiG 9.9.4-RedHat-9.9.4-37.el7 <<>> @localhost example.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53485
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
example.com.            86400   IN      A       93.184.216.34

;; Query time: 817 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Dec 07 10:40:46 AEDT 2016
;; MSG SIZE  rcvd: 56

Note, that the query time is more that 817 msec. Since we have configured DNS cache-only server this query is now cached so any subsequent DNS query resolution of that same domain name we be rather instant:

# dig @localhost example.com

; <<>> DiG 9.9.4-RedHat-9.9.4-37.el7 <<>> @localhost example.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34443
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
example.com.            86272   IN      A       93.184.216.34

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Dec 07 10:42:54 AEDT 2016
;; MSG SIZE  rcvd: 56

Lastly, you may now test Ubound DNS server's configuration from your local LAN clients by pointing them to Unbound's IP address eg. 10.1.1.45:

$ dig @10.1.1.45 example.com

; <<>> DiG 9.9.5-9+deb8u6-Debian <<>> @10.1.1.45 example.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 50494
;; flags: qr rd ad; QUERY: 0, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; Query time: 0 msec
;; SERVER: 10.1.1.45#53(10.1.1.45)
;; WHEN: Wed Dec 07 10:45:43 AEDT 2016
;; MSG SIZE  rcvd: 12