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

ECS Automatically Added Despite Empty ecs-add-for #15232

Open
yegors opened this issue Feb 28, 2025 · 4 comments
Open

ECS Automatically Added Despite Empty ecs-add-for #15232

yegors opened this issue Feb 28, 2025 · 4 comments

Comments

@yegors
Copy link

yegors commented Feb 28, 2025

  • Program: Recursor
  • Issue type: Bug report

Short description

PowerDNS Recursor 5.2.0 automatically adds EDNS Client Subnet (ECS) to all queries, even when not specified by the client, despite setting --ecs-add-for= to empty. ECS should only be included when explicitly provided (e.g., via dig +subnet).

Environment

  • Operating system: Ubuntu 22.04
  • Software version: PowerDNS Recursor 5.2.0
  • Software source: Direct download

Steps to reproduce

  1. Launch PowerDNS Recursor with: sudo pdns_recursor --config-dir=/etc/powerdns --socket-dir=/tmp --dnssec=off --trace=yes --quiet=no --use-incoming-edns-subnet=yes --ecs-add-for= --ecs-scope-zero-address=0.0.0.0 --edns-subnet-allow-list=0.0.0.0/0,::/0 --local-address=127.0.0.1
  2. Query without ECS: dig @127.0.0.1 -t txt o-o.myaddr.google.com
  3. Query with ECS: dig @127.0.0.1 -t txt o-o.myaddr.google.com +subnet=1.2.3.4/24

Expected behaviour

  • Without +subnet, no ECS should be added to queries.
  • With +subnet=1.2.3.4/24, ECS should be 1.2.3.0/24 in the response.

Actual behaviour

  • Without ECS: ECS (127.0.0.1/32) is added automatically.
  • Log: Feb 27 19:57:34 [1] myaddr.google.com: Adding EDNS Client Subnet Mask 127.0.0.1/32 to query
  • Response includes "edns0-client-subnet 66.xxx.xxx.xxx/32" (Google overrides 127.0.0.1 to source IP of query).
  • With ECS: ECS (1.2.3.0/24) is correctly passed through.
  • Log: Feb 27 19:58:21 [2] o-o.myaddr.google.com: Adding EDNS Client Subnet Mask 1.2.3.0/24 to query
  • Response: "edns0-client-subnet 1.2.3.0/24"

Other information

  • Workarounds tried: --ecs-add-for=, --ecs-scope-zero-address=0.0.0.0, --ecs-add-for=!0.0.0.0/0,!::/0—none stop automatic ECS.
  • Minimal config (--dnssec=off --trace=yes --quiet=no --local-address=127.0.0.1) prevents ECS, but adding --edns-subnet-allow-list=0.0.0.0/0,::/0 triggers it again.
  • Suspect edns-subnet-allow-list overrides --ecs-add-for=, forcing ECS addition.
@dwfreed
Copy link
Contributor

dwfreed commented Feb 28, 2025

This is expected and intentional behavior. You're hitting this code, which includes an explanation:

else if (s_ecsScopeZero.source.getBits() > 0) {
/* RFC7871 says we MUST NOT send any ECS if the source scope is 0.
But using an empty ECS in that case would mean inserting
a non ECS-specific entry into the cache, preventing any further
ECS-specific query to be sent.
So instead we use the trick described in section 7.1.2:
"The subsequent Recursive Resolver query to the Authoritative Nameserver
will then either not include an ECS option or MAY optionally include
its own address information, which is what the Authoritative
Nameserver will almost certainly use to generate any Tailored
Response in lieu of an option. This allows the answer to be handled
by the same caching mechanism as other queries, with an explicit
indicator of the applicable scope. Subsequent Stub Resolver queries
for /0 can then be answered from this cached response.
*/
d_outgoingECSNetwork = boost::optional<Netmask>(s_ecsScopeZero.source.getMaskedNetwork());
d_cacheRemote = s_ecsScopeZero.source.getNetwork();
}

(Random fun fact: because of other code, the condition at line 6092 will always be true)

@yegors
Copy link
Author

yegors commented Feb 28, 2025

Thanks, but I'm a little confused. How would I achieve the goal of not sending any ECS options to authoritative servers unless the subnet is explicitly provided in the query? I'm using dig for testing, in reality there is a DNS server sitting in front of PowerDNS that will provide dynamic ECS values based on user configuration.

The value of ecs-scope-zero-address does not change anything, it can be set to any value or omitted, the behavior is still the same - ECS is always appended by PowerDNS.

@dwfreed
Copy link
Contributor

dwfreed commented Feb 28, 2025

You can't. pdns-recursor isn't set up to be able to do that, because an answer cached without ECS will always be returned regardless of ECS from the source, so if it's supposed to be providing ECS to an auth, it needs to always provide ECS to that auth in some form.

@omoerbeek
Copy link
Member

@dwfreed hits the nail on the head. On an additional note, do not send ECS info to all the nameservers you're contacting. Some of them do not respond well to ECS containing queries and in general it reduces cache performance in the Recursor. Only send ECS to nameservers for which it is useful. So restrict edns-subnet-allow-list (it can contain names).

I'm switching this to a discussion as it it's not a bug.

@PowerDNS PowerDNS locked and limited conversation to collaborators Feb 28, 2025
@omoerbeek omoerbeek converted this issue into a discussion Feb 28, 2025
@omoerbeek omoerbeek reopened this Feb 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants