AdguardTeam / dnsproxy

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

How does ECS work? #303

Open trmdi opened 1 year ago

trmdi commented 1 year ago

When running: dnsproxy -u https://dns.adguard.com/dns-query --edns --edns-addr=a.b.c.d and query with: dig @localhost [domain] at a same place, sometimes it returns the best IP, but sometimes it doesn't. Is it a bug or it's how ECS work?

ameshkov commented 1 year ago

Does it depend on the domain? Have you tried comparing it with Google DNS?

What's important also is that you're testing it with AG DNS and it does not simply pass your IP to the nameservers. Instead, it uses a different IP from the same country or ASN (depending on how large is the ASN your IP belongs to) so that the nameservers didn't receive your personal information. Sometimes it works pretty well, sometimes it does not.

trmdi commented 1 year ago

Yeah, it depends on the domain. Google DNS sometimes doesn't return the best one too.

What's important also is that you're testing it with AG DNS and it does not simply pass your IP to the nameservers. Instead, it uses a different IP from the same country or ASN (depending on how large is the ASN your IP belongs to) so that the nameservers didn't receive your personal information. Sometimes it works pretty well, sometimes it does not.

I'm a bit confused at this. We have several IPs here:

Then which one will be chosen? For this example, AG DNS is failed in returning the best IP to my query.

dig @localhost cf.shopee.vn.akamaized.net +short
a1958.w16.akamai.net.
23.49.60.169
23.49.60.129
23.49.60.178

dig @8.8.8.8 cf.shopee.vn.akamaized.net +short  
a1958.w16.akamai.net.
113.171.230.82
113.171.230.80

Maybe AG DNS would return the same result if it uses (1) ? Or there could be an option in AG DNS to send the real subnet of the user's IP instead of (3)? (just a wild guess)

ameshkov commented 1 year ago

I'm a bit confused at this. We have several IPs here:

Let's take some random IP address as an example.

  1. For instance, let's say you make dnsproxy send 108.26.1.115 in the ECS.
  2. AdGuard DNS receives it and checks which ASN and country it belongs to. This one belongs to AS701, country US.
  3. Then AdGuard DNS gets a random IP address from that ASN (not exactly random, but just for the sake of simplicity) and sends it to the nameserver instead of the IP that it received from you.

Let's take another example, let's say we're dealing with a smaller ASN.

  1. For instance, you send 62.228.232.15 in the ECS.
  2. AdGuard DNS checks ASN and country. This one belongs to AS35247, country CY.
  3. This is not a popular ASN so AdGuard DNS cannot choose an address from it. Instead, it will take the most popular ASN in CY and use an address from it.

The idea is that we should get the best from ECS, but without sharing users's addresses with the nameservers.

Or there could be an option in AG DNS to send the real subnet of the user's IP instead of

Can't do that, the behavior that I explain is the default one.

Google DNS sometimes doesn't return the best one too.

This sounds like the nameserver's load balancing fault if they can't return the best IP even when your real IP is used in the ECS.

agneevX commented 1 year ago

@ameshkov that sounds like a very expensive way of just not sending source IP CIDRs to name servers and it seems like it has the opposite effect.

~> kdig TXT o-o.myaddr.google.com @dns.adguard.com +tls +short
"2a02:6ea0:d13b:3::2"
"edns0-client-subnet 184.86.248.0/24"

184.86.248.0/24 belongs to another ISP and obviously has a different AS. The issue is that this particular AS has their own transit so any CDN stuff is on their network and the interconnect with any other AS' is non existent, ultimately leading to high latency...

~> kdig @dns.adguard.com +tls +short hses.akamaized.net
a1834.dscw80.akamai.net.
23.47.190.219
23.47.190.160

~> ping 23.47.190.219
PING 23.47.190.219 (23.47.190.219) 56(84) bytes of data.
64 bytes from 23.47.190.219: icmp_seq=1 ttl=52 time=98.6 ms
64 bytes from 23.47.190.219: icmp_seq=2 ttl=52 time=99.9 ms

Now, dns.adguard.com anycast points to another country... SGP in my case, so does 9.9.9.9...

~> kdig @9.9.9.9 +tls +short hses.akamaized.net
a1834.dscw80.akamai.net.
42.99.140.184
42.99.140.217

~> ping 42.99.140.184
PING 42.99.140.184 (42.99.140.184) 56(84) bytes of data.
64 bytes from 42.99.140.184: icmp_seq=1 ttl=56 time=67.6 ms
64 bytes from 42.99.140.184: icmp_seq=2 ttl=56 time=68.0 ms

As you can see, a non ECS sending resolver sends me on a path of less latency :)

trmdi commented 1 year ago

Yes, suppose you are in Hanoi/Vietnam, Adguard uses an IP in Ho Chi Minh city (Vietnam) as the ECS. Then resolvers return IPs in HCM city or Singapore, rather than ones in Hanoi or Hongkong.

Similar to https://github.com/AdguardTeam/AdGuardDNS/issues/336

ameshkov commented 1 year ago

that sounds like a very expensive way of just not sending source IP CIDRs to name servers and it seems like it has the opposite effect

I would disagree, it actually provides much better results than not sending ECS at all.

But yeah, this is not ideal, at least not until we extend the number of "popular AS numbers".

trmdi commented 1 year ago

To Adguard DNS lovers, I made a new request here: https://github.com/AdguardTeam/AdGuardDNS/issues/649