AdguardTeam / dnsproxy

Simple DNS proxy with DoH, DoT, DoQ and DNSCrypt support
Apache License 2.0
2.37k stars 246 forks source link

edns-addr breaks caching #329

Closed timkgh closed 1 year ago

timkgh commented 1 year ago

dnsproxy v0.49.1 with the following configuration:

cache: true
cache-size: 4194304
cache-min-ttl: 300
cache-max-ttl: 86400
cache-optimistic: false
edns: true
edns-addr: "x.x.x.0"

where x.x.x.0 is an IP at my ISP

The caching doesn't seem to work. If I keep querying for google.com using dig, each query is slow (20ms) and the returned TTL is always 300 instead of decreasing for each query. This makes me think each query goes to the upstream instead of being served from the local cache.

If I disable edns-addr then queries are fast (0ms as reported by dig) and the returned TTL decreases with each query as expected.

Mizzick commented 1 year ago

Hello!

I've tested it with the following config:

bootstrap:
  - "8.8.8.8:53"
listen-addrs:
  - "127.0.0.1"
listen-ports:
  - 5353
max-go-routines: 0
ratelimit: 0
udp-buf-size: 0
upstream:
  - "8.8.8.8:53"
cache: true
cache-size: 4194304
cache-min-ttl: 300
cache-max-ttl: 86400
cache-optimistic: false
edns: true
edns-addr: [MY_ADDR]

Run proxy with verbose:

./dnsproxy -v --config-path=config.yaml

When made some test requests:

dig IN A 'google.com' @127.0.0.1 -p 5353

As I see the TTL is decreasing and the response is served from cache, I see this in the logs:

2023/05/11 13:20:58 6159#19 [debug] dnsproxy: cache: serving response from subnet cache
dig IN A 'google.com' @127.0.0.1 -p 5353

; <<>> DiG 9.10.6 <<>> IN A google.com @127.0.0.1 -p 5353
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59808
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com.            IN  A

;; ANSWER SECTION:
google.com.     269 IN  A   64.233.161.113
google.com.     269 IN  A   64.233.161.102
google.com.     269 IN  A   64.233.161.138
google.com.     269 IN  A   64.233.161.100
google.com.     269 IN  A   64.233.161.101
google.com.     269 IN  A   64.233.161.139

;; Query time: 0 msec
;; SERVER: 127.0.0.1#5353(127.0.0.1)
;; WHEN: Thu May 11 13:28:17 +03 2023
;; MSG SIZE  rcvd: 135
Mizzick commented 1 year ago

@timkgh It would be helpful if you provide more details of your case?

timkgh commented 1 year ago

I tested some more and here's what I discovered using edns-addr: "66.60.200.0"

2023/05/11 07:08:37 3436332#69 [debug] dnsproxy: setting ecs: 66.60.200.0/24
...
2023/05/11 07:08:37 3436332#69 [debug] dnsproxy: cache: ecs option in response: 66.60.192.0/19

And it's never served from the cache I'm guessing because of the ecs subnet difference in the request and response.

If I use a random edns-addr: "1.2.3.0" then it works, it is served from the cache because the ecs in request and response match.

It appears that the dnsproxy cache matching needs to be done based on a wider subnet match not on an exact /24 match. Or use the edns-addr value as the cache key.

I cannot set a wider ecs subnet because of bug #178

Mizzick commented 1 year ago

@timkgh thanks for your reply! Indeed I have figured that out yesterday as well, the fix is coming shortly.

EugeneOne1 commented 1 year ago

@timkgh, sorry for the late response. We've actually merged the fix within 936bd45decb66694932ce39dd7c2f9313c3c52d7. Could you please check if the cache now works as it should? Also, we're going to release this fix today, so you may also wait for the patch update v0.49.2.

timkgh commented 1 year ago

Seems to work, thanks for the fix.