Skip to content

Knot Resolver (kresd)

What Is It?

Knot Resolver is a caching, recursive DNS resolver developed by CZ.NIC (the Czech domain registry). It resolves DNS queries on behalf of clients by walking the DNS hierarchy, caching results for faster subsequent lookups. Unlike an authoritative server, a recursive resolver does not hold zone data — it fetches and caches answers from authoritative servers around the Internet.

In this course, kresd serves as the recursive resolver on port 53, while Knot DNS (knotd) handles authoritative duties on port 5353.

Installation

dnf install knot-resolver

The knot-utils package (installed as a dependency or separately via dnf install knot-utils) provides DNS utilities like kdig for testing.

Key Files and Directories

Path Purpose
/etc/knot-resolver/kresd.conf Main configuration file (Lua syntax)
/var/cache/knot-resolver/ Cache storage directory

Configuration

The configuration file uses Lua syntax. Order of directives matters — configure interfaces before modules that depend on them.

Minimal Working Configuration

To run kresd as a recursive resolver accessible from both localhost and external clients on port 53:

-- /etc/knot-resolver/kresd.conf

-- Listen on localhost and all interfaces, port 53
net.listen('127.0.0.1', 53, { kind = 'dns' })
net.listen('0.0.0.0', 53, { kind = 'dns' })

-- Set cache size (100 MB is reasonable for a small server)
cache.size = 100 * MB

Warning

Listening on 0.0.0.0 makes the resolver available to anyone who can reach your IP. For a lab environment this is fine, but in production you should restrict access via firewall rules or kresd's view module.

Important Directives

  • net.listen(address, port, options) — Bind to a specific address and port. The kind option can be 'dns' (default, plain DNS) or 'tls' (DNS-over-TLS).
  • cache.size — Set the maximum cache size in bytes. Use MB or GB multipliers (e.g., cache.size = 100 * MB).
  • modules.load('...') — Load additional modules (e.g., 'hints' for /etc/hosts integration, 'predict' for prefetching).

Disabling DNSSEC Validation

If the upstream zones are not DNSSEC-signed (as in this course), you can disable DNSSEC validation to avoid SERVFAIL responses:

-- Disable DNSSEC validation
trust_anchors.remove('.')

Post-Install Fix (CentOS Stream)

Known packaging issue

On CentOS Stream, the knot-resolver RPM may install files before the knot-resolver user is created, leaving runtime directories with incorrect ownership. If kresd@1.service fails to start with Permission denied errors, run:

install -d -o knot-resolver -g knot-resolver -m 0750 /run/knot-resolver /run/knot-resolver/control /var/cache/knot-resolver
chown -R knot-resolver:knot-resolver /usr/lib64/knot-resolver /var/lib/knot-resolver
systemctl restart kresd@1.service

Common Commands

# Start a single resolver instance
systemctl start kresd@1.service

# Enable at boot
systemctl enable kresd@1.service

# Start and enable in one command
systemctl enable --now kresd@1.service

# Check status
systemctl status kresd@1.service

# Restart after config changes
systemctl restart kresd@1.service

# Test resolution using kdig (from knot-utils)
kdig @127.0.0.1 google.com

# Test resolution using dig
dig @127.0.0.1 google.com

Note

kresd uses systemd template units (kresd@N.service). The @1 suffix is the instance number. For a single-core VM, one instance is sufficient.

Logging and Debugging

kresd logs to the systemd journal by default:

# View kresd logs
journalctl -u kresd@1.service

# Follow logs in real time
journalctl -f -u kresd@1.service

To increase verbosity, add to kresd.conf:

log_level('debug')

Security Considerations

  • Firewall: Open port 53 for both TCP and UDP:
    firewall-cmd --add-service=dns --permanent
    firewall-cmd --reload
    
  • Open resolver risk: A publicly accessible recursive resolver can be abused for DNS amplification attacks. In production, restrict access to trusted networks.

Further Reading