dnscrypt-proxy
dnscrypt-proxy copied to clipboard
Bind9 named server interaction with block_ipv6 activated resulting in SERVFAIL queries
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 :
- If block_ipv6 = true, querying directly dnscrypt-proxy the status is NOERROR.
- If block_ipv6 is set to false, querying through bind9 give an answser with the status NOERROR .
- 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.