In this post we will explain how to conﬁgure a secure, caching nameserver using the unbound DNS server.
Caching Name Servers And DNSSEC
Caching nameservers store DNS query results in a local cache and remove resource records from the cache when their TTLs expire. It is common to set up caching nameservers to perform queries on behalf of clients on the local network. This greatly improves the efﬁciency of DNS name resolutions by reducing DNS trafﬁc across the Internet. As the cache grows, DNS performance improves as the caching nameserver answers more and more client queries from its local cache.
Given the stateless nature of UDP, DNS transactions are prone to spooﬁng and tampering. Caching nameservers have historically been favored targets of attackers looking to redirect or hijack network trafﬁc. This is often achieved by exploiting vulnerabilities in DNS server software to fool a DNS server into accepting and populating malicious data into its cache, a technique commonly referred to as cache poisoning. Once the attacker succeeds in poisoning a DNS server’s cache, they effectively compromise the DNS data received by the numerous clients utilizing the caching name service on the DNS server and can consequently redirect or hijack the clients’ network trafﬁc.
While a caching nameserver can greatly improve DNS performance on the local network, they can also provide improved security by performing Domain Name System Security Extensions (DNSSEC) validation. DNSSEC validation enabled at the caching nameserver allows the authenticity and integrity of resource records to be validated prior to being placed in the cache for use by clients, and therefore protects clients against the consequences of cache poisoning.
Configuring And Administring unbound As a Caching Nameserver
Several packages are available for conﬁguring a caching nameserver, including bind, dnsmasq, and unbound. In this example, please follow along to conﬁgure and administer unbound as a secure, caching nameserver with DNSSEC validation enabled.
To conﬁgure unbound as a secure, caching nameserver:
1. Install unbound. As root, install the unbound package.
# yum install -y unbound
2. Start and enable unbound.service.
# systemctl start unbound.service # systemctl enable unbound.service ln -s '/usr/lib/systemd/system/unbound.service' '/etc/systemd/system/multi user.target.wants/unbound.service'
3. Conﬁgure the network interface to listen on.
By default, unbound only listens on the localhost network interface. To make unbound available to remote clients as a caching nameserver, use the interface option in the server clause of /etc/unbound/unbound.conf to specify the network interface(s) to listen on. A value of 0.0.0.0 will conﬁgure unbound to listen on all network interfaces:
4. Conﬁgure client access.
By default, unbound refuses recursive queries from all clients. In the server clause of /etc/unbound/unbound.conf, use the access-control option to specify which clients are allowed to make recursive queries.
access-control: 172.25.0.0/24 allow
5. Conﬁgure forwarding.
In /etc/unbound/unbound.conf, create a forward-zone clause to specify which DNS server(s) to forward queries to. DNS servers can be speciﬁed by host name using the forward-host option, or by IP address using the forward-addr option. For a caching nameserver, forward all queries by specifying a forward-zone of “.”.
forward-zone: name: "." forward-addr: 172.25.254.254
6. If desired, bypass DNSSEC validation for select unsigned zones.
By default, unbound is enabled to perform DNSSEC validation to verify all DNS responses received. The domain-insecure option in the server clause of /etc/unbound/ unbound.conf can be used to specify a domain for which DNSSEC validation should be skipped. This is often desirable when dealing with an unsigned internal domain that would otherwise fail trust chain validation.
7. If desired, install trust anchors for select signed zones without a complete chain of trust.
Since not all ccTLDs have completed the implementation of DNSSEC, the subdomains of these ccTLDs can be DNSSEC-signed but still have a broken chain of trust. This problem can be overcome by using the trust-anchor option in the server clause of /etc/unbound/ unbound.conf to specify a trust anchor for the zone. Obtain theDNSKEY record for the key signing key (KSK) of the zone using dig and input it as the value for the trust-anchor option.
$ dig +dnssec DNSKEY example.com
trust-anchor: "example.com. 3600 IN DNSKEY 257 3 8 AwEAAawt7HplI5M8GGAsxuyCyjF0l +QlcgVN11CRZ4vP66qbDCX0BnSh Z11BGb//4zSG/8mmBHirL2FLg+mVuIIxig+iroZYjh4iTKVOhv2hZftR wyrQHK++qXvCCWN3ki51RG/e8R4kOEV71rZ8OgQvPWx6F91qroqOPpcf 7PPxippeHOn+PxnP0hpyLyo1mx1rPs/cMpL3jOMufGP+LJYh+fBU7lt0 sP5i09HaJPruzyZML9BPtpv8ZAdQhwtXVG0+MnET2qT/1+TljpxZn6ye egFRCFRHBjMo6iiRJnUWra/ klkrgEn2Q+BXGTOMTTKQdYz4OxYEa1z7a pu3a09dYNBM="
8. Save changes to /etc/unbound/unbound.conf.
9. Check the /etc/unbound/unbound.conf conﬁguration ﬁle for syntax errors.
# unbound-checkconf unbound-checkconf: no errors in /etc/unbound/unbound.conf
10. Restart unbound.service.
# systemctl restart unbound.service
11. Conﬁgure the ﬁrewall to allow DNS trafﬁc.
# firewall-cmd --permanent --add-service=dns success # firewall-cmd --reload success
Dumping and loading unbound cache
Administrators of caching nameservers need to dump out cache data when troubleshooting DNS issues, such as those resulting from stale resource records. With an unbound DNS server, the cache can be dumped by running the unbound-control utility in conjunction with the dump_cache subcommand.
# unbound-control dump_cache START_RRSET_CACHE ;rrset 86395 1 0 3 3 classroom.example.com. 86395 IN A 172.25.254.254 ;rrset 86395 1 0 7 3 example.com. 86395 IN NS classroom. example.com. ;rrset 86395 1 0 8 3 example.com. 86395 IN A 172.25.254.254 END_RRSET_CACHE START_MSG_CACHE msg example.com. IN A 33152 1 86395 3 1 1 1 example.com. IN A 0 example.com. IN NS 0 classroom.example.com. IN A 0 END_MSG_CACHE EOF
Executingunbound-control with the dump_cache command dumps out the cache to stdout in a text format. This output can be directed to a ﬁle for storage and be loaded back into cache later with unbound-control load_cache, if desired. unbound-control load_cache reads from stdin to populate the cache.
# unbound-control load_cache < dump.out ok
Flushing unbound cache
Administrators of caching nameservers also need to purge outdated resource records from cache from time to time. Erroneous and outdated resource records in cache will keep their newly corrected counterparts from becoming available to clients until the TTLs on the outdated resource records expire. Rather than waiting for TTL expiration, administrators can forcibly purge the outdated records from cache by executing unbound-control with the flush subcommand.
# unbound-control flush www.example.com ok
If all resource records belonging to a domain need to be purged from the cache of an unbound DNS server, unbound-control can be executed with the flush_zone subcommand.
# unbound-control flush_zone example.com ok removed 3 rrsets, 1 messages and 0 key entries
Updating Local Caching unbound Conﬁguration with dnssectrigger
In addition to providing caching name service for a local subnet, unbound can also be useful as a local caching nameserver to provide secure DNS name resolution for local use on an individual system. For a local caching nameserver setup, the nameserver entry in /etc/resolv.conf will be conﬁgured to point to localhost where unbound is listening. The unbound conﬁguration will forward DNS requests to upstream nameservers and validate their responses.
For DHCP systems running local caching name service, the upstream nameservers speciﬁed in unbound’s conﬁguration may become outdated if DNS servers provided by DHCP change. The dnssec-trigger tool supplied by the package of the same name can be leveraged to automatically update forwarder settings in unbound’s conﬁguration ﬁle to point to the new DNS servers. The use of the dnssec-trigger tool in conjunction with unbound is mostly useful for secure DNS name resolution on roaming client machines.