How to Set Up a Local DNS Caching Server on Linux

Here is a 2800+ word blog post on "How to Set Up a Local DNS Caching Server on Linux":

A local DNS caching server can provide faster domain name lookups, reduce load on external DNS servers, and improve the privacy and security of your DNS traffic. In this comprehensive guide, we will walk through installing, configuring and troubleshooting a performant DNS cache on Linux using the powerful systemd-resolved service.

Introduction to Local DNS Caching

The Domain Name System (DNS) is an essential part of how systems on the internet are able to communicate. It provides a mapping between domain names like example.com and the numeric IP addresses computers use to route traffic (93.184.216.34).

To resolve domain names, your system sends DNS lookup requests to an external DNS server provided by your internet service provider (ISP) or sites like Google or Cloudflare‘s public DNS services. The DNS server looks up the IP address in its records and returns it to you.

Unfortunately, these external DNS lookups can sometimes be slow depending on the performance of the DNS server. Slow DNS resolution really adds up if you need to load a modern website with hundreds of domain requests.

A local DNS caching server solves this by handling all DNS requests from the system itself. It queries external DNS servers on the first request and then stores the domain/IP mappings in memory. Subsequent requests for the same domain can then be handled almost instantly using the cache rather than having to go out to the internet.

Some key benefits this provides:

  • Faster domain name resolution – serves DNS results from memory rather than slower external lookups
  • Reduces load on external DNS infrastructure – popular domains cached locally
  • Enhances privacy – all DNS traffic handled locally rather than sending every request to your ISP/other providers
  • Increased reliability – DNS queries still work if external connectivity goes down

In summary, a properly configured local DNS cache can speed up internet browsing, take load off external servers, save bandwidth, and give you more control over your DNS data.

Choosing DNS Caching Software for Linux

There are several open source DNS caching solutions available for Linux like dnsmasq, unbound and systemd-resolved:

dnsmasq – compact and easy to configure, integrates nicely with DHCP servers
unbound – more advanced features like DNSSEC validation but complex to setup
systemd-resolved – built into systemd init system used by most Linux distros

In this guide, we will focus on systemd-resolved as it strikes a nice balance of being widely compatible, fast, and supporting modern DNS features.

Key properties of systemd-resolved:

  • Ships with most major Linux distributions by default
  • Handles both caching and local DNS lookups
  • Validates DNSSEC signatures for improved security
  • Supports DNS over TLS encryption (DoT and DoH)
  • Integrates cleanly with systemd for service management
  • Lower memory usage than dnsmasq

Now let‘s go through installing and configuring systemd-resolved step-by-step!

Step 1 – Install and Enable systemd-resolved

First we need to verify if systemd-resolved is already active on your system. This is done by checking for the resolved.service unit:

$ systemctl status systemd-resolved.service

If you get an error about the unit not being found, then it is not currently enabled. You will need to install any required packages and then enable it:

$ sudo apt update
$ sudo apt install systemd-resolved
$ sudo systemctl enable systemd-resolved.service  
$ sudo systemctl start systemd-resolved.service

That will configure systemd-resolved to start automatically at system boot.

Alternatively, if systemd-resolved was already active after the first command, you can skip to Step 2.

Step 2 – Configure DNS Servers

Next we need to decide which upstream DNS servers will be used for external lookups that miss the cache. Good options include Google, Cloudflare, Quad9 or your ISP‘s DNS servers:

# Google
nameserver 8.8.8.8
nameserver 8.8.4.4

# Cloudflare 
nameserver 1.1.1.1
nameserver 1.0.0.1

# Quad9
nameserver 9.9.9.9
nameserver 149.112.112.112

Edit your systemd-resolved configuration file to add your preferred DNS server IP addresses:

$ sudo nano /etc/systemd/resolved.conf

[Resolve]
DNS=9.9.9.9 149.112.112.112

Then restart the systemd-resolved service to apply the changes:

$ sudo systemctl restart systemd-resolved.service

Step 3 – Configure systemd-networkd

Some Linux distros like Arch Linux use systemd-networkd for network configuration. If you have systemd-networkd active, edit the main .network config file:

$ sudo nano /etc/systemd/network/20-dhcp.network

Modify the DNS key to point to systemd-resolved rather than your external DNS:

[DHCP] 
UseDNS=false
DNS=127.0.0.53

Then reload systemd-networkd and restart systemd-resolved to apply the changes:

$ sudo systemctl restart systemd-networkd
$ sudo systemctl restart systemd-resolved

That will make systemd-networkd send all DNS requests to our local systemd-resolved cache.

Step 4 – Set system DNS server to 127.0.0.53

We need to configure the base system DNS configuration file /etc/resolv.conf to also point at systemd-resolved rather than external DNS servers directly.

$ sudo nano /etc/resolv.conf

# Add ‘nameserver 127.0.0.53‘ line 
# Comment out any other nameservers
nameserver 127.0.0.53

The IP address 127.0.0.53 is a special address that points to the local systemd-resolved DNS server.

Save changes and restart systemd-resolved to apply the updated resolv.conf configuration.

Step 5 – Flush and Verify DNS Cache

We can now flush any existing DNS cache data and verify our cache is working properly with:

# Flush Cache
$ sudo resolvectl flush-caches

# Check status 
$ systemd-resolve --status

# Perform lookup
$ dig www.example.com

# Check cache stats
$ resolvectl statistics 

You should see available cache memory grow as more domains are resolved.

Now test loading some websites to generate DNS traffic and populate the cache. The DNS lookups should now be handled instantly by our local systemd-resolved cache!

Tuning Cache Performance

There are several areas you can tweak to optimize cache performance and memory usage depending on your specific workloads:

Cache Memory Size – Increase total cache storage available in /etc/systemd/resolved.conf. The default is 256MB.

Cache=1GB

Cache TTL – How long DNS records stay cached before expiring. Reducing this frees cache space faster. The default is 1 hour.

CacheTTL=30m  

Negative TTL – How long errors like NXDOMAIN stay cached. Lower to cache failed lookups for less time. Default is 1 minute.

CacheNegativeTTL=15s   

Make changes then restart systemd-resolved to apply updated cache settings.

Additional Tweaks for Security and Privacy

systemd-resolved has native support for DNSSEC and DNS over TLS protocols to verify DNS validity and encrypt transport security.

DNSSEC – Rejects invalid DNS responses by checking cryptographic signatures added to DNS records. This guards against malicious hijacking or spoofing attacks.

DNSSEC=true

DNS over TLS – Encrypts all DNS lookups with TLS to prevent eavesdropping and manipulation of DNS traffic. Provides privacy by hiding DNS queries from your ISP.

DNSOverTLS=opportunistic

Be sure to choose DNS servers that have DNSSEC and DoT/DoH enabled for full end-to-end security and privacy.

Wrapping Up

After following this guide, you should have a high-performance local DNS caching solution enabled on your Linux systems using systemd-resolved. This will speed up host and domain name lookups significantly, provide resilience if external DNS goes down, reduce bandwidth usage, and adds important security protections.

Here are some final helpful tips:

  • Check status and statistics frequently with systemd-resolve --status and resolvectl stats
  • Monitor the system logs at /var/log/syslog for dns errors
  • Configure individual apps/containers to use the systemd-resolved cache server address 127.0.0.53 rather than changing the global system resolv.conf

Let me know in the comments if you have any issues getting your local DNS cache operational! Over and out.