dotlinux blog

Setting up a Caching DNS Server in Ubuntu Server 14.04

DNS (Domain Name System) is the backbone of the internet, translating human-readable domain names (like google.com) into machine-readable IP addresses (like 172.217.16.14). A caching DNS server optimizes this process by storing (caching) DNS responses for a set period (TTL, or Time to Live). Subsequent queries for the same domain are answered from the cache—faster, more private, and with less bandwidth usage.

This guide will walk you through setting up a caching DNS server on Ubuntu Server 14.04 LTS using BIND9 (Berkeley Internet Name Domain), the most widely used DNS server software.

2026-05

Table of Contents#

  1. Prerequisites
  2. What is a Caching DNS Server?
  3. Installing BIND9
  4. Configuring BIND9
    a. Editing named.conf.options
    b. Verifying Configuration Syntax
    c. Restarting BIND9
  5. Testing the Caching DNS Server
  6. Troubleshooting Common Issues
  7. Securing Your Caching DNS Server
  8. Conclusion
  9. References

Prerequisites#

Before you begin, ensure you have:

  • Ubuntu Server 14.04 LTS: Critical Note—Ubuntu 14.04 reached End of Life (EOL) in April 2019 and no longer receives security updates. For production environments, use a supported release like Ubuntu Server 22.04 LTS. Proceed only if you must use 14.04.
  • A static IP address for your server (DNS servers require consistent IPs to function reliably).
  • Root or sudo access.
  • Basic familiarity with the Linux command line.

What is a Caching DNS Server?#

A caching DNS server does not host any domain records (like a primary/secondary DNS server). Instead, it:

  1. Receives a DNS query (e.g., "What is the IP of google.com?").
  2. Checks if it has the answer in its cache. If yes, it responds immediately.
  3. If not, it forwards the query to a forwarder (e.g., Google DNS, ISP DNS) to get the answer.
  4. Stores (caches) the answer for the TTL duration specified in the response.
  5. Serves the cached answer to future queries until the TTL expires.

Key Benefits#

  • Faster Queries: Cached responses are served in milliseconds.
  • Reduced Bandwidth: Less traffic to external DNS servers.
  • Privacy: Queries go through your server instead of your ISP’s (which may log data).

Installing BIND9#

BIND9 is the default DNS server for Ubuntu. Install it with:

sudo apt-get update
sudo apt-get install bind9 bind9utils bind9-doc

Package Breakdown#

  • bind9: Core DNS server software.
  • bind9utils: Utilities for debugging and managing BIND9 (e.g., dig, named-checkconf).
  • bind9-doc: Optional documentation (useful for learning advanced features).

After installation, verify BIND9 is running:

sudo service bind9 status

You should see output like:

bind9 is running

Configuring BIND9#

The main BIND9 configuration file is /etc/bind/named.conf.options. We’ll modify this to set up caching.

Step 1: Edit named.conf.options#

Open the file with a text editor (we’ll use nano for simplicity):

sudo nano /etc/bind/named.conf.options

Original Configuration#

The default file is mostly commented out:

options {
        directory "/var/cache/bind";

        // If your ISP provided DNS servers, use them as forwarders.
        // forwarders {
        //      0.0.0.0;
        // };

        dnssec-validation auto;

        auth-nxdomain no;    # Conform to RFC1035
        listen-on-v6 { any; };
};

Modified Configuration#

Replace the contents with the following (adjust values for your network):

options {
        directory "/var/cache/bind";

        // Listen for queries on localhost and your local network
        listen-on port 53 { 127.0.0.1; 192.168.1.0/24; };

        // Allow queries only from trusted devices (localhost + local network)
        allow-query { localhost; 192.168.1.0/24; };

        // Forward unresolved queries to Google DNS (replace with ISP DNS if preferred)
        forwarders {
                8.8.8.8;
                8.8.4.4;
        };

        dnssec-validation auto;  # Enable DNSSEC (verifies response authenticity)
        auth-nxdomain no;        # Conform to DNS standards
        listen-on-v6 { ::1; };   # Listen on IPv6 localhost (remove if not using IPv6)
        version "none;";         # Hide BIND version (prevents vulnerability scanning)
};

Key Directives Explained#

DirectivePurpose
listen-on port 53 { ... };Tells BIND9 which IPs to listen for queries on. Use your server’s static IP or subnet (e.g., 192.168.1.0/24 for a home network).
allow-query { ... };Restricts who can send queries to your server. Never use any;—this creates an open resolver (a security risk).
forwarders { ... };External DNS servers to use when the cache is empty. Google DNS (8.8.8.8, 8.8.4.4) is reliable, but you can use your ISP’s DNS instead.
version "none;";Hides the BIND9 version from external queries (prevents attackers from targeting known vulnerabilities).

Step 2: Verify Configuration Syntax#

Before restarting BIND9, check for syntax errors with:

sudo named-checkconf

If no output is returned, your configuration is valid!

Step 3: Restart BIND9#

Apply the changes by restarting BIND9:

sudo service bind9 restart

Testing the Caching DNS Server#

We’ll use dig (a DNS lookup tool from bind9utils) to test the cache.

Step 1: First Query (No Cache)#

Run this command to query google.com using your local DNS server:

dig google.com @localhost

Sample Output#

; <<>> DiG 9.9.5-3ubuntu0.17-Ubuntu <<>> google.com @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.     299     IN      A       172.217.16.14

;; Query time: 150 msec  # Slow—query forwarded to Google DNS
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Oct 10 14:00:00 UTC 2023
;; MSG SIZE  rcvd: 55

Step 2: Second Query (Cached)#

Run the same command again:

dig google.com @localhost

Sample Output#

; <<>> DiG 9.9.5-3ubuntu0.17-Ubuntu <<>> google.com @localhost
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 67890
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.     295     IN      A       172.217.16.14

;; Query time: 1 msec  # Fast—response from cache!
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Oct 10 14:00:05 UTC 2023
;; MSG SIZE  rcvd: 55

What Changed?#

  • Query Time: Dropped from 150ms to 1ms (cache hit).
  • TTL: Decreased from 299 to 295 (cache entries age over time).

If the query time doesn’t drop, double-check your forwarders and allow-query settings!

Troubleshooting Common Issues#

Here are fixes for frequent problems:

1. BIND9 Won’t Start#

Check the logs for errors:

sudo tail /var/log/syslog | grep named

Common causes:

  • Syntax errors in named.conf.options (fix with sudo named-checkconf).
  • Port 53 is in use (kill the conflicting process with sudo fuser -k 53/udp).

2. Firewall Blocking DNS Traffic#

Ubuntu’s default firewall (ufw) may block port 53 (used for DNS). Allow it:

sudo ufw allow 53/tcp
sudo ufw allow 53/udp
sudo ufw reload

3. No Response from Forwarders#

Test if your forwarders are reachable:

ping 8.8.8.8

If you get no response, your server may have no internet access or the forwarders are down. Replace them with your ISP’s DNS servers.

4. Cache Isn’t Working#

Ensure:

  • forwarders are set correctly in named.conf.options.
  • Your IP is included in allow-query.
  • BIND9 is running (sudo service bind9 restart).

Securing Your Caching DNS Server#

Caching DNS servers are targets for attacks (e.g., DNS amplification DDoS). Follow these steps to harden your server:

1. Restrict allow-query#

Never use allow-query { any; }—this makes your server an open resolver (abused in attacks). Only allow trusted networks (e.g., your home or office LAN).

2. Disable Recursion for Untrusted Clients#

Recursion (resolving queries for unknown domains) is required for caching—but only enable it for trusted clients. BIND9 defaults to recursion yes;, but allow-query already restricts access.

3. Hide BIND Version#

We added version "none;" to named.conf.options—this prevents attackers from targeting known vulnerabilities. Test it with:

dig @localhost version.bind CH TXT

You should see:

; <<>> DiG 9.9.5-3ubuntu0.17-Ubuntu <<>> @localhost version.bind CH TXT
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54321
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;version.bind.           CH      TXT

;; ANSWER SECTION:
version.bind.    0       CH      TXT     "none"

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Tue Oct 10 14:30:00 UTC 2023
;; MSG SIZE  rcvd: 62

4. Use AppArmor#

Ubuntu 14.04 includes AppArmor, a mandatory access control system that restricts BIND9’s file access. Verify it’s enabled:

sudo apparmor_status | grep bind9

Output:

bind9 (enforced)

5. Update BIND9 (Critical!)#

Ubuntu 14.04 is EOL, so no new security updates are available. If you must use it, ensure BIND9 is at the latest version for 14.04:

sudo apt-get upgrade bind9

Conclusion#

You’ve successfully set up a caching DNS server on Ubuntu Server 14.04! Key takeaways:

  • Caching DNS servers speed up queries and improve privacy.
  • BIND9 is powerful but requires careful configuration (especially for security).
  • Always restrict access to trusted networks to avoid abuse.

Next Steps#

  • Test with More Domains: Use dig to query different sites (e.g., facebook.com, github.com) and verify cache hits.
  • Monitor Cache Stats: Use sudo rndc stats to write cache statistics to /var/cache/bind/named.stats.
  • Set Up as Primary DNS: For advanced users, configure BIND9 as a primary DNS server for your domain (e.g., yourdomain.com).

References#

  1. BIND 9 Administrator Reference Manual
  2. Ubuntu Server Guide - DNS
  3. Google Public DNS
  4. Ubuntu 14.04 EOL Information
  5. DNS Amplification Attacks

Let me know if you have questions—happy caching! 🚀