MatthewVance / unbound-docker-rpi

Run Unbound with latest version of OpenSSL on Raspberry Pi with Docker.
MIT License
144 stars 23 forks source link

Questions re: Developer's Example Raspberry Pi Config File #10

Closed johntdavis84 closed 3 years ago

johntdavis84 commented 3 years ago

Hello, @MatthewVance ,

In another issue thread (thanks again for all your help over there!), you provided this sample unbound.conf file:

I've got some questions about why certain values were chosen, which I highlighted below.

  1. Min/Max Cache: I also run a reverse proxy which works with Cloudflare DNS on my domain. Will these cache times potentially cause problems with that setup?
  2. logfile: /dev/null: Does this mean it doesn't log anything at all? I think I'm misunderstanding something. What exactly gets tossed into the ether, here?
  3. do-daemonize: no: The documentation says: "Enable or disable whether the unbound server forks into the background as a daemon. Set the value to no when unbound runs as systemd service. Default is yes." Is systemd being used inside the container? Is something else going on?
  4. neg-cache-size: 4M: What does this do? The docs assume I understand a lot more about DNS than I do.
  5. Access control, part 1: What is the absolute minimum I should give it access to, in terms of subnets? The two I know for sure it needs are the localhost subnet and the internal docker network subnet (that unbound shares with pihole). Does it need the generic 10.x and 192.168.x blocks?
  6. Access control, part 2: I noticed you're not allowing access from any IPv6 addresses, including localhost. Any specific reason why? I have an IPv6-enabled setup, so I could use it, but does it provide any benefit to actually turn it on for DNS?
  7. auto-trust-anchor-file: "var/root.key": Is this root.key suitable for a server meant never to be a fully self-sustaining DNS server? (That is, I want to be able to resolve any address without relying on something like Cloudflare DNS.)
  8. private-address: What address ranges do I need to include for this, aside from localhost's subnet and the pi-hole network's (172.x.x.x)? My host network (my actual LAN) runs on 10.x.x.x). I'm not using 169.254.x.x or 192.168.x.x for anything, anywhere.
  9. tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt: Is this inside the container? I honestly have no idea where the tls-cert-bundle is on Manjaro Linux (the host OS). If I needed to change it, I'm not sure I'd know how.
  10. use-caps-for-id: yes: Have you run into any issues with this on a Raspberry Pi? One of the tutorials I found had it set to no because it could otherwise cause Pi-specific errors, but that might be due to an old version of ... something.
  11. PERFORMANCE SETTINGS: I have a 4GB Raspberry Pi 4B, overclocked to 2GHz stable. I'm running Manjaro ARM, a 64-bit OS with a 64-bit userland. Should I modify any of this?
  12. Finally: Does this create an "authoritative, validating, recursive, caching DNS server? That's what I was hoping to end up with.

server: ###########################################################################

BASIC SETTINGS

###########################################################################
# Time to live maximum for RRsets and messages in the cache. If the maximum
# kicks in, responses to clients still get decrementing TTLs based on the
# original (larger) values. When the internal TTL expires, the cache item
# has expired. Can be set lower to force the resolver to query for data
# often, and not trust (very large) TTL values.
cache-max-ttl: 86400

# Time to live minimum for RRsets and messages in the cache. If the minimum
# kicks in, the data is cached for longer than the domain owner intended,
# and thus less queries are made to look up the data. Zero makes sure the
# data in the cache is as the domain owner intended, higher values,
# especially more than an hour or so, can lead to trouble as the data in
# the cache does not match up with the actual data any more.
cache-min-ttl: 300

# Set the working directory for the program.
directory: "/opt/unbound/etc/unbound"

# RFC 6891. 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  1232 which is the DNS Flag Day 2020 recommendation.
# 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: 1232

# Listen to for queries from clients and answer from this network interface
# and port.
interface: 0.0.0.0@53

# Rotates RRSet order in response (the pseudo-random number is taken from
# the query ID, for speed and thread safety).
rrset-roundrobin: yes

# Drop user  privileges after  binding the port.
username: "_unbound"

###########################################################################
# LOGGING
###########################################################################

# Do not print log lines to inform about local zone actions
log-local-actions: no

# Do not print one line per query to the log
log-queries: no

# Do not print one line per reply to the log
log-replies: no

# Do not print log lines that say why queries return SERVFAIL to clients
log-servfail: no

# Further limit logging
logfile: /dev/null

# Only log errors
verbosity: 0

###########################################################################
# PRIVACY SETTINGS
###########################################################################

# RFC 8198. Use the DNSSEC NSEC chain to synthesize NXDO-MAIN and other
# denials, using information from previous NXDO-MAINs answers. In other
# words, use cached NSEC records to generate negative answers within a
# range and positive answers from wildcards. This increases performance,
# decreases latency and resource utilization on both authoritative and
# recursive servers, and increases privacy. Also, it may help increase
# resilience to certain DoS attacks in some circumstances.
aggressive-nsec: yes

# Extra delay for timeouted UDP ports before they are closed, in msec.
# This prevents very delayed answer packets from the upstream (recursive)
# servers from bouncing against closed ports and setting off all sort of
# close-port counters, with eg. 1500 msec. When timeouts happen you need
# extra sockets, it checks the ID and remote IP of packets, and unwanted
# packets are added to the unwanted packet counter.
delay-close: 10000

# Prevent the unbound server from forking into the background as a daemon
do-daemonize: no

# Add localhost to the do-not-query-address list.
do-not-query-localhost: no

# Number  of  bytes size of the aggressive negative cache.
neg-cache-size: 4M

# Send minimum amount of information to upstream servers to enhance
# privacy (best privacy).
qname-minimisation: yes

###########################################################################
# SECURITY SETTINGS
###########################################################################
# Only give access to recursion clients from LAN IPs
access-control: 127.0.0.1/32 allow
access-control: 192.168.0.0/16 allow
access-control: 172.16.0.0/12 allow
access-control: 10.0.0.0/8 allow
# access-control: fc00::/7 allow
# access-control: ::1/128 allow

# File with trust anchor for  one  zone, which is tracked with RFC5011
# probes.
auto-trust-anchor-file: "var/root.key"

# Enable chroot (i.e, change apparent root directory for the current
# running process and its children)
chroot: "/opt/unbound/etc/unbound"

# Deny queries of type ANY with an empty response.
deny-any: yes

# Harden against algorithm downgrade when multiple algorithms are
# advertised in the DS record.
harden-algo-downgrade: yes

# RFC 8020. returns nxdomain to queries for a name below another name that
# is already known to be nxdomain.
harden-below-nxdomain: yes

# Require DNSSEC data for trust-anchored zones, if such data is absent, the
# zone becomes bogus. If turned off you run the risk of a downgrade attack
# that disables security for a zone.
harden-dnssec-stripped: yes

# Only trust glue if it is within the servers authority.
harden-glue: yes

# Ignore very large queries.
harden-large-queries: yes

# Perform additional queries for infrastructure data to harden the referral
# path. Validates the replies if trust anchors are configured and the zones
# are signed. This enforces DNSSEC validation on nameserver NS sets and the
# nameserver addresses that are encountered on the referral path to the
# answer. Experimental option.
harden-referral-path: no

# Ignore very small EDNS buffer sizes from queries.
harden-short-bufsize: yes

# Refuse id.server and hostname.bind queries
hide-identity: yes

# Refuse version.server and version.bind queries
hide-version: yes

# Report this identity rather than the hostname of the server.
identity: "DNS"

# These private network addresses are not allowed to be returned for public
# internet names. Any  occurrence of such addresses are removed from DNS
# answers. Additionally, the DNSSEC validator may mark the  answers  bogus.
# This  protects  against DNS  Rebinding
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
# private-address: fd00::/8
# private-address: fe80::/10
# private-address: ::ffff:0:0/96

# Enable ratelimiting of queries (per second) sent to nameserver for
# performing recursion. More queries are turned away with an error
# (servfail). This stops recursive floods (e.g., random query names), but
# not spoofed reflection floods. Cached responses are not rate limited by
# this setting. Experimental option.
ratelimit: 1000

# Use this certificate bundle for authenticating connections made to
# outside peers (e.g., auth-zone urls, DNS over TLS connections).
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt

# Set the total number of unwanted replies to eep track of in every thread.
# When it reaches the threshold, a defensive action of clearing the rrset
# and message caches is taken, hopefully flushing away any poison.
# Unbound suggests a value of 10 million.
unwanted-reply-threshold: 10000

# Use 0x20-encoded random bits in the query to foil spoof attempts. This
# perturbs the lowercase and uppercase of query names sent to authority
# servers and checks if the reply still has the correct casing.
# This feature is an experimental implementation of draft dns-0x20.
# Experimental option.
use-caps-for-id: yes

# Help protect users that rely on this validator for authentication from
# potentially bad data in the additional section. Instruct the validator to
# remove data from the additional section of secure messages that are not
# signed properly. Messages that are insecure, bogus, indeterminate or
# unchecked are not affected.
val-clean-additional: yes

###########################################################################
# PERFORMANCE SETTINGS
###########################################################################
# https://nlnetlabs.nl/documentation/unbound/howto-optimise/
# https://nlnetlabs.nl/news/2019/Feb/05/unbound-1.9.0-released/

# Number of slabs in the infrastructure cache. Slabs reduce lock contention
# by threads. Must be set to a power of 2.
infra-cache-slabs: 4

# Number of incoming TCP buffers to allocate per thread. Default
# is 10. If set to 0, or if do-tcp is "no", no  TCP  queries  from
# clients  are  accepted. For larger installations increasing this
# value is a good idea.

incoming-num-tcp: 10

# Number of slabs in the key cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2. Setting (close) to the number
# of cpus is a reasonable guess.
key-cache-slabs: 4

# Number  of  bytes  size  of  the  message  cache.
# Unbound recommendation is to Use roughly twice as much rrset cache memory
# as you use msg cache memory.
msg-cache-size: 131294549

# Number of slabs in the message cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2. Setting (close) to the number of
# cpus is a reasonable guess.
msg-cache-slabs: 4

# The number of queries that every thread will service simultaneously. If
# more queries arrive that need servicing, and no queries can be jostled
# out (see jostle-timeout), then the queries are dropped.
# This is best set at half the number of the outgoing-range.
# This Unbound instance was compiled with libevent so it can efficiently
# use more than 1024 file descriptors.
num-queries-per-thread: 4096

# The number of threads to create to serve clients.
# This is set dynamically at run time to effectively use available CPUs
# resources
num-threads: 3

# Number of ports to open. This number of file descriptors can be opened
# per thread.
# This Unbound instance was compiled with libevent so it can efficiently
# use more than 1024 file descriptors.
outgoing-range: 8192

# Number of bytes size of the RRset cache.
# Use roughly twice as much rrset cache memory as msg cache memory
rrset-cache-size: 262589098

# Number of slabs in the RRset cache. Slabs reduce lock contention by
# threads. Must be set to a power of 2.
rrset-cache-slabs: 4

# Do no insert authority/additional sections into response messages when
# those sections are not required. This reduces response size
# significantly, and may avoid TCP fallback for some responses. This may
# cause a slight speedup.
minimal-responses: yes

# # Fetch the DNSKEYs earlier in the validation process, when a DS record
# is encountered. This lowers the latency of requests at the expense of
# little more CPU usage.
prefetch: yes

# Fetch the DNSKEYs earlier in the validation process, when a DS record is
# encountered. This lowers the latency of requests at the expense of little
# more CPU usage.
prefetch-key: yes

# Have unbound attempt to serve old responses from cache with a TTL of 0 in
# the response without waiting for the actual resolution to finish. The
# actual resolution answer ends up in the cache later on.
serve-expired: yes

# Open dedicated listening sockets for incoming queries for each thread and
# try to set the SO_REUSEPORT socket option on each socket. May distribute
# incoming queries to threads more evenly.
so-reuseport: yes

###########################################################################
# LOCAL ZONE
###########################################################################

# Include file for local-data and local-data-ptr
include: /opt/unbound/etc/unbound/a-records.conf
include: /opt/unbound/etc/unbound/srv-records.conf

###########################################################################
# FORWARD ZONE
###########################################################################

include: /opt/unbound/etc/unbound/forward-records.conf

remote-control: control-enable: no

MatthewVance commented 3 years ago

Here's some quick answers:

1. Min/Max Cache: I also run a reverse proxy which works with Cloudflare DNS on my domain. Will these cache times potentially cause problems with that setup?

I'm not sure I understand. The Unbound cache functions independently. You'll have to keep it and your reverse proxy caches in mind when troubleshooting issues. I doubt it'd cause any issues under normal circumstances. If it does, you could always shut one down briefly during troubleshooting, clear the cache, etc.

The main benefit of having Unbound cache items is to speed up DNS responses on your network. You should be able to see this in action by running dig somesiteyouhavenotbeento.com and looking twice. The second response time shown by dig should be much faster (relative term when talking msec's).

2. logfile: /dev/null: Does this mean it doesn't log anything at all? I think I'm misunderstanding something. What exactly gets tossed into the ether, here?

That's right. No logging at all. Privacy first. Users of this image can re-configure if logging is needed.

3. do-daemonize: no: The documentation says: "Enable or disable whether the unbound server forks into the background as a daemon. Set the value to no when unbound runs as systemd service. Default is yes." Is systemd being used inside the container? Is something else going on?

Remember this is docker, not bare metal.

4. neg-cache-size: 4M: What does this do? The docs assume I understand a lot more about DNS than I do.

I'm not DNS expert either. My assumption is it's related to what's described in https://tools.ietf.org/html/rfc2308. If so, I would think it sets a 4M cache to reduce the response time for negative answers.

5. Access control, part 1: What is the absolute minimum I should give it access to, in terms of subnets? The two I know for sure it needs are the localhost subnet and the internal docker network subnet (that unbound shares with pihole). Does it need the generic 10.x and 192.168.x blocks?

Only the CIDRs for your local network(s). The default config I provide won't know if a user has a 10.x, 192.168.x, etc. so I include the full RFC1918 space. That being said, no need to stress too much on this one. The key is to keep it local, not public unless you that's your intent.

6. Access control, part 2: I noticed you're not allowing access from any IPv6 addresses, including localhost. Any specific reason why? I have an IPv6-enabled setup, so I could use it, but does it provide any benefit to actually turn it on for DNS?

IPv6 is good to support. I cannot ensure everyone has enabled it on their host so that's why the default config in this image is IPv4 only (i.e., the Docker daemon doesn't enable IPv6 support by default). I provide example entries for those who want to enable support.

7. auto-trust-anchor-file: "var/root.key": Is this root.key suitable for a server meant never to be a fully self-sustaining DNS server? (That is, I want to be able to resolve any address without relying on something like Cloudflare DNS.)

See https://github.com/MatthewVance/unbound-docker/issues/28#issuecomment-541953720. Also see https://nlnetlabs.nl/documentation/unbound/howto-anchor/. The root.key file provided is from Unbound, it's not anything I provide directly.

8.private-address: What address ranges do I need to include for this, aside from localhost's subnet and the pi-hole network's (172.x.x.x)? My host network (my actual LAN) runs on 10.x.x.x). I'm not using 169.254.x.x or 192.168.x.x for anything, anywhere.

There's no harm including the full RFC1918 space. In fact, I recommend it to protects against DNS Rebinding. Basically, there's no reason for any of your potential private network addresses to be returned in DNS answers.

9. tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt: Is this inside the container? I honestly have no idea where the tls-cert-bundle is on Manjaro Linux (the host OS). If I needed to change it, I'm not sure I'd know how.

Yes. You can exec into to see.

10. use-caps-for-id: yes: Have you run into any issues with this on a Raspberry Pi? One of the tutorials I found had it set to no because it could otherwise cause Pi-specific errors, but that might be due to an old version of ... something.

I haven't seen any issues. I turn it on for security. Technically, Unbound considers it "an experimental implementation of draft dns-0x20." Unbound's default (if the value is not set) is off.

11. PERFORMANCE SETTINGS: I have a 4GB Raspberry Pi 4B, overclocked to 2GHz stable. I'm running Manjaro ARM, a 64-bit OS with a 64-bit userland. Should I modify any of this?

Probably so. When using the provided unbound.conf, those values are generated on the fly with unbound.sh. You can run this image with all the defaults to see what is recommended for your hardware and then set those values manually in your config.

What I shared came from my Pi, an older version than yours.

This is also a good reference: https://nlnetlabs.nl/documentation/unbound/howto-optimise/

12. Finally: Does this create an "authoritative, validating, recursive, caching DNS server? That's what I was hoping to end up with.

That's something you'll have to validate on your own. Dig, drill, tcpdump, etc. should help.

MatthewVance commented 3 years ago

One edit for 12. Unbound is never an authoritative DNS server (unless you count setting a-records for your LAN). Unbound is designed as a recursive server only. For an authoritative server, you need to pair Unbound with something like NSD or BIND.

MatthewVance commented 3 years ago

One more edit for 12, I didn't read your question closely enough at first. I think you're asking if the example config does that. I can answer that. It does not.

Other than the authoritative point I previously noted, my example/default config is not a recursive setup. Instead, it forwards queries to an upstream server over TLS (specified in the forward zone file). This is a tradeoff. Your queries leave your network using DNS over TLS (DoT) with this method, but you have to trust an upstream DNS provider.

A better option might be to run two Unbound servers. One on a cloud provider that supports responding to DNS over TLS queries (you could still restrict access to who can use it) and one locally that forwards queries from your local network to your cloud hosted instance. That way queries leaving your local network are encrypted, but you know the upstream server is appropriately resolving queries.

You could also support DNS over HTTPS on your cloud instance. I haven't test that in Unbound yet, but Unbound 1.12.0 and newer support DoH.

DoH is cool if you run your own server. DoH vs DoT gets interesting. Both have their pros and cons.

johntdavis84 commented 3 years ago

Thanks for taking the time to write such detailed answers. This is super helpful.

  1. logfile: /dev/null: Does this mean it doesn't log anything at all? I think I'm misunderstanding something. What exactly gets tossed into the ether, here?

That's right. No logging at all. Privacy first. Users of this image can re-configure if logging is needed.

I think this is a great way to set it up.

  1. auto-trust-anchor-file: "var/root.key": Is this root.key suitable for a server meant never to be a fully self-sustaining DNS server? (That is, I want to be able to resolve any address without relying on something like Cloudflare DNS.)

See MatthewVance/unbound-docker#28 (comment). Also see https://nlnetlabs.nl/documentation/unbound/howto-anchor/. The root.key file provided is from Unbound, it's not anything I provide directly.

Thanks. I'll take a closer look at these materials to make sure I understand how this part works. I'm trying to set it up so it doesn't depend on any third party DNS server (Cloudflare, Google, etc., for privacy reasons.)

8.private-address: What address ranges do I need to include for this, aside from localhost's subnet and the pi-hole network's (172.x.x.x)? My host network (my actual LAN) runs on 10.x.x.x). I'm not using 169.254.x.x or 192.168.x.x for anything, anywhere.

There's no harm including the full RFC1918 space. In fact, I recommend it to protects against DNS Rebinding. Basically, there's no reason for any of your potential private network addresses to be returned in DNS answers.

Cool. I have uncommented all of these.

  1. use-caps-for-id: yes: Have you run into any issues with this on a Raspberry Pi? One of the tutorials I found had it set to no because it could otherwise cause Pi-specific errors, but that might be due to an old version of ... something.

I haven't seen any issues. I turn it on for security. Technically, Unbound considers it "an experimental implementation of draft dns-0x20." Unbound's default (if the value is not set) is off.

Thanks for the explanation.

  1. PERFORMANCE SETTINGS: I have a 4GB Raspberry Pi 4B, overclocked to 2GHz stable. I'm running Manjaro ARM, a 64-bit OS with a 64-bit userland. Should I modify any of this?

Probably so. When using the provided unbound.conf, those values are generated on the fly with unbound.sh. You can run this image with all the defaults to see what is recommended for your hardware and then set those values manually in your config.

What I shared came from my Pi, an older version than yours.

This is also a good reference: https://nlnetlabs.nl/documentation/unbound/howto-optimise/

Thanks. I'll have to explore this further. I'm still not sure why it bombed out when I set the number of threads the first time around. It's like it didn't recognize the key.

  1. Finally: Does this create an "authoritative, validating, recursive, caching DNS server? That's what I was hoping to end up with.

That's something you'll have to validate on your own. Dig, drill, tcpdump, etc. should help.

Something to explore this week. :) My forward-records file is empty, and it still seems to resolve hostnames, so maybe I have it set up right. 👍

Thanks again!

johntdavis84 commented 3 years ago

For the record, here's what I get when I let unbound autogenerate an unbound.conf file.

$ cat unbound.conf.autogen 
server:
    ###########################################################################
    # BASIC SETTINGS
    ###########################################################################
    # Time to live maximum for RRsets and messages in the cache. If the maximum
    # kicks in, responses to clients still get decrementing TTLs based on the
    # original (larger) values. When the internal TTL expires, the cache item
    # has expired. Can be set lower to force the resolver to query for data
    # often, and not trust (very large) TTL values.
    cache-max-ttl: 86400

    # Time to live minimum for RRsets and messages in the cache. If the minimum
    # kicks in, the data is cached for longer than the domain owner intended,
    # and thus less queries are made to look up the data. Zero makes sure the
    # data in the cache is as the domain owner intended, higher values,
    # especially more than an hour or so, can lead to trouble as the data in
    # the cache does not match up with the actual data any more.
    cache-min-ttl: 300

    # Set the working directory for the program.
    directory: "/opt/unbound/etc/unbound"

    # RFC 6891. 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  1232 which is the DNS Flag Day 2020 recommendation.
    # 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: 1232

    # Listen to for queries from clients and answer from this network interface
    # and port.
    interface: 0.0.0.0@53

    # Rotates RRSet order in response (the pseudo-random number is taken from
    # the query ID, for speed and thread safety).
    rrset-roundrobin: yes

    # Drop user  privileges after  binding the port.
    username: "_unbound"

    ###########################################################################
    # LOGGING
    ###########################################################################

    # Do not print log lines to inform about local zone actions
    log-local-actions: no

    # Do not print one line per query to the log
    log-queries: no

    # Do not print one line per reply to the log
    log-replies: no

    # Do not print log lines that say why queries return SERVFAIL to clients
    log-servfail: no

    # Further limit logging
    logfile: /dev/null

    # Only log errors
    verbosity: 0

    ###########################################################################
    # PRIVACY SETTINGS
    ###########################################################################

    # RFC 8198. Use the DNSSEC NSEC chain to synthesize NXDO-MAIN and other
    # denials, using information from previous NXDO-MAINs answers. In other
    # words, use cached NSEC records to generate negative answers within a
    # range and positive answers from wildcards. This increases performance,
    # decreases latency and resource utilization on both authoritative and
    # recursive servers, and increases privacy. Also, it may help increase
    # resilience to certain DoS attacks in some circumstances.
    aggressive-nsec: yes

    # Extra delay for timeouted UDP ports before they are closed, in msec.
    # This prevents very delayed answer packets from the upstream (recursive)
    # servers from bouncing against closed ports and setting off all sort of
    # close-port counters, with eg. 1500 msec. When timeouts happen you need
    # extra sockets, it checks the ID and remote IP of packets, and unwanted
    # packets are added to the unwanted packet counter.
    delay-close: 10000

    # Prevent the unbound server from forking into the background as a daemon
    do-daemonize: no

    # Add localhost to the do-not-query-address list.
    do-not-query-localhost: no

    # Number  of  bytes size of the aggressive negative cache.
    neg-cache-size: 4M

    # Send minimum amount of information to upstream servers to enhance
    # privacy (best privacy).
    qname-minimisation: yes

    ###########################################################################
    # SECURITY SETTINGS
    ###########################################################################
    # Only give access to recursion clients from LAN IPs
    access-control: 127.0.0.1/32 allow
    access-control: 192.168.0.0/16 allow
    access-control: 172.16.0.0/12 allow
    access-control: 10.0.0.0/8 allow
    # access-control: fc00::/7 allow
    # access-control: ::1/128 allow

    # File with trust anchor for  one  zone, which is tracked with RFC5011
    # probes.
    auto-trust-anchor-file: "var/root.key"

    # Enable chroot (i.e, change apparent root directory for the current
    # running process and its children)
    chroot: "/opt/unbound/etc/unbound"

    # Deny queries of type ANY with an empty response.
    deny-any: yes

    # Harden against algorithm downgrade when multiple algorithms are
    # advertised in the DS record.
    harden-algo-downgrade: yes

    # RFC 8020. returns nxdomain to queries for a name below another name that
    # is already known to be nxdomain.
    harden-below-nxdomain: yes

    # Require DNSSEC data for trust-anchored zones, if such data is absent, the
    # zone becomes bogus. If turned off you run the risk of a downgrade attack
    # that disables security for a zone.
    harden-dnssec-stripped: yes

    # Only trust glue if it is within the servers authority.
    harden-glue: yes

    # Ignore very large queries.
    harden-large-queries: yes

    # Perform additional queries for infrastructure data to harden the referral
    # path. Validates the replies if trust anchors are configured and the zones
    # are signed. This enforces DNSSEC validation on nameserver NS sets and the
    # nameserver addresses that are encountered on the referral path to the
    # answer. Experimental option.
    harden-referral-path: no

    # Ignore very small EDNS buffer sizes from queries.
    harden-short-bufsize: yes

    # Refuse id.server and hostname.bind queries
    hide-identity: yes

    # Refuse version.server and version.bind queries
    hide-version: yes

    # Report this identity rather than the hostname of the server.
    identity: "DNS"

    # These private network addresses are not allowed to be returned for public
    # internet names. Any  occurrence of such addresses are removed from DNS
    # answers. Additionally, the DNSSEC validator may mark the  answers  bogus.
    # This  protects  against DNS  Rebinding
    private-address: 10.0.0.0/8
    private-address: 172.16.0.0/12
    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    # private-address: fd00::/8
    # private-address: fe80::/10
    # private-address: ::ffff:0:0/96

    # Enable ratelimiting of queries (per second) sent to nameserver for
    # performing recursion. More queries are turned away with an error
    # (servfail). This stops recursive floods (e.g., random query names), but
    # not spoofed reflection floods. Cached responses are not rate limited by
    # this setting. Experimental option.
    ratelimit: 1000

    # Use this certificate bundle for authenticating connections made to
    # outside peers (e.g., auth-zone urls, DNS over TLS connections).
    tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt

    # Set the total number of unwanted replies to eep track of in every thread.
    # When it reaches the threshold, a defensive action of clearing the rrset
    # and message caches is taken, hopefully flushing away any poison.
    # Unbound suggests a value of 10 million.
    unwanted-reply-threshold: 10000

    # Use 0x20-encoded random bits in the query to foil spoof attempts. This
    # perturbs the lowercase and uppercase of query names sent to authority
    # servers and checks if the reply still has the correct casing.
    # This feature is an experimental implementation of draft dns-0x20.
    # Experimental option.
    use-caps-for-id: yes

    # Help protect users that rely on this validator for authentication from
    # potentially bad data in the additional section. Instruct the validator to
    # remove data from the additional section of secure messages that are not
    # signed properly. Messages that are insecure, bogus, indeterminate or
    # unchecked are not affected.
    val-clean-additional: yes

    ###########################################################################
    # PERFORMANCE SETTINGS
    ###########################################################################
    # https://nlnetlabs.nl/documentation/unbound/howto-optimise/
    # https://nlnetlabs.nl/news/2019/Feb/05/unbound-1.9.0-released/

    # Number of slabs in the infrastructure cache. Slabs reduce lock contention
    # by threads. Must be set to a power of 2.
    infra-cache-slabs: 4

    # Number of incoming TCP buffers to allocate per thread. Default
    # is 10. If set to 0, or if do-tcp is "no", no  TCP  queries  from
    # clients  are  accepted. For larger installations increasing this
    # value is a good idea.
        incoming-num-tcp: 10

    # Number of slabs in the key cache. Slabs reduce lock contention by
    # threads. Must be set to a power of 2. Setting (close) to the number
    # of cpus is a reasonable guess.
    key-cache-slabs: 4

    # Number  of  bytes  size  of  the  message  cache.
    # Unbound recommendation is to Use roughly twice as much rrset cache memory
    # as you use msg cache memory.
    msg-cache-size: 538606250

    # Number of slabs in the message cache. Slabs reduce lock contention by
    # threads. Must be set to a power of 2. Setting (close) to the number of
    # cpus is a reasonable guess.
    msg-cache-slabs: 4

    # The number of queries that every thread will service simultaneously. If
    # more queries arrive that need servicing, and no queries can be jostled
    # out (see jostle-timeout), then the queries are dropped.
    # This is best set at half the number of the outgoing-range.
    # This Unbound instance was compiled with libevent so it can efficiently
    # use more than 1024 file descriptors.
    num-queries-per-thread: 4096

    # The number of threads to create to serve clients.
    # This is set dynamically at run time to effectively use available CPUs
    # resources
    num-threads: 3

    # Number of ports to open. This number of file descriptors can be opened
    # per thread.
    # This Unbound instance was compiled with libevent so it can efficiently
    # use more than 1024 file descriptors.
    outgoing-range: 8192

    # Number of bytes size of the RRset cache.
    # Use roughly twice as much rrset cache memory as msg cache memory
    rrset-cache-size: 1077212501

    # Number of slabs in the RRset cache. Slabs reduce lock contention by
    # threads. Must be set to a power of 2.
    rrset-cache-slabs: 4

    # Do no insert authority/additional sections into response messages when
    # those sections are not required. This reduces response size
    # significantly, and may avoid TCP fallback for some responses. This may
    # cause a slight speedup.
    minimal-responses: yes

    # # Fetch the DNSKEYs earlier in the validation process, when a DS record
    # is encountered. This lowers the latency of requests at the expense of
    # little more CPU usage.
    prefetch: yes

    # Fetch the DNSKEYs earlier in the validation process, when a DS record is
    # encountered. This lowers the latency of requests at the expense of little
    # more CPU usage.
    prefetch-key: yes

    # Have unbound attempt to serve old responses from cache with a TTL of 0 in
    # the response without waiting for the actual resolution to finish. The
    # actual resolution answer ends up in the cache later on.
    serve-expired: yes

    # Open dedicated listening sockets for incoming queries for each thread and
    # try to set the SO_REUSEPORT socket option on each socket. May distribute
    # incoming queries to threads more evenly.
    so-reuseport: yes

    ###########################################################################
    # LOCAL ZONE
    ###########################################################################

    # Include file for local-data and local-data-ptr
    include: /opt/unbound/etc/unbound/a-records.conf
    include: /opt/unbound/etc/unbound/srv-records.conf

    ###########################################################################
    # FORWARD ZONE
    ###########################################################################

    include: /opt/unbound/etc/unbound/forward-records.conf
johntdavis84 commented 3 years ago

The auto-generated file's biggest (only?) change in performance appeared to be the much larger caches.

Looking at the optimize instructions, I see:

Set *-slabs to a power of 2 close to the num-threads value. Do this for msg-cache-slabs, rrset-cache-slabs, infra-cache-slabs and key-cache-slabs. This reduces lock contention.

I've got 4 cores, and am using that instead of the default setting of 3. 2^2 = 4 slabs, which is as close as one can get. :P Or does it mean I should go for 8 or 16 slabs? I'm using 4 slabs on everything for now.

I also added so-rcvbuf and so-sndbuf at about 4m each (the maximum they will go, presently).

My goal presently is to give the server more resources than it hopefully will ever need on my home network. I've got 3 computers, 3 smartphones, and 2 TVs that TBs of data monthly.

(I will admit it's also fun to see how far I can push the Pi.)

MatthewVance commented 3 years ago

Unbound's documentation is confusing on slabs. Go with what is autogenerated. Here's the logic: https://github.com/MatthewVance/unbound-docker-rpi/blob/30f84ee302397dca10ff430aa195bad6c0bae5d3/1.13.0/unbound.sh#L15

The Unbound conf docs are a bit more clear (take msg-cache-slabs as an example): Must be set to a power of 2. Setting (close) to the number of cpus is a reasonable guess.

In reality, our personal servers aren't going to receive a high enough load for optimization to matter much. It would come into play if we operated a public resolver used by many people. We're not an ISP.

On Mon, Feb 1, 2021, 12:27 AM johntdavis84 notifications@github.com wrote:

Looking at the optimize instructions, I see:

Set *-slabs to a power of 2 close to the num-threads value. Do this for msg-cache-slabs, rrset-cache-slabs, infra-cache-slabs and key-cache-slabs. This reduces lock contention.

I've got 4 cores. 2^2 = 4 slabs, which is as close as one can get. :P Or does it mean I should go for 8 or 16 slabs?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/MatthewVance/unbound-docker-rpi/issues/10#issuecomment-770605362, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAUMHORJ4GCD7RFVGHJYJ6TS4ZCUXANCNFSM4W37KUFA .