dnscrypt-proxy icon indicating copy to clipboard operation
dnscrypt-proxy copied to clipboard

Bind9 named server interaction with block_ipv6 activated resulting in SERVFAIL queries

Open Daryes opened this issue 1 year ago • 5 comments

It is probably the same as the reddit discussion with blacklist

Output of the following commands:

# /usr/local/bin/dnscrypt-proxy --config /etc/dnscrypt-proxy/dnscrypt-proxy.toml -version
2.1.4

# /usr/local/bin/dnscrypt-proxy --config /etc/dnscrypt-proxy/dnscrypt-proxy.toml -check
[2024-10-26 20:14:58] [NOTICE] dnscrypt-proxy 2.1.4
[2024-10-26 20:14:58] [NOTICE] Configuration successfully checked

# /usr/local/bin/dnscrypt-proxy --config /etc/dnscrypt-proxy/dnscrypt-proxy.toml -resolve example.com
Resolving [example.com] using 127.0.2.1 port 53

Resolver      : **sensitive**

Canonical name: example.com.

IPv4 addresses: 93.184.215.14
IPv6 addresses: -

Name servers  : b.iana-servers.net., a.iana-servers.net.
DNSSEC signed : yes
Mail servers  : 1 mail servers found

HTTPS alias   : -
HTTPS info    : -

Host info     : -
TXT records   : wgyf8z8cgvm2qmxpnbnldrcltvk4xqfn, v=spf1 -all

What is affected by this bug?

All IPv6 queries or explicit IPv4+v6 dns record queries are ending in SERVFAIL

When does this occur?

Always, when block_ipv6=true is set in dnscrypt-proxy configuration with a Bind9 dns server in front, dnscrypt-proxy being used as a forwarder.

How do we replicate the issue?

I'm currently having a Bind9 dns servers for the internal network, forwarding external queries to a dnscrypt-proxy server. IPv6 is not used on the network, thus having it blocked by dnscrypt-proxy. This usually is working well, but it seems there are more and more applications explicitly querying for both A and AAAA records.

That's when I found that such queries were returned with the SERVFAIL status when coming from dnscrypt-proxy through bind9.

When investigating, I found the following when querying for a AAAA record :

  1. If block_ipv6 = true, querying directly dnscrypt-proxy the status is NOERROR.
  2. If block_ipv6 is set to false, querying through bind9 give an answser with the status NOERROR .
  3. with another dns server (Windows), chained through bind9, it returns a correct NOERROR status for a AAAA query on an non-existing AAAA record, but a A record (the server does not contains a single IPv6 record)

It seems the generated HINT answer from dnscrypt-proxy when blocking ipv6 records is accepted by most clients, but not bind.

When block_ipv6 is active, using "dig" with a direct query to dnscryp-proxy, and one to the windows server, it appeared there's a difference in the answer flags :

  • Windows dns : Flags: qr aa rd ra; QUERY: 1; ANSWER: 0; AUTHORITY: 1; ADDITIONAL: 0
  • dnscrypt-proxy : Flags: qr ra; QUERY: 1; ANSWER: 1; AUTHORITY: 1; ADDITIONAL: 0

dnscrypt-proxy is missing these flags in its response : aa (authoritative) and rd (recursion desired) in the HINT generated answer.

So I did some packet capture to confirm this and decode the header content with wireshark : Windows DNS answer header

Flags: 0x8580 (Standard query response, No error)
1... .... .... .... = Response: Message is a response
.000 0... .... .... = Opcode: Standard query (0)
.... .1.. .... .... = Authoritative: Server is an authority for domain
.... ..0. .... .... = Truncated: Message is not truncated
.... ...1 .... .... = Recursion desired: Do query recursively
.... .... 1... .... = Recursion available: Server can do recursive queries
.... .... .0.. .... = Z: reserved (0)
.... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
.... .... ...0 .... = Non-authenticated data: Unacceptable
.... .... .... 0000 = Reply code: No error (0)
Questions: 1
Answer RRs: 0
Authority RRs: 1
Additional RRs: 0

dnscrypt-proxy answer header

Flags: 0x8080 (Standard query response, No error)
1... .... .... .... = Response: Message is a response
.000 0... .... .... = Opcode: Standard query (0)
.... .0.. .... .... = Authoritative: Server is not an authority for domain
.... ..0. .... .... = Truncated: Message is not truncated
.... ...0 .... .... = Recursion desired: Don't do query recursively
.... .... 1... .... = Recursion available: Server can do recursive queries
.... .... .0.. .... = Z: reserved (0)
.... .... ..0. .... = Answer authenticated: Answer/authority portion was not authenticated by the server
.... .... ...0 .... = Non-authenticated data: Unacceptable
.... .... .... 0000 = Reply code: No error (0)
Questions: 1
Answer RRs: 1
Authority RRs: 1
Additional RRs: 0

Both flags are indeed missing from dnscrypt-proxy answer

Expected behavior (i.e. solution)

I suspect that as Bind9 has only dnscrypt-proxy as the only forwarder, it will force the status to failed because the AAAA answer is absent, no recursion was done and the server is not authoritative. And I didn't find in the RFC what is the correct behavior here, if there's one.

But I'm not seeing how to alter the dns.HINFO construct in the block_ipv6 plugin of dnscrypt-proxy, to add the "authoritative" and "Recursion desired" flags to check if Bind9 is happy with these.

That's the last part I am looking for, I can run a test build if required.

Daryes avatar Oct 26 '24 19:10 Daryes