Anyone using Knot-resolver?

I have several Raspberry Pi's so I always setup a new one when trying out something new. Otherwise you could get another SD-card so you can easily go back to the old one?

It's not harder than setting up Unbound though, probably easier.

yeah I have a spare Pi I think, may have a play.

Why is this required? Does using Knot hinder the usage stats, and / or client name displaying?

No, I just want it to say knot-resolver instead of just localhost in "queries answered by" on the dashboard. It is certainly not required.

Compile unbound from source, instructions here, no need to switch to unstable...

Are you willing to share your configuration file, so we can have a look at the tweaks?

Thanks, I didn't think it would be that "easy" compiling it myself. Not sure why it's taking so long getting 1.9.1 into testing/unstable, are they waiting for Buster?

Sure, I can share my kresd.conf, pretty sure it's not perfect though. The last part is from when I experimented with DoT.

-- Load useful modules
modules = {
'policy',
'hints',
'serve_stale < cache',
'workarounds < iterate',
'stats',
'predict'
}

net.ipv6 = false
net.bufsize(1472)

-- Auto-maintain root TA
trust_anchors.add_file('/usr/share/dns/root.key')

-- Root hints
hints.root_file = '/var/lib/knot-resolver/root.hints'

-- Cache size
cache.size = 200 * MB

-- Prefetch learning (30-minute blocks over 24 hours)
predict.config({ window = 30, period = 48})

-- Verbose logging to syslog
verbose(true)

tls_bundle='/etc/ssl/certs/ca-certificates.crt'

-- Forward queries encrypted to Cloudflare DoT
--policy.add(policy.all(policy.TLS_FORWARD({
-- {'1.1.1.1', hostname='cloudflare-dns.com', ca_file=tls_bundle},
-- {'1.0.0.1', hostname='cloudflare-dns.com', ca_file=tls_bundle}
--})))

1 Like

How about adding:

modules.load('prefill')
prefill.config({
      ['.'] = {
              url = 'https://www.internic.net/domain/root.zone',
              ca_file = '/etc/ssl/certs/ca-certificates.crt',
              interval = 86400  -- seconds
      }
})

edit
corrected the path of the ca_file.
from ca_file = '/etc/pki/tls/certs/ca-bundle.crt',
to ca_file = '/etc/ssl/certs/ca-certificates.crt',
/edit

reference for prefill here.
reference for ca-file here.

the equivalent in unbound (you need the compiled version) is:

auth-zone:
	name: "."
	master: i.root-servers.net
	master: f.root-servers.net
	master: j.root-servers.net
	master: k.root-servers.net
	fallback-enabled: yes
	for-downstream: no
	for-upstream: yes
	zonefile: "/root.zone"

Knot-resolver stores the data in the cache, whereas unbound stores the data in a file.

My goal is to run unboud (compiled version) and knot-resolver, both serving pihole-FTL (already works on my test pi).
pihole-FTL will than decide, based on the built in algorithm, witch resolver is the fastest and use it for a while. If unbound OR knot-resolver gets into trouble (doesn't work anymore), pihole-FTL will use the other available resolver.

To achieve this, I simply removed all server entries from /etc/dnsmasq.d/01-pihole.conf and added /etc/dnsmasq.d/04-servers.conf, content:

# unbound
server=127.10.10.2#5552
server=fdaa:bbcc:ddee:2::5552#5552
# knot-resolver
server=127.10.10.5#5555
server=fdaa:bbcc:ddee:2::5555#5555

I assume you got some of the configuration changes you made here. If you have a better information source, please let us know.

1 Like

I briefly tried the prefill module but I couldn't get it to work, that was in the beginning though so I might give it another try. Thanks, this is exactly why I started this thread! :slight_smile:

Interesting idea running both Unbound and Knot in parallell, let me know how it turns out!

That's right, that tutorial on Knot was the one that got me started. Only one I could find to be honest, I'm surprised there aren't more out there. I'll let you know if I find others. Oh and I got some pointers from someone on Reddit too...

Thanks!

EDIT: I tried prefill but get this error...

May 10 14:55:36 pihole systemd[1]: Starting Knot Resolver daemon...
May 10 14:55:37 pihole kresd[399]: [ ta ] warning: overriding previously set trust anchors for .
May 10 14:55:37 pihole systemd[1]: Started Knot Resolver daemon.
May 10 14:55:37 pihole kresd[399]: [prefill] downloading root zone...
May 10 14:55:37 pihole kresd[399]: [prefill] cannot download new zone (/usr/lib/knot-resolver/kres_modules/prefill.lua:88: [prefill] fetch of https://www.internic.net/domain/root.zone failed: temporary failure in name resolution), will retry root zone download in 09 minutes 54 seconds
May 10 14:55:37 pihole kresd[399]: [ta_update] refreshing TA for .
May 10 14:55:43 pihole kresd[399]: [ta_update] key: 20326 state: Valid
May 10 14:55:43 pihole kresd[399]: [ta_update] next refresh for . in 12 hours

I don't really know if using the prefill module will benefit your configuration. You are using cloudflare, so the DNS request will always be completely resolved by cloudflare.
If you are querying discourse.pi-hole.net (with the cloudflare setup active), you are asking cloudflare to resolve discourse.pi-hole.net. cloudflare will do that, and immediately send you the resulting IP address.
The downside is that cloudflare knows you visited discourse.pi-hole.net (and every other site you visit).

By using the recursive approach (described for unbound here), only the targeted DNS server will know this. e.g. if you visit google.com, google will know you where there, but if you visit yahoo.com, google will never know, and of course visa versa.
If you use a recursive approach, this is what I think happens:

  • client queries discourse.pi-hole.net
  • pihole-FTL sends the request (if NOT cached OR blocked) to knot-resolver.
  • knot-resolvers asks the root server: who serves net (wouldn't do that with prefill, would already know this - cached)
  • root server replies: net is served by DNS server x.x.x.x
  • knot-resolver asks server x.x.x.x: who serves pi-hole.net
  • server x.x.x.x replies: pi-hole.net is served by DNS y.y.y.y
  • knot-resolver asks server y.y.y.y: what is the IP for discourse.pi-hole.net
  • server y.y.y.y replies: IP for discourse.pi-hole.net is 167.99.26.239
  • knot-resolver replies to pihole-FTL: A 167.99.26.239
  • pihole-FTL replies to client: A 167.99.26.239

I hope these steps are correct, that is how I always thought it works.

You may think this is overly complex, but if you use cloudflare, the same thing happens, it isn't the knot-resolver making all those queries, cloudflare will do this, you just don't see these requests.

The advantage is obviously privacy. server y.y.y.y will only see the requests to discourse.pi-hole.net, but doesn't know about any other sites. When using cloudflare, they have your complete browsing history.

I'm not using forwarding, thoses lines are commented out. I only tried it once and then left it commented for reference... :slight_smile:

EDIT: I changed my Pi-hole DNS to cloudflare in the dashboard and then it work. I suppose it needs another DNS than itself when downloading root zone? I will see what happens in a day when it refreshes...

I had a similar problem:

May 10 15:40:16 raspberrypi kresd[27105]: [prefill] downloading root zone...
May 10 15:40:17 raspberrypi kresd[27105]: [prefill] cannot download new zone (/usr/lib/knot-resolver/kres_modules/prefill.lua:88: [prefill] fetch of `https://www.internic.net/domain/root.zone` failed: error loading CA locations (No such file or directory)), will retry root zone download in 09 minutes 52 seconds

solved, reference here.

replace the line

ca_file = '/etc/pki/tls/certs/ca-bundle.crt',

with

ca_file = '/etc/ssl/certs/ca-certificates.crt',

result:

May 10 15:46:41 raspberrypi kresd[28519]: [prefill] downloading root zone...
May 10 15:46:44 raspberrypi kresd[28519]: [prefill] saving root zone...
May 10 15:46:44 raspberrypi kresd[28519]: [prefill] root zone successfully parsed, import started
May 10 15:46:44 raspberrypi kresd[28519]: [prefill] root zone refresh in 23 hours 59 minutes

also added the following:

hints.root({
  ['i.root-servers.net.'] = { '2001:7fe::53', '192.36.148.17' }
})

reference, again here (You can also use the module to change the root hints; they are used as a safety belt or if the root NS drops out of cache).
You should probably select a root server near by, select one here.

Thanks but my ca_file is correct, my error was name resolution error. When I changed the dns on the pihole dashboard to 1.1.1.1 it worked. Not sure why, you’re running it on a pihole too right?

I have downloaded the hints file and point to it in my kresd.conf because the debian one was old before the last update.
hints.root_file = ‘/var/lib/knot-resolver/root.hints’

Do I still need this then?

hints.root({
  ['i.root-servers.net.'] = { '2001:7fe::53', '192.36.148.17' }
})

Also when I reboot and check the status of the service I get this, any idea why?

Warning: kresd@1.service changed on disk. Run 'systemctl daemon-reload' to reload units.

Whenever you change something in /lib/systems/system, systemctl will notice that and generate the warning. just run sudo systemctl daemon-reload ant the warning will go away.

The reference says: You can also use the module to change the root hints; they are used as a safety belt or if the root NS drops out of cache. I suppose it doesn't hurt to have the entry, but, also new to this, not sure

Yes, sudo systemctl daemon-reload makes it go away but I don't quite understand what has changed...

Yeah, can't hurt I guess! :slight_smile: Thanks for all the help!

You can use stat to check the file history, e.g. stat /lib/system/system/kresd@1.service

What is the content of this file? (just to verify)

It started when I added the prefill settings...

[Unit]
Description=Knot Resolver daemon
Documentation=man:kresd.systemd(7)
Documentation=man:kresd(8)

[Service]
Type=notify
WorkingDirectory=/var/cache/knot-resolver
ExecStart=/usr/sbin/kresd --config=/etc/knot-resolver/kresd.conf
User=knot-resolver
Restart=on-abnormal
Sockets=kresd.socket
Sockets=kresd-tls.socket
Sockets=kresd-control@%i.socket

[Install]
WantedBy=kresd.target

changing the knot-resolver configuration file (in /etc/knot-resolver) should NOT affect systemctl. Only changes in /lib/system/system should trigger this message. Are you sure you didn't change anything there, if NOT, strange ...

Nope, it started just after I added the prefill setting. Didn't touch anything else...

I think I'll setup a new Pi and see what I get... :slight_smile:

Thanks!

got it up and running yesterday, but got distracted by this problem. I read this reply from you (I think I’ll setup a new Pi and see what I get), so you will be running into this too...

Looks impressive! I might try something like this some day... :slight_smile: Would you mind posting your Unbound config?

Thanks for the heads up!

I've got for files for unbound.
/etc/unbound/unbound.conf, content:

# Unbound configuration file for Debian.
#
# See the unbound.conf(5) man page.
#
# See /usr/share/doc/unbound/examples/unbound.conf for a commented
# reference config file.
#
# The following line includes additional configuration files from the
# /etc/unbound/unbound.conf.d directory.
include: "/etc/unbound/unbound.conf.d/*.conf"

/etc/unbound/unbound.conf.d/qname-minimisation.conf, content:

server:
    # Send minimum amount of information to upstream servers to enhance
    # privacy. Only sends minimum required labels of the QNAME and sets
    # QTYPE to NS when possible.

    # See RFC 7816 "DNS Query Name Minimisation to Improve Privacy" for
    # details.
	
	# https://ripe72.ripe.net/presentations/120-unbound_qnamemin_ripe72.pdf
	# test: drill txt qnamemintest.internet.nl
	# result: "HOORAY - QNAME minimisation is enabled on your resolver :)!"

    qname-minimisation: yes
	harden-below-nxdomain: yes

/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf, content:

server:
    # The following line will configure unbound to perform cryptographic
    # DNSSEC validation using the root trust anchor.
    auto-trust-anchor-file: "/etc/unbound/root.key"

/etc/unbound/unbound.conf.d/unbound.conf, content:

## See wiki: https://github.com/pi-hole/pi-hole/...
#
server:
	logfile: /unbound.log
	log-time-ascii: yes
    verbosity: 1
	interface: 127.10.10.2@5552
	interface: fdaa:bbcc:ddee:2::5552@5552
    #port: 5552
    do-ip4: yes
    do-udp: yes
    do-tcp: yes
	
    # May be set to yes if you have IPv6 connectivity
    do-ip6: yes

    # Use this only when you downloaded the list of primary root servers!
    root-hints: "/root.hints"

	# enable to not answer id.server and hostname.bind queries.
	# hide-identity: yes

	# enable to not answer version.server and version.bind queries.
	# hide-version: yes
	
    # Trust glue only if it is within the servers authority
    harden-glue: yes

    # Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
    harden-dnssec-stripped: yes
	
	# Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
	# and other denials, using information from previous NXDOMAINs answers.
	aggressive-nsec: yes

    # Use Capitalization randomization
    # This is an experimental resilience method which uses upper and lower case letters in the question hostname to obtain randomness. Two names with the same spelling but different case should be treated as identical.
    # Attackers hoping to poison a DNS cache must guess the mixed-case encoding of the query. This increases the difficulty of such an attack significantly
    use-caps-for-id: no

    # TTL bounds for cache
    cache-min-ttl: 3600
    cache-max-ttl: 86400

    # Perform prefetching of close to expired message cache entries
    # This only applies to domains that have been frequently queried
    prefetch: yes

    # One thread should be sufficient, can be increased on beefy machines
    num-threads: 1

    # Ensure kernel buffer is large enough to not loose messages in traffix spikes
    so-rcvbuf: 1m

    # Number of bytes size to advertise as the EDNS reassembly  buffer size.
	# This  is  the  value put into datagrams over UDP towards peers.
	# The actual buffer size is determined by  msg-buffer-size(both  for  TCP  and  UDP).
	# Do not set higher than that value.
    # Default is 4096 which is RFC recommended.
	# If you have fragmentation reassembly problems,
	# usually  seen as timeouts, then a value of 1472 can fix it.
	# Setting to 512 bypasses even the most stringent path MTU problems,
	# but is seen as extreme, since the amount of TCP fallback generated is
	# excessive (probably also for this resolver, consider tuning the outgoing tcp number).
	edns-buffer-size: 1472
	
    # Ensure privacy of local IP ranges
    private-address: 192.168.0.0/16
	private-address: 169.254.0.0/16
	private-address: 172.16.0.0/12
	private-address: 10.0.0.0/8
	private-address: fd00::/8
	private-address: fe80::/10
	
	# Access Control
	access-control: fdaa:bbcc:ddee:2::5552/128 allow

# Remote control config section.
remote-control:
	control-enable: yes

# Copy of the root for local usage
auth-zone:
	name: "."
	master: i.root-servers.net
	master: f.root-servers.net
	master: j.root-servers.net
	master: k.root-servers.net
	fallback-enabled: yes
	for-downstream: no
	for-upstream: yes
	zonefile: "/root.zone"

As you can see, I no longer use pihole-FTL for DNSSEC (to many problems), both unbound and knot-resolver are capable of doing this.

2 Likes