DNS-OVER-TLS with UNBOUND GETDNS and STUBBY, help needed

Hello,
I am working on this Instruction, which has also a few threads in this forum, the author is @directnupe. Unfortunately, all uci commands given in this tutorial result in a "Parse Error". After a couple of attempts to identify the cause for the error I felt it is getting too dangerous to mess around with configurations without knowing which ones are affected.

Then, there are some additional things that did not work in my hands. I have put together the Howto into a small list and refer to it when talking about the issues I experienced. 'My WORKING CONFIG' stands for directnupe's configs:

  1. opkg install unbound odhcpd unbound-control unbound-control-setup luci-app-unbound unbound-anchor getdns stubby
  2. My WORKING CONFIG (adapt for your CPU/MEM) /etc/unbound/unbound_srv.conf
  3. uci set ‘unbound.@unbound[0].query_minimize=1’
  4. modify etc/config/stubby and set option manual '1'
  5. My WORKING CONFIG /etc/stubby/stubby.yml
  6. install drill, run drill txt qnamemintest.internet.nl
  7. MY WORKING CONFIG /etc/unbound/unbound_ext.conf
  8. uci set ‘dhcp.@dnsmasq[0].port=53535’ ; uci add_list “dhcp.lan.dhcp_option=option:dns-server,$(uci get network.lan.ipaddr)”; uci set ‘unbound.@unbound[0].dhcp_link=dnsmasq’
  9. uci commit; /etc/init.d/unbound restart
  10. modify /etc/config/dhcp: list server '127.0.0.1#5453'; option noresolv ‘1’
  11. reboot
  12. logread |grep 'using nameserver' -->127.0.0.1#5453
  13. replace DNS servers by ISP with 127.0.0.1, along with Tenta nameservers 99.192.182.200 and 99.192.182.100
  14. My WORKING CONFIG /etc/config/unbound
  15. /etc/init.d/unbound restart

No. 3. gave a Parse Error
No. 6 returned "NO - QNAME minimisation is NOT enabled on your resolver"
No. 8 none of the commands worked. In particular the second one (...option:dns-server,$(uci get network.lan.ipaddr)), how does it look in a plain text file?
I stopped here, because it does not make sense to continue.

My OpenWRT version is 18.06.3.

Apologies if essential information is missing for good answers, I am familiar with command line and Linux, but no expert in this field.

Cheers
Oscar

Dear Oscar,
Hello and I hope that you are well. I do not know why you are getting parse errors- frankly, I have never heard of this. Perhaps you should try entering each uci command individually instead of using the colons and combining commands. Next get rid of the Tenta DNS SERVERS on the WAN Interface - only use the localhost ( 127.0.0.1 ) for DNS on WAN.
You also - did not mention how you edited the /etc/config/unbound file which is important - here is an example here:

 9 - Working /etc/config/unbound file
nano /etc/config/unbound  
 
config unbound
        option add_extra_dns '0'
        option add_local_fqdn '1'
        option add_wan_fqdn '0'
        option dhcp4_slaac6 '0'
        option dns64 '0'
        option dns64_prefix '64:ff9b::/96'
        option domain "your.domain" ## put your domain here
        option domain_type 'static'
        option edns_size '1280'
        option extended_stats '1'
        option hide_binddata '1'
        option extended_luci '1'
        option luci_expanded '1'
        option listen_port '53'
        option localservice '1'
        option manual_conf '0'
        option protocol 'ip4_only'
        option query_min_strict '1'
        option rebind_localhost '0'
        option rebind_protection '1'
        option recursion 'default'
        option resource 'medium'
        option root_age '28'
        option ttl_min '120'
        option unbound_control '2'
        option validator '1'
        option validator_ntp '1'
        option verbosity '2'
        list trigger_interface 'lan'
        list trigger_interface 'wan'
        option query_minimize '1'
        option dhcp_link 'dnsmasq' 

Here is an excellent /etc/stubby/stubby.yml file which will help with QNAME minimisation

# Note: by default on OpenWRT stubby configuration is handled via
# the UCI system and the file /etc/config/stubby. If you want to
# use this file to configure stubby, then set "option manual '1'"
# in /etc/config/stubby.
resolution_type: GETDNS_RESOLUTION_STUB
round_robin_upstreams: 1
appdata_dir: "/var/lib/stubby"
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
edns_client_subnet_private: 1
idle_timeout: 60000
listen_addresses:
  - 127.0.0.1@5453
  - 0::1@5453
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_connection_retries: 5
tls_backoff_time: 900
timeout: 2000
tls_ca_path: "/etc/ssl/certs/"
upstream_recursive_servers:
# IPV4 Servers
### DNS Privacy Test Servers ###
#The DNS Warden DNS TLS Primary Server          uncensored-dot.dnswarden.com
  - address_data: 116.203.70.156
    tls_auth_name: "uncensored-dot.dnswarden.com"
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: aPns02lcGrDxnJQcRSHN8Cfx0XG+IXwqy5ishTQtzR0=
#The DNS Warden DNS TLS Secondary Server           adblock-dot.dnswarden.com
  - address_data: 116.203.35.255
    tls_auth_name: "uncensored-dot.dnswarden.com"
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: aPns02lcGrDxnJQcRSHN8Cfx0XG+IXwqy5ishTQtzR0=
### Test servers ###
#The BlahDNS German DNS TLS Server
  - address_data: 159.69.198.101
    tls_auth_name: "dot-de.blahdns.com"
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: RzMGlPVE8DlsiA9DQRuW9CoVkwFBjS8j+we5PZ3eE0c=
#The BlahDNS Japan DNS TLS Server
  - address_data: 108.61.201.119
    tls_auth_name: "dot-jp.blahdns.com"
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: 427fIEGdHRXL9C6i+PzEk+CstsrmNGXJaAnu9ECu+Hk=
## The Surfnet/Sinodun DNS TLS Server
  - address_data: 145.100.185.18
    tls_port: 853
    tls_auth_name: "dnsovertls3.sinodun.com"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: 5SpFz7JEPzF71hditH1v2dBhSErPUMcLPJx1uk2svT8=
# The securedns.eu DNS TLS Server  dot.securedns.eu   ads-dot.securedns.eu
  - address_data: 146.185.167.43
    tls_auth_name: "dot.securedns.eu"
    tls_port: 853
    tls_pubkey_pinset:
      - digest: "sha256"
        value: h3mufC43MEqRD6uE4lz6gAgULZ5/riqH/E+U+jE3H8g=
#The dns.seby.io - Vultr DNS TLS Server
  - address_data: 139.99.222.72
    tls_auth_name: "dot.seby.io"
    tls_port: 853
    tls_pubkey_pinset:
      - digest: "sha256"
        value: 8A/1KQQiN+aFWenQon076nAINhlZjGkB15C4E/qogGw=
#The Primary appliedprivacy.net DNS TLS Server
  - address_data: 37.252.185.232
    tls_auth_name: "dot1.appliedprivacy.net"
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: TvTo5uauOH66/Vnxl2QHwBhN9xdU0Zp1Jeqi+byC1p4=
#The Secure DNS Project by PumpleX DNS TLS Server
  - address_data: 51.38.83.141
    tls_auth_name: "dns.oszx.co"
    tls_port: 853
    tls_pubkey_pinset:
      - digest: "sha256"
        value: yevnTQfRqEOU1W8rUBABZRgToMgAwRn0eH7zJeBcq0s=
#The ibksturm DNS TLS Server
  - address_data: 178.82.102.190
    tls_auth_name: "ibksturm.synology.me"
    tls_port: 853
    tls_pubkey_pinset:
      - digest: "sha256"
        value: TjpalBJr0Ir27Dr59lXky4PXN0yTAoW92ddF8lBxYBQ=

and here is an example for /etc/unbound/unbound_srv.conf I run a WRT32x or WRT3200ACM with usb exroot :

cat >> /etc/unbound/unbound_srv.conf <<UNBOUND_SERVER_CONF
server:
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
# use all CPUs
num-threads: 2

# power of 2 close to num-threads
msg-cache-slabs: 4
rrset-cache-slabs: 4
infra-cache-slabs: 4
key-cache-slabs: 4

# more cache memory, rrset=msg*2
rrset-cache-size: 200m
msg-cache-size: 100m

# more outgoing connections
# depends on number of cores: 1024/cores - 50
outgoing-range: 8192

# Larger socket buffer.  OS may need config.
so-rcvbuf: 4m
so-sndbuf: 4m

cache-min-ttl: 3600
cache-max-ttl: 86400
hide-identity: yes
hide-version: yes
hide-trustanchor: yes
harden-glue: yes
harden-dnssec-stripped: yes
infra-cache-numhosts: 100000
num-queries-per-thread: 4096
max-udp-size: 3072
minimal-responses: yes
rrset-roundrobin: yes
use-caps-for-id: no
do-ip6: no
do-ip4: yes
do-tcp: yes
do-udp: yes
prefetch: yes
prefetch-key: yes
qname-minimisation: yes
qname-minimisation-strict: yes
harden-below-nxdomain: yes
aggressive-nsec: yes
so-reuseport: yes
unwanted-reply-threshold: 10000000
interface-automatic: yes
verbosity: 1
private-domain: "your-domain.here"
do-not-query-localhost: no
harden-referral-path: yes
target-fetch-policy: "0 0 0 0 0"
val-clean-additional: yes
ip-ratelimit: 300
ip-ratelimit-factor: 10
incoming-num-tcp: 100
edns-buffer-size: 1472
UNBOUND_SERVER_CONF

Hope this helps - Peace and I am OUT

Dear Oscar,
Oh yeah ! A light bulb just went off in my head. I run Davidc502 Builds - see here : https://dc502wrt.org/ and when Dave first bumped up to Linux Kernel 4.19 I encountered the same type of issue which you are talking about. The issue went away when he compiled his first non-test standard 4.19 Build. The workaround that I found after much trial and error was to limit the number of DNS RESOLVERS in the /etc/stubby/stubby.yml file to five or less. For example try this :slight_smile:

# Note: by default on OpenWRT stubby configuration is handled via
# the UCI system and the file /etc/config/stubby. If you want to
# use this file to configure stubby, then set "option manual '1'"
# in /etc/config/stubby.
resolution_type: GETDNS_RESOLUTION_STUB
round_robin_upstreams: 1
appdata_dir: "/var/lib/stubby"
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
edns_client_subnet_private: 1
idle_timeout: 60000
listen_addresses:
  - 127.0.0.1@5453
  - 0::1@5453
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_connection_retries: 5
tls_backoff_time: 900
timeout: 2000
tls_ca_path: "/etc/ssl/certs/"
upstream_recursive_servers:
### Test servers ###
#The BlahDNS German DNS TLS Server
  - address_data: 159.69.198.101
    tls_auth_name: "dot-de.blahdns.com"
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: RzMGlPVE8DlsiA9DQRuW9CoVkwFBjS8j+we5PZ3eE0c=
#The BlahDNS Japan DNS TLS Server
  - address_data: 108.61.201.119
    tls_auth_name: "dot-jp.blahdns.com"
    tls_port: 443
    tls_pubkey_pinset:
      - digest: "sha256"
        value: 427fIEGdHRXL9C6i+PzEk+CstsrmNGXJaAnu9ECu+Hk=
## The Surfnet/Sinodun DNS TLS Server
  - address_data: 145.100.185.18
    tls_port: 853
    tls_auth_name: "dnsovertls3.sinodun.com"
    tls_pubkey_pinset:
      - digest: "sha256"
        value: 5SpFz7JEPzF71hditH1v2dBhSErPUMcLPJx1uk2svT8=
# The securedns.eu DNS TLS Server  dot.securedns.eu   ads-dot.securedns.eu
  - address_data: 146.185.167.43
    tls_auth_name: "dot.securedns.eu"
    tls_port: 853
    tls_pubkey_pinset:
      - digest: "sha256"
        value: h3mufC43MEqRD6uE4lz6gAgULZ5/riqH/E+U+jE3H8g=
#The dns.seby.io - Vultr DNS TLS Server
  - address_data: 139.99.222.72
    tls_auth_name: "dot.seby.io"
    tls_port: 853
    tls_pubkey_pinset:
      - digest: "sha256"
        value: 8A/1KQQiN+aFWenQon076nAINhlZjGkB15C4E/qogGw=

This worked for me - and even if you use the default /etc/config/stubby you still must use five ( 5 ) resolvers or less in the configuration. I may try to contact David Mora aka iamperson347 the developer and maintainer of GETDNS and STUBBY package for OpenWRT about this - however; as I said the problem went away - on Dave's first non experimental 4.19 Build. Hope this works.

Hello @directnupe ,
I really appreciate your support in this matter. However, I now found out that at least in my hands, the instructions in the on the uci commands contain syntax errors. An example:

uci set ‘dhcp.@dnsmasq[0].port=53535’
uci: Parse error

setting the quotes a little bit differently works

**uci set dhcp.@dnsmasq[0].port='53535’
uci commit
cat /etc/config/dhcp |grep port
option port '53535'

While I could help myself with this line I am totally stuck with the other:

uci add_list “dhcp.lan.dhcp_option=option:dns-server,$(uci get network.lan.ipaddr)”

What I understand is that the modification is on the /etc/config/dhcp file, section lan (config dhcp 'lan'). But, no matter what I try I can't find what exactly needs to be entered. May I ask you to provide the part of your dhcp file where the a.m. modification is in plain text? I would not ask if I had not spent a couple of hours on this matter already.

Can't wait to get this up and running...

Cheers
Oscar

Dear Oscar,
Hello - the original Bog Post is here : https://blog.grobox.de/2018/what-is-dns-privacy-and-how-to-set-it-up-for-openwrt/
I modified for GETDNS and STUBBY as I point out in the tutorial
Original Commands here:

# Move dnsmasq to port 53535 where it will still serve local DNS from DHCP
# Network -> DHCP & DNS -> Advanced Settings -> DNS server port to 53535
uci set 'dhcp.@dnsmasq[0].port=53535'

# Configure dnsmasq to send a DNS Server DHCP option with its LAN IP
# since it does not do this by default when port is configured.
uci add_list "dhcp.lan.dhcp_option=option:dns-server,$(uci get network.lan.ipaddr)"
uci set 'unbound.@unbound[0].dhcp_link=dnsmasq'

# Save & Apply (will restart dnsmasq, DNS unreachable until unbound is up)
uci commit

# Restart (or start) unbound (System -> Startup -> unbound -> Restart)
/etc/init.d/unbound restart

Never had a problem - Here is OpenWRT page : https://github.com/openwrt/packages/blob/master/net/stubby/files/README.md
Only command line problem I had was with - :

uci dhcp.@dnsmasq[-1].noresolv=1

It would not work correctly so I found and use this:

uci set dhcp.@dnsmasq[-1].noresolv=1

Other than that no issues - I run Davidc502 Builds found here: https://dc502wrt.org/ As for /etc/config/dhcp -you can enter all the options manually - I think whatever OpenWRT Build you are using may be quirky or you need to do a fresh install
Peace

Perhaps it's a keyboard layout issue in your side. If you look closely, your not using proper single quotes.

You have:

Notice the ' vs ’ two very different characters. All your examples seem to be slightly off.