getdnsapi / stubby

Stubby is the name given to a mode of using getdns which enables it to act as a local DNS Privacy stub resolver (using DNS-over-TLS).
https://dnsprivacy.org/dns_privacy_daemon_-_stubby/
BSD 3-Clause "New" or "Revised" License
1.19k stars 99 forks source link

stubby seems to automatically question local bind9 #333

Open quippy-git opened 1 year ago

quippy-git commented 1 year ago

I want to use stubby with my local bind9 as a forwarder. However I also use stunnel to provide port 853 with local bind for internal DNS-over-TLS queries. For instance my FireTV does need this to get local addresses resolved (only uses DoT and falls back to google, if non is found locally).

It now seems that stubby identifies the local bind answering queries on 127.0.0.1:853 and sends queries to my local bind installation, which then forwards this query back to stubby, which forwards back to bind - and so on. I get a circular dns query queue that slows down everything.

I was not able to identify a switch to prevent stubby from sending queries to local bind, if it is reachable over 853.

What I need is:

saradickinson commented 1 year ago

Did you solve this problem. Stubby will only forward to whatever resolvers are configured in the stubby configuration file. Are you able to share your config file? Also please double check the stubby logs to ensure it is finding and reading the config file correctly?

quippy-git commented 1 year ago

Not really.

First I have to appollogize, as I did not notice, that the config did not load when started as a Systemd-service. Stubby was running in default config and then delegated everything do localhost:53. With systemd it is loaded as user/group "stubby" and something goes wrong. As root (on command line) everything was fine. (Config is valid...)

However, I found out that I obviously can make Stubby run as a systemd when I comment "dnssec_trust_anchors:". But then it might load and run, but will not return any valid answer. A dig command to stubby will show delegation to let's say 1.1.1.1, but no answer. BTW: The file referenced at "dnssec_trust_anchors:" is valid and there.

I am yet a bit lost here...

saradickinson commented 1 year ago

A quick answer is that this sounds like a permissions issue.... what are the permissions on the dnssec_trust_anchors file e.g. if it was created while stubby was running as root it may be owned by root and user stubby cannot access it.....

quippy-git commented 1 year ago

May bad - it would really be helpful, if stubby would show a bit more information on what is bad in the config. It only shows

Could not configure context with config dict: Generic error
Error parsing config file "/etc/stubby/stubby.yml": Generic error
WARNING: No Stubby config file found... using minimal default config (Opportunistic Usage)

which does not really help in finding the culprit.

In /etc/stubby/stubby.yml the setting dnssec_trust_anchors: "/etc/unbound/root.key" referred to a file with only 640-rights, owner is root:unbound. Changing this to 644 helps, however two things are to mention now:

  1. I would not like to mess around with these file permissions - they might be reset after an update of unbound
  2. Stubby still does not return any request

I started stubby on the console with sudo -u stubby stubby -v7 and get the following output after a dig @localhost -p10053 google.com

[21:46:12.123501] STUBBY: Read config from file /etc/stubby/stubby.yml
[21:46:12.123729] STUBBY: DNSSEC Validation is ON
[21:46:12.123742] STUBBY: Transport list is:
[21:46:12.123752] STUBBY:   - TLS
[21:46:12.123762] STUBBY: Privacy Usage Profile is Strict (Authentication required)
[21:46:12.123775] STUBBY: (NOTE a Strict Profile only applies when TLS is the ONLY transport!!)
[21:46:12.123788] STUBBY: Starting DAEMON....
[21:46:54.692126] STUBBY: 1.1.1.1                                  : Conn opened: TLS - Strict Profile
[21:46:54.721570] STUBBY: 1.1.1.1                                  : Verify passed : TLS
[21:46:54.822706] STUBBY: 1.0.0.1                                  : Conn opened: TLS - Strict Profile
[21:46:54.851782] STUBBY: 1.0.0.1                                  : Verify passed : TLS
[21:47:04.943023] STUBBY: 1.1.1.1                                  : Conn closed: TLS - Resps=     6, Timeouts  =     0, Curr_auth =Success, Keepalive(ms)= 10000
[21:47:04.943088] STUBBY: 1.1.1.1                                  : Upstream   : TLS - Resps=     6, Timeouts  =     0, Best_auth =Success
[21:47:04.943100] STUBBY: 1.1.1.1                                  : Upstream   : TLS - Conns=     1, Conn_fails=     0, Conn_shuts=      0, Backoffs     =     0
[21:47:04.943293] STUBBY: 1.0.0.1                                  : Conn closed: TLS - Resps=     5, Timeouts  =     0, Curr_auth =Success, Keepalive(ms)= 10000
[21:47:04.943308] STUBBY: 1.0.0.1                                  : Upstream   : TLS - Resps=     5, Timeouts  =     0, Best_auth =Success
[21:47:04.943320] STUBBY: 1.0.0.1                                  : Upstream   : TLS - Conns=     1, Conn_fails=     0, Conn_shuts=      0, Backoffs     =     0

Is this because Authentication required but not provided?

Output of dig:

; <<>> DiG 9.16.33 <<>> @localhost -p10053 google.com
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 7348
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;google.com.                    IN      A

;; Query time: 1024 msec
;; SERVER: ::1#10053(::1)
;; WHEN: Tue Jan 10 23:00:59 CET 2023
;; MSG SIZE  rcvd: 28
quippy-git commented 1 year ago

And here is the output of stubby -i

[22:06:25.938861] STUBBY: Read config from file /etc/stubby/stubby.yml
{
  "all_context":
  {
    "add_warning_for_bad_dns": GETDNS_EXTENSION_FALSE,
    "appdata_dir": <bindata of "/var/cache/stubby/">,
    "append_name": GETDNS_APPEND_NAME_TO_SINGLE_LABEL_FIRST,
    "dns_transport_list":
    [
      GETDNS_TRANSPORT_TLS
    ],
    "dnssec": GETDNS_EXTENSION_TRUE,
    "dnssec_allowed_skew": 0,
    "dnssec_return_all_statuses": GETDNS_EXTENSION_FALSE,
    "dnssec_return_full_validation_chain": GETDNS_EXTENSION_FALSE,
    "dnssec_return_only_secure": GETDNS_EXTENSION_FALSE,
    "dnssec_return_status": GETDNS_EXTENSION_FALSE,
    "dnssec_return_validation_chain": GETDNS_EXTENSION_FALSE,
    "dnssec_roadblock_avoidance": GETDNS_EXTENSION_FALSE,
    "edns_client_subnet_private": 1,
    "edns_cookies": GETDNS_EXTENSION_FALSE,
    "edns_do_bit": 0,
    "edns_extended_rcode": 0,
    "edns_version": 0,
    "follow_redirects": GETDNS_REDIRECTS_FOLLOW,
    "hosts": <bindata of "/etc/hosts">,
    "idle_timeout": 10000,
    "limit_outstanding_queries": 0,
    "max_backoff_value": 1000,
    "namespaces":
    [
      GETDNS_NAMESPACE_LOCALNAMES,
      GETDNS_NAMESPACE_DNS
    ],
    "resolution_type": GETDNS_RESOLUTION_STUB,
    "resolvconf": <bindata of "/etc/resolv.conf">,
    "return_both_v4_and_v6": GETDNS_EXTENSION_FALSE,
    "return_call_reporting": GETDNS_EXTENSION_FALSE,
    "round_robin_upstreams": 1,
    "specify_class": 1,
    "suffix":
    [
       <bindata of "******************.int.">,
       <bindata of "******************.int.">,
    ],
    "timeout": 5000,
    "tls_authentication": GETDNS_AUTHENTICATION_REQUIRED,
    "tls_backoff_time": 3600,
    "tls_cipher_list": <bindata of "EECDH+AESGCM:EECDH+CHACHA20">,
    "tls_ciphersuites": <bindata of "TLS_AES_256_GCM_SHA384:TLS_AES_1"...>,
    "tls_connection_retries": 2,
    "tls_min_version": GETDNS_TLS1_2,
    "tls_query_padding_blocksize": 128,
    "trust_anchors_backoff_time": 2500,
    "trust_anchors_url": <bindata of "http://data.iana.org/root-anchor"...>,
    "trust_anchors_verify_CA": <bindata of 0x2d2d2d2d2d424547494e204345525449...>,
    "trust_anchors_verify_email": <bindata of "dnssec@iana.org">,
    "upstream_recursive_servers":
    [
      {
        "address_data": <bindata for 1.1.1.1>,
        "address_type": <bindata of "IPv4">,
        "tls_auth_name": <bindata of "cloudflare-dns.com">
      },
      {
        "address_data": <bindata for 1.0.0.1>,
        "address_type": <bindata of "IPv4">,
        "tls_auth_name": <bindata of "cloudflare-dns.com">
      }
    ]
  },
  "api_version_number": 132058112,
  "api_version_string": <bindata of "December 2015">,
  "compilation_comment": <bindata of "getdns 1.5.2 configured on 2022-"...>,
  "default_hosts_location": <bindata of "/etc/hosts">,
  "default_resolvconf_location": <bindata of "/etc/resolv.conf">,
  "default_trust_anchor_location": <bindata of "/var/lib/unbound/root.anchor">,
  "implementation_string": <bindata of "https://getdnsapi.net">,
  "listen_addresses":
  [
    {
      "address_data": <bindata for 127.0.0.1>,
      "address_type": <bindata of "IPv4">,
      "port": 10053
    },
    {
      "address_data": <bindata for ::1>,
      "address_type": <bindata of "IPv6">,
      "port": 10053
    }
  ],
  "openssl_build_version_number": 269488335,
  "openssl_built_on": <bindata of 0x>,
  "openssl_cflags": <bindata of "compiler: gcc -fPIC -pthread -m6"...>,
  "openssl_dir": <bindata of "OPENSSLDIR: "/etc/ssl"">,
  "openssl_engines_dir": <bindata of "ENGINESDIR: "/usr/lib64/engines-"...>,
  "openssl_platform": <bindata of "platform: linux-x86_64">,
  "openssl_version_number": 269488335,
  "openssl_version_string": <bindata of "OpenSSL 1.1.1l  24 Aug 2021 SUSE"...>,
  "resolution_type": GETDNS_RESOLUTION_STUB,
  "version_number": 17105408,
  "version_string": <bindata of "1.5.2">
}
Result: Config file syntax is valid.
quippy-git commented 1 year ago

OK, I solved it. Did not see through this...

Again, it was the appdata_dir, which points to /var/cache/stubby, which is a link to /var/cache/private/stubby The link itself belongs to root:root - that is OK. The private-Dir however was also created by root:root with 600 - the stubby below private then again correctly with stubby:stubby, 644 This construct was created by stubby itself.

Running stubby on console as user stubby will not work now, as that directory is not writable in that case. However I deleted that construct and when restarting stubby as systemd with DynamicUser enabled, it is now working (only with systemd!)

One question stays: do I need dnssec_trust_anchors: point to anything in stubby.yml - and what is, if I do not? Currently is commented out.