How to Configure a Debian Server as a DNS Resolver on Debian 12 Bookworm

This guide will walk you through setting up a Debian 12 server as a DNS resolver using Unbound, a lightweight and efficient DNS resolver.

Introduction

A Domain Name System (DNS) resolver plays a crucial role in translating human-friendly domain names into IP addresses, enabling communication over the internet. Configuring a Debian 12 (Bookworm) server as a DNS resolver allows you to improve network performance, enforce security policies, and reduce dependency on external DNS providers.

This guide will walk you through setting up a Debian 12 server as a DNS resolver using Unbound, a lightweight and efficient DNS resolver. We will cover installation, configuration, and optimization for security and performance.

Prerequisites

Before you begin, ensure you have:

  • A Debian 12 (Bookworm) server with root or sudo access
  • A stable internet connection
  • Basic knowledge of Linux command-line usage

Step 1: Update Your System

Before installing any new packages, update your system to ensure all existing software is up to date:

sudo apt update && sudo apt upgrade -y

Step 2: Install Unbound

Unbound is a fast and secure validating, recursive, and caching DNS resolver. Install it using the following command:

sudo apt install unbound -y

Once installed, Unbound runs as a background service, but it requires configuration before use.

Step 3: Configure Unbound as a DNS Resolver

The main configuration file for Unbound is located at /etc/unbound/unbound.conf. Before making changes, create a backup of the default configuration:

sudo cp /etc/unbound/unbound.conf /etc/unbound/unbound.conf.bak

Now, open the configuration file for editing:

sudo nano /etc/unbound/unbound.conf

Modify the file with the following minimal configuration for a local DNS resolver:

server:
    verbosity: 1
    interface: 0.0.0.0
    interface: ::0
    access-control: 192.168.1.0/24 allow
    access-control: 127.0.0.0/8 allow
    access-control: ::1 allow
    cache-max-ttl: 86400
    cache-min-ttl: 3600
    num-threads: 2
    do-ip4: yes
    do-ip6: yes
    do-udp: yes
    do-tcp: yes
    root-hints: "/var/lib/unbound/root.hints"
    prefetch: yes
    hide-identity: yes
    hide-version: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: yes

Explanation of Configuration

  • interface: 0.0.0.0 and interface: ::0 – Listens on all IPv4 and IPv6 addresses
  • access-control: 192.168.1.0/24 allow – Allows local network clients to query the server
  • cache-max-ttl: 86400 – Caches responses for up to 24 hours
  • root-hints – Uses the latest root DNS servers for resolution
  • harden-glue and harden-dnssec-stripped – Enhances security
  • use-caps-for-id – Helps prevent spoofing attacks

Save and exit (CTRL + X, Y, Enter).

Step 4: Download and Update Root Hints

Root hints provide a list of authoritative root DNS servers. Download the latest version:

sudo curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.cache

Set the correct permissions:

sudo chown unbound:unbound /var/lib/unbound/root.hints

Step 5: Start and Enable Unbound Service

Restart the Unbound service to apply changes:

sudo systemctl restart unbound

Enable Unbound to start on boot:

sudo systemctl enable unbound

Check the status to ensure it’s running correctly:

sudo systemctl status unbound

Step 6: Configure the System to Use the Local Resolver

To direct DNS queries to your local resolver, update the system’s DNS configuration:

Edit /etc/resolv.conf:

sudo nano /etc/resolv.conf

Replace existing nameserver entries with:

nameserver 127.0.0.1

To prevent automatic overwrites by dhclient, make the file immutable:

sudo chattr +i /etc/resolv.conf

Step 7: Test Your DNS Resolver

To verify Unbound is resolving DNS queries correctly, use the dig or nslookup command:

dig example.com @127.0.0.1

or

nslookup example.com 127.0.0.1

If the output shows a valid response, your DNS resolver is working correctly.

Step 8: Enable DNSSEC for Additional Security

DNSSEC (Domain Name System Security Extensions) helps prevent DNS spoofing and attacks. To enable it, ensure the following line is present in /etc/unbound/unbound.conf:

server:
    val-log-level: 2
    auto-trust-anchor-file: "/var/lib/unbound/root.key"

Initialize the trust anchor:

sudo unbound-anchor -a /var/lib/unbound/root.key

Restart Unbound:

sudo systemctl restart unbound

Test DNSSEC validation:

dig +dnssec example.com @127.0.0.1

If DNSSEC is working, you will see an ad flag in the response, indicating that the answer is authenticated.

Step 9: Optimize Performance

For better performance, consider increasing cache size and adjusting thread count based on available resources. Edit /etc/unbound/unbound.conf:

server:
    msg-cache-size: 50m
    rrset-cache-size: 100m
    num-threads: 4

Restart Unbound:

sudo systemctl restart unbound

Conclusion

You have successfully configured a Debian 12 server as a DNS resolver using Unbound. This setup enhances network speed, security, and reliability. Regularly update root hints and trust anchors for optimal performance and security. By enabling DNSSEC and optimizing caching, you ensure a robust DNS resolving environment for your network.

Would you like to integrate this setup with additional security features, such as Pi-hole for ad blocking or firewall rules for controlled access?