Discussion:
[Unbound-users] ends client subnet testing
DeJong, Steve
2015-05-06 17:13:10 UTC
Permalink
Hello,

I have been testing the edns-client-subnet support branch with the latest sync (thanks for the recent trunk sync) and there appears to be an issue when the subnet enabled query results in a CNAME response pointing to an A record that does not have client subnet information with it.

In my current setup I am running:
version: 1.5.4
verbosity: 3
threads: 2
modules: 3 [ subnet validator iterator ]
uptime: 1471 seconds
options: control(ssl)
unbound (pid 3307) is running...

My unbound.conf contains:
send-client-subnet: 156.154.64.0/24
send-client-subnet: 156.154.65.0/24
send-client-subnet: 156.154.66.0/24
send-client-subnet: 156.154.67.0/24
send-client-subnet: 156.154.68.0/24
send-client-subnet: 156.154.69.0/24
send-client-subnet: 2001:0502:F3FF::0000/48
send-client-subnet: 2610:00A1:1014::0000/48
send-client-subnet: 2610:00A1:1015::0000/48
send-client-subnet: 2610:00A1:1016::0000/48
send-client-subnet: 2610:00A1:1017::0000/48
send-client-subnet: 2001:0502:4612::0000/48

client-subnet-opcode: 8
max-client-subnet-ipv6: 48
max-client-subnet-ipv4: 24


When performing a dig against a hostname that returns a CNAME I see that the scope netmask is set to 0:
; <<>> DiG 9.10.1-P1 <<>> @127.0.0.1 +subnet=4.34.119.15 whereami.ultradns.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6362
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 6, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; CLIENT-SUBNET: 4.34.119.0/24/0
;; QUESTION SECTION:
;whereami.ultradns.net. IN A

;; ANSWER SECTION:
whereami.ultradns.net. 60 IN CNAME US-NY-New-York.ipi.ultrasupport.net.
US-NY-New-York.ipi.ultrasupport.net. 3600 IN A 127.0.0.2

;; AUTHORITY SECTION:
ipi.ultrasupport.net. 3600 IN NS pdns196.ultradns.co.uk.
ipi.ultrasupport.net. 3600 IN NS pdns196.ultradns.com.
ipi.ultrasupport.net. 3600 IN NS pdns196.ultradns.net.
ipi.ultrasupport.net. 3600 IN NS pdns196.ultradns.biz.
ipi.ultrasupport.net. 3600 IN NS pdns196.ultradns.org.
ipi.ultrasupport.net. 3600 IN NS pdns196.ultradns.info.

;; Query time: 1121 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed May 06 13:47:55 UTC 2015
;; MSG SIZE rcvd: 318

Some pcap analysis – attached – shows that the query for the CNAME responds with the correct scope netmask of 24. Unbound then goes to chase the CNAME and gets an A record response that does not contain client subnet information and the final response to the client sets the scope netmask to 0 which is what is shown in the dig result above. This response is optimized for the subnet that was sent but since the end scope netmask has been set to 0 all subsequent lookups, possibly from other clients, will get a cached answer that may not be optimal for that client. For example the next dig from a different subnet (Amsterdam) is answered from cache with an answer that is sub-optimal. This behavior is identical when the cname points to an address in zone as well.

; <<>> DiG 9.10.1-P1 <<>> @127.0.0.1 +subnet=212.72.53.207 whereami.ultradns.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33629
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 6, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; CLIENT-SUBNET: 212.72.53.207/32/0
;; QUESTION SECTION:
;whereami.ultradns.net. IN A

;; ANSWER SECTION:
whereami.ultradns.net. 46 IN CNAME US-NY-New-York.ipi.ultrasupport.net.
US-NY-New-York.ipi.ultrasupport.net. 3586 IN A 127.0.0.2

;; AUTHORITY SECTION:
ipi.ultrasupport.net. 3586 IN NS pdns196.ultradns.co.uk.
ipi.ultrasupport.net. 3586 IN NS pdns196.ultradns.com.
ipi.ultrasupport.net. 3586 IN NS pdns196.ultradns.net.
ipi.ultrasupport.net. 3586 IN NS pdns196.ultradns.biz.
ipi.ultrasupport.net. 3586 IN NS pdns196.ultradns.org.
ipi.ultrasupport.net. 3586 IN NS pdns196.ultradns.info.

;; Query time: 1 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed May 06 16:43:10 UTC 2015
;; MSG SIZE rcvd: 319

The draft, as far as I can tell , doesn’t say anything about chasing the CNAME so is this the expected behavior for Unbound? It would seem that the final response should use the client subnet information from the original CNAME response.

On the other hand all of the tests where the response is a plain A or AAAA record appear to be working well.

Thanks
Steve
Yuri Schaeffer
2015-05-07 18:47:42 UTC
Permalink
Hi Steve,
Post by DeJong, Steve
so is this the expected behavior for Unbound?
Yes.
Post by DeJong, Steve
It would seem that the final response should use the client subnet
information from the original CNAME response.
Why?
I don't think I'd agree.

//Yuri
DeJong, Steve
2015-05-07 20:20:57 UTC
Permalink
Post by Yuri Schaeffer
Why?
I don't think I'd agree.
Yuri, we see this kind of setup frequently with www records. The
authoritative zone will have www be an ECS capable record that will give
back CNAME records depending on the geographic location of the client. In
many cases those CNAMEs will point to a CDN or other hosting provider
outside the zone and often on a different authoritative resolver. The
actual A record referenced may not support ECS queries or may not provide
ECS information in the response.

Client A from NewYork looks up www.example.com
ECS enabled recursor (Unbound) asks the authoritative for www.example.com
with subnet information
Auth resolver responds with ECS specific CNAME for a CDN in eastern United
States with appropriate source and scope masks
Unbound chases the CNAME to get the address again providing subnet
information
Auth resolver either doesn¹t support ECS or chooses to set the scope mask
to 0 for the A record response

At this point Unbound has a CNAME that is ECS specific and an A that is
not. It will use the 0 scope for the CNAME as well as the A and cache the
response.

Now client B from London looks up www.example.com
Unbound has a cached response that technically is an ECS specific CNAME
for the eastern US - but because the scope mask was 0 on the A record
chase the server hands that answer back to the London client.

Probably not the result the owner of example.com was intending.

-Steve
Yuri Schaeffer
2015-05-08 08:23:04 UTC
Permalink
Post by DeJong, Steve
At this point Unbound has a CNAME that is ECS specific and an A
that is not. It will use the 0 scope for the CNAME as well as the A
and cache the response.
Well, you say that. But the trace shows that the A answer was in fact
ECS specific. (it indicated a scope of /0).
Post by DeJong, Steve
Probably not the result the owner of example.com was intending.
Indeed and I'm sure ignoring the ECS option from the A response would
solve your problem. But I don't think that is the right thing to do.

A middle ground _could_ be taking the maximum scopemask from the whole
cname chain. This will tell you how many bits where used/asked to come
to this final answer. I find it quite elegant and makes sense.

Changing this one 'small' thing however will result in a completely
different behaviour and answer. Since the draft does not cover this
topic at all I worry we are introducing something that might be
incompatible with other (future) implementations. If you base your
setup on Unbound with ECS you'll break it horribly if you try to
replace it with something else even tough that something implements
the very same protocol.

For me that last part is a red flag and makes me reluctant to start
coding a solution right away. I'd be much happier when the document
would include text on this matter.

//Yuri
DeJong, Steve
2015-05-08 13:53:40 UTC
Permalink
Post by Yuri Schaeffer
Post by DeJong, Steve
At this point Unbound has a CNAME that is ECS specific and an A
that is not. It will use the 0 scope for the CNAME as well as the A
and cache the response.
Well, you say that. But the trace shows that the A answer was in fact
ECS specific. (it indicated a scope of /0).
Yes, that behavior is specified clearly in the draft.

"If the edns-client-subnet option in the request is not used at all, a
server supporting edns-client-subnet MUST indicate that no bits of
the ADDRESS in the request have been used by specifying a SCOPE
NETMASK of 0, equivalent to the networks 0.0.0.0/0 or ::/0.²
Post by Yuri Schaeffer
Post by DeJong, Steve
Probably not the result the owner of example.com was intending.
Indeed and I'm sure ignoring the ECS option from the A response would
solve your problem. But I don't think that is the right thing to do.
A middle ground _could_ be taking the maximum scopemask from the whole
cname chain. This will tell you how many bits where used/asked to come
to this final answer. I find it quite elegant and makes sense.
That may be a decent solution as well.
Post by Yuri Schaeffer
Changing this one 'small' thing however will result in a completely
different behaviour and answer. Since the draft does not cover this
topic at all I worry we are introducing something that might be
incompatible with other (future) implementations. If you base your
setup on Unbound with ECS you'll break it horribly if you try to
replace it with something else even tough that something implements
the very same protocol.
For me that last part is a red flag and makes me reluctant to start
coding a solution right away. I'd be much happier when the document
would include text on this matter.
Agreed, there needs to be some clarity as there are multiple options for
behavior in this case. And the Unbound implementation is currently
different than the observed behavior of 8.8.8.8.

Thank you for taking a look and the responses.

-Steve

Loading...