Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocky seems to keep query upstream domain via bootstrap DNS even after bootstrapped #454

Closed
PeterDaveHello opened this issue Mar 14, 2022 · 17 comments
Labels
🔨 enhancement New feature or request
Milestone

Comments

@PeterDaveHello
Copy link
Contributor

As title, I've noticed that Blocky seems to keep query upstream domain via bootstrap DNS even after bootstrapped, and it's frequently, not sure if it's expected? Thinking about maybe once the query to encrypted DNS upstream is established, should use the encrypted DNS to look up the upstream's IP addresses?

Here's the partial of the timestamp records that I observed the query to of upstream encrypted DNS's domain name. I use only single one upstream in this case, and its TTL of the upstream domain is 300 secs, it looks like the query is much more frequent than the TTL.

15:46:31
15:46:33
15:46:34
15:46:34
15:46:35
15:46:36
15:46:36
15:46:37
15:46:38
15:47:36
15:48:27
15:48:42
15:48:45
15:48:47
15:49:37
15:49:54
15:50:39
15:50:49
15:50:51
15:50:52
15:50:54
15:51:37
15:51:38
15:52:09
15:52:18
15:52:19
15:52:20
15:52:21
15:52:22
15:52:23
15:52:24
15:52:25
15:53:07
15:53:18
15:53:42
15:53:43
15:53:44
15:53:45
15:53:58
15:54:00
15:54:02
15:54:02
15:54:08
15:54:25
15:54:29
15:54:50
15:55:36
15:55:52
15:55:55
15:56:22
15:57:23
15:57:36
15:57:40
15:57:40
15:57:41
@0xERR0R
Copy link
Owner

0xERR0R commented Mar 17, 2022

Did I understand it correct: you have one upstream server (defined as hostname and not as IP). Bootstrap DNS is also defined. You can observe multiple queries on bootstrap DNS server with upstream's hostname.

@PeterDaveHello
Copy link
Contributor Author

PeterDaveHello commented Mar 18, 2022

@0xERR0R yes! You're right! The queries keep going after the upstream's ready and resolving queries.

@0xERR0R
Copy link
Owner

0xERR0R commented Mar 18, 2022

I can't reproduce it. I started one blocky instance as docker container and a local instance, which uses docker container as bootstrapDNS. I configured only 1 upstream resolver as DoH. I see only 2 requests with resolver's address. No further requests if i run DNS queries.

@PeterDaveHello
Copy link
Contributor Author

I'll see how I can package a reproducible environment in Dockerfile that can be used for debug. Thanks.

@PeterDaveHello
Copy link
Contributor Author

@0xERR0R

I can reproduce the issue with blocky v0.18(Build time: 20220223-205646) on Ubuntu 20.04, and maybe my original report wasn't accurate, here's the config used to produce the issue, the log, and the result that I found:

Two blocky process will be setup to reprodice this issue, one will be act like the bootstrap server for the other one, one will act like normal local blocky resolver:

config-bootstrap.yml:

upstream:
  default:
    - tcp-tls:dns.google
port: ":8053"

config-normal.yml:

upstream:
  default:
    - tcp-tls:dns.google
port: ":8054"
bootstrapDns: udp:127.0.0.1:8053

Once they're running, I'll send some DNS requests to the normal one listen on port 8054.

This is the log of the bootstrap DNS:

[2022-03-19 23:23:01]  INFO server: UDP server is up and running on address :8053
[2022-03-19 23:23:01]  INFO server: TCP server is up and running on address :8053
[2022-03-19 23:23:14]  INFO queryLog: query resolved answer=A (8.8.8.8), A (8.8.4.4) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=33 question=A (dns.google.) response_code=NOERROR response_reason=RESOLVED (dns.google:853)
[2022-03-19 23:23:14]  INFO queryLog: query resolved answer=AAAA (2001:4860:4860::8888), AAAA (2001:4860:4860::8844) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=33 question=AAAA (dns.google.) response_code=NOERROR response_reason=RESOLVED (dns.google:853)
[2022-03-19 23:23:14]  INFO queryLog: query resolved answer=A (8.8.8.8), A (8.8.4.4) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=A (dns.google.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:14]  INFO queryLog: query resolved answer=AAAA (2001:4860:4860::8888), AAAA (2001:4860:4860::8844) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=AAAA (dns.google.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:25]  INFO queryLog: query resolved answer=AAAA (2001:4860:4860::8888), AAAA (2001:4860:4860::8844) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=AAAA (dns.google.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:25]  INFO queryLog: query resolved answer=A (8.8.8.8), A (8.8.4.4) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=A (dns.google.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:30]  INFO queryLog: query resolved answer=AAAA (2001:4860:4860::8888), AAAA (2001:4860:4860::8844) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=AAAA (dns.google.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:30]  INFO queryLog: query resolved answer=A (8.8.8.8), A (8.8.4.4) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=A (dns.google.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:30]  INFO queryLog: query resolved answer=AAAA (2001:4860:4860::8888), AAAA (2001:4860:4860::8844) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=AAAA (dns.google.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:30]  INFO queryLog: query resolved answer=A (8.8.8.8), A (8.8.4.4) client_ip=127.0.0.1 client_names=127.0.0.1 duration_ms=0 question=A (dns.google.) response_code=NOERROR response_reason=CACHED

This is the log of the normal local blocky DNS:

[2022-03-19 23:23:02]  INFO server: UDP server is up and running on address :8054
[2022-03-19 23:23:02]  INFO server: TCP server is up and running on address :8054
[2022-03-19 23:23:14]  INFO queryLog: query resolved answer=A (188.166.199.140) client_ip=::1 client_names=::1 duration_ms=545 question=A (ipinfo.tw.) response_code=NOERROR response_reason=RESOLVED (dns.google:853)
[2022-03-19 23:23:14]  INFO queryLog: query resolved answer=AAAA (2400:6180:0:d1::4fc:4001) client_ip=::1 client_names=::1 duration_ms=217 question=AAAA (ipinfo.tw.) response_code=NOERROR response_reason=RESOLVED (dns.google:853)
[2022-03-19 23:23:19]  INFO queryLog: query resolved answer=A (188.166.199.140) client_ip=::1 client_names=::1 duration_ms=0 question=A (ipinfo.tw.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:19]  INFO queryLog: query resolved answer=AAAA (2400:6180:0:d1::4fc:4001) client_ip=::1 client_names=::1 duration_ms=0 question=AAAA (ipinfo.tw.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:22]  INFO queryLog: query resolved answer=A (188.166.199.140) client_ip=::1 client_names=::1 duration_ms=0 question=A (ipinfo.tw.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:22]  INFO queryLog: query resolved answer=AAAA (2400:6180:0:d1::4fc:4001) client_ip=::1 client_names=::1 duration_ms=0 question=AAAA (ipinfo.tw.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:25]  INFO queryLog: query resolved answer=CNAME (ipinfo.tw.), A (188.166.199.140) client_ip=::1 client_names=::1 duration_ms=96 question=A (www.ipinfo.tw.) response_code=NOERROR response_reason=RESOLVED (dns.google:853)
[2022-03-19 23:23:25]  INFO queryLog: query resolved answer=AAAA (2400:6180:0:d1::4fc:4001) client_ip=::1 client_names=::1 duration_ms=0 question=AAAA (ipinfo.tw.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:28]  INFO queryLog: query resolved answer=A (188.166.199.140) client_ip=::1 client_names=::1 duration_ms=0 question=A (ipinfo.tw.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:28]  INFO queryLog: query resolved answer=AAAA (2400:6180:0:d1::4fc:4001) client_ip=::1 client_names=::1 duration_ms=0 question=AAAA (ipinfo.tw.) response_code=NOERROR response_reason=CACHED
[2022-03-19 23:23:30]  INFO queryLog: query resolved answer=CNAME (ipv4.ipinfo.tw.), A (188.166.199.140) client_ip=::1 client_names=::1 duration_ms=238 question=A (4.ipinfo.tw.) response_code=NOERROR response_reason=RESOLVED (dns.google:853)
[2022-03-19 23:23:31]  INFO queryLog: query resolved answer= client_ip=::1 client_names=::1 duration_ms=279 question=AAAA (ipv4.ipinfo.tw.) response_code=NOERROR response_reason=RESOLVED (dns.google:853)

What I saw is that blocky will ask the bootstrap DNS about the encrypted DNS "everytime" when it received a non-cached query, which is not ideally, consider TTL of dns.google is actually 900 secs.

Maybe blocky should cache the upstream DNS's IP itself, lookup via bootstrap DNS only when the cache is not valid like the TTL is passed? Would be even better to lookup via encrypted DNS before the TTL is passed, so that there's no need to use the plaintext DNS for non-bootstrap need.

@0xERR0R
Copy link
Owner

0xERR0R commented Mar 19, 2022

Thanks for your input, now I can reproduce it. If I try following config:

upstream:
  default:
    - tcp-tls:one.one.one.one
    - https://dns.digitale-gesellschaft.ch/dns-query
port: ":8054"
bootstrapDns: udp:127.0.0.1:8053

only "one.one.one.one" appears in the log for each query. DoH address only once.

@0xERR0R
Copy link
Owner

0xERR0R commented Mar 19, 2022

If I understand it right, Go doesn't cache any DNS queries for lookups (see golang/go#24796 (comment) and golang/go#24796 (comment)). This is typically done by system DNS resolver. By setting the bootstrap dns for blocky, the application doesn't use the system DNS resolver.

I'll try to find out, if it is possible to cache those queries.

@0xERR0R 0xERR0R added the 🔨 enhancement New feature or request label Mar 19, 2022
@0xERR0R 0xERR0R added this to the 0.19 milestone Mar 19, 2022
@0xERR0R
Copy link
Owner

0xERR0R commented Mar 19, 2022

I added caching to the bootstrap resolver, It looks better now.

@0xERR0R 0xERR0R closed this as completed Mar 19, 2022
@PeterDaveHello
Copy link
Contributor Author

That's awesome, I'll see if I can build from the development branch and verify the behavior ;)

@0xERR0R
Copy link
Owner

0xERR0R commented Mar 20, 2022

That's awesome, I'll see if I can build from the development branch and verify the behavior ;)

If not, I can provide you a binary for Linux

@PeterDaveHello
Copy link
Contributor Author

I can verify that block isn't going to ask about upstream's IP address every time, that's nice! Would be even better if the upstream IP address can be looked up via encrypted DNS before the cache expired 😆

@0xERR0R
Copy link
Owner

0xERR0R commented Mar 21, 2022

If you want to DoT or DoH as bootstrap DNS, you need a working DNS resolver to resolve the IP of the URL. Therefore, current bootstrap DNS is a plain DNS, which can be used as IP address. I think, for DoT and DoH you can't use the IP address.

@PeterDaveHello
Copy link
Contributor Author

If you want to DoT or DoH as bootstrap DNS, you need a working DNS resolver to resolve the IP of the URL.

If the cache of DoH or DoT address is not expired yet, that'll be easier, to just to resolve those domains again, but just via the encrypted DNS? I mean, of course the first bootstrap has no context about upstream IP, but the following behavior after the bootstrap, the encrypted DNS is ready with resolved IP address, right?

Therefore, current bootstrap DNS is a plain DNS, which can be used as IP address. I think, for DoT and DoH you can't use the IP address.

Not sure if you mean the cert of DoT/DoH validation issue? Though this may not be very related to the original issue, but I know at least Google, Quad9, Quad101 and Cloudflare has valid cert for their IP address, that won't need a bootstrap, and can actually be reached via DoT/DoH via IP address.

For example, these sites are all valid:

Though Quad9 doesn't seem to support JSON API query, the other three DNS do, they will return the json format query result for you.:

@0xERR0R
Copy link
Owner

0xERR0R commented Mar 21, 2022

Not sure if you mean the cert of DoT/DoH validation issue? Though this may not be very related to the original issue, but I know at least Google, Quad9, Quad101 and Cloudflare has valid cert for their IP address, that won't need a bootstrap, and can actually be reached via DoT/DoH via IP address.

For example, these sites are all valid:

Though Quad9 doesn't seem to support JSON API query, the other three DNS do, they will return the json format query result for you.:

I was not aware, that some DNS providers have valid certs for IP only addresses. In this case it should be possible to use DoH/DoT as bootstrap even if the system has no valid DNS resolver. I'll create an issue for tracking purposes.

Edit: Issue created: #464

@PeterDaveHello
Copy link
Contributor Author

Just to confirm, so that using encrypted DNS itself to query its IP address before the cache expire wouldn't be considered to implement, right?

@0xERR0R
Copy link
Owner

0xERR0R commented Mar 22, 2022

I don't get your question. The idea is to allow to use either plain DNS or DoT/DoH as bootstrap DNS. This is only necessary, if host DNS resolver is not properly configured (of for some other reasons). If user wants to use a DNS server and configures a hostname/URL instead of IP address, blocky will use the system DNS resolver to obtain the IP.

@PeterDaveHello
Copy link
Contributor Author

Sorry for the confusion, I just wonder if the bootstrap can only be used at the bootstrap stage, which means once the first encrypted query was successfully sent and resolved, the following requests all going to the encrypted DNS, including the query of the domain of encrypted DNS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants