Subject: preventing cache contamination

From: masataka ohta <[email-masked]>
Date: Thu, 06 Nov 2003 08:28:57 +0900

Does the following work to prevent DNS cache contamination

	1) have no public access on shared media from cache to external
	network (to prevent MITM)

	2) have separate cache for glue

	3) cache an answer to a query but activate it only after a
	compatible answer is returned for latter query (to protect
	against ID space attack)

?

						Masataka Ohta

#----------------------------------------------------------------------
# To unsubscribe, send a message to <[email-masked]>.

---

From: bert hubert <[email-masked]>
Date: Thu, 6 Nov 2003 08:00:44 +0100

> Does the following work to prevent DNS cache contamination

A proper algorithm prevents that. There is a slight chance of spoofing
answers to a nameserver if you can guess its source port and query id.

> 	network (to prevent MITM)

You need to trust your local segment indeed.

> 	2) have separate cache for glue

This isn't necessary and a bad idea.

> 	compatible answer is returned for latter query (to protect

I don't understand this one, but indeed, there are some things you need to
do to prevent birthday attacks on the ID space.

Good luck.

-- 
http://www.PowerDNS.com      Open source, database driven DNS Software 
http://lartc.org           Linux Advanced Routing & Traffic Control HOWTO
#----------------------------------------------------------------------
# To unsubscribe, send a message to <[email-masked]>.

---

From: "Scott Rose" <[email-masked]>
Date: Thu, 6 Nov 2003 08:13:08 -0500

I am not if I understand all the questions.  Is this for an implementation
of a recursive (caching) name server?

----- Original Message ----- 
From: "masataka ohta" <[email-masked]>

> network (to prevent MITM)
Agree with bert.  As long as you trust the links.

> 2) have separate cache for glue

Could the server mark glue RRsets in cache, then trust them when they can be
confirmed through subsequent queries?

> compatible answer is returned for latter query (to protect
A later query initiated by the server, or from another client?  I think I do
not understand this.

Scott

---

From: Masataka Ohta <[email-masked]>
Date: Fri, 07 Nov 2003 14:23:37 +0900

bert hubert;

> answers to a nameserver if you can guess its source port and query id.

That's what I'm trying to prevent.

> This isn't necessary and a bad idea.

It is a just enough protection against well known attack to
contaminate cache by glue A, which I confirmed to work about
10 years ago.

That is, with

	hpcl.titech.ac.jp.	NS	foo.bar
	foo.bar.		A	131.112.32.132

a manager of hpcl.titech.ac.jp (that is, I) can tell anything
about A of foo.bar or whatever domain, cache of which should be
used only for glue A of hpcl.titech.ac.jp.

I know both PV and DJB didn't understand it and tried to use
insufficient or excessively complex approaches.

> do to prevent birthday attacks on the ID space.

I'm saying answer should be stored in cache for latter use, only
if the same answer is obtained multiple times with independent
IDs.

Then, attackers must guess all the IDs, which effectively enlengthen
the number of ID bits, though it reduces the effectiveness of cache.

						Masataka Ohta

---

From: bert hubert <[email-masked]>
Date: Fri, 7 Nov 2003 08:15:20 +0100

> contaminate cache by glue A, which I confirmed to work about

pdns_recursor simply rejects answers that are not in the zone of the NS that

> 	foo.bar.		A	131.112.32.132

Say a question originally arrived for www.hpcl.titech.ac.jp, and
pdns_recursor already had "titech.ac.jp NS your-nameserver", pdns_recursor
only accepts answers within or above titech.ac.jp. Foo.bar is immediately
rejected, as it does not end on titech.ac.jp.

Every once in a while this causes pdns to ask more questions than strictly
necessary but it's still faster than most recursing nameservers.

Run pdns_recursor in --trace mode to see it explain all its decisions. In
this case, the glue is not necessary and hence not accepted.

I think DJB does something smarter and accepts the glue *only* for this
question.

> if the same answer is obtained multiple times with independent

Ah - so you just ask a question multiple times with different id and source
port, making it exponentially harder to spoof an answer. Sure, that would
work but it doubles the load on authoritative nameservers.

Bert.

---

From: Masataka Ohta <[email-masked]>
Date: Fri, 07 Nov 2003 16:42:31 +0900

bert hubert;

> port, making it exponentially harder to spoof an answer.

No, though it is a protection on end systems. To prevent cache
contamination, it is enough that caching server caches information
only if there are more than one query.

> Sure, that would
> work

Thanks. Anyone else with other opinion?

> but it doubles the load on authoritative nameservers.

Not necessarily. That is, as for caching servers, some questions
are asked only once that there is no duplicated query generated.

Anyway, does anyone mind?

Note that the traffic should be a lot less than that for
secure DNS.

> rejected, as it does not end on titech.ac.jp.

Are you saying nameservers "[a-m].gtld-servers.net." for "com." are
rejected?

> I think DJB does something smarter and accepts the glue *only* for this

That's unnecessarily inefficient.

							Masataka Ohta

---

From: bert hubert <[email-masked]>
Date: Fri, 7 Nov 2003 09:03:38 +0100

> only if there are more than one query.

Ah - that would still allow the first answer to be spoofed. How do you deal
with bonafide changes within the TTL? These also generate different answers
than before.

> Anyway, does anyone mind?

I think every recursor is free to determine its own strategy, if this rocks
your boat, go right ahead :-)

> Are you saying nameservers "[a-m].gtld-servers.net." for "com." are

No, I look at the left hand side, [a-m].gtld-servers.net are accepted from
the "." nameserver because they are records for "COM." which is above ".".
They are also accepted from [a-m].gtld-servers.net themselves, as they are
the "COM." nameservers.

Output of --trace:

question for 'www.theregister.com|A' from 127.0.0.1
www.theregister.com: Looking for CNAME cache hit of 'www.theregister.com|CNAME'
www.theregister.com: No CNAME cache hit of 'www.theregister.com|CNAME' found
www.theregister.com: Looking for direct cache hit of 'www.theregister.com|A', 0
www.theregister.com: No cache hit for 'www.theregister.com|A', trying to find an appropriate NS record
www.theregister.com: Checking if we have NS in cache for 'www.theregister.com'
www.theregister.com: Checking if we have NS in cache for 'theregister.com'
www.theregister.com: Checking if we have NS in cache for 'com'
www.theregister.com: Checking if we have NS in cache for ''
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'A.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'B.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'C.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'D.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'E.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'F.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'G.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'H.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'I.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'J.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'K.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'L.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: NS (with ip, or non-glue) in cache for '' -> 'M.ROOT-SERVERS.NET'
www.theregister.com: endson: 1, in cache, ttl=3599999
www.theregister.com: We have NS in cache for ''
www.theregister.com: Cache consultations done, have 13 NS to contact
www.theregister.com: Trying to resolve NS M.ROOT-SERVERS.NET (1/13)
  M.ROOT-SERVERS.NET: Looking for CNAME cache hit of 'm.root-servers.net|CNAME'
  M.ROOT-SERVERS.NET: No CNAME cache hit of 'm.root-servers.net|CNAME' found
  M.ROOT-SERVERS.NET: Looking for direct cache hit of 'm.root-servers.net|A', 0
  M.ROOT-SERVERS.NET: Found cache hit for A: 202.12.27.33[ttl=3599999] 
www.theregister.com: Resolved NS M.ROOT-SERVERS.NET to 202.12.27.33, asking 'www.theregister.com|A'
www.theregister.com: Got 26 answers from M.ROOT-SERVERS.NET (202.12.27.33), rcode=0
www.theregister.com: accept answer 'com|NS|A.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|G.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|H.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|C.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|I.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|B.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|D.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|L.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|F.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|J.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|K.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|E.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'com|NS|M.GTLD-SERVERS.NET' from '' nameservers? YES!
www.theregister.com: accept answer 'A.GTLD-SERVERS.NET|A|192.5.6.30' from '' nameservers? YES!
www.theregister.com: accept answer 'G.GTLD-SERVERS.NET|A|192.42.93.30' from '' nameservers? YES!
www.theregister.com: accept answer 'H.GTLD-SERVERS.NET|A|192.54.112.30' from '' nameservers? YES!
www.theregister.com: accept answer 'C.GTLD-SERVERS.NET|A|192.26.92.30' from '' nameservers? YES!
www.theregister.com: accept answer 'I.GTLD-SERVERS.NET|A|192.43.172.30' from '' nameservers? YES!
www.theregister.com: accept answer 'B.GTLD-SERVERS.NET|A|192.33.14.30' from '' nameservers? YES!
www.theregister.com: accept answer 'D.GTLD-SERVERS.NET|A|192.31.80.30' from '' nameservers? YES!
www.theregister.com: accept answer 'L.GTLD-SERVERS.NET|A|192.41.162.30' from '' nameservers? YES!
www.theregister.com: accept answer 'F.GTLD-SERVERS.NET|A|192.35.51.30' from '' nameservers? YES!
www.theregister.com: accept answer 'J.GTLD-SERVERS.NET|A|192.48.79.30' from '' nameservers? YES!
www.theregister.com: accept answer 'K.GTLD-SERVERS.NET|A|192.52.178.30' from '' nameservers? YES!
www.theregister.com: accept answer 'E.GTLD-SERVERS.NET|A|192.12.94.30' from '' nameservers? YES!
www.theregister.com: accept answer 'M.GTLD-SERVERS.NET|A|192.55.83.30' from '' nameservers? YES!
www.theregister.com: determining status after receiving this packet
www.theregister.com: got NS record 'com' -> 'A.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'G.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'H.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'C.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'I.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'B.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'D.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'L.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'F.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'J.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'K.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'E.GTLD-SERVERS.NET'
www.theregister.com: got NS record 'com' -> 'M.GTLD-SERVERS.NET'
www.theregister.com: status=did not resolve, got 13 NS, looping to them
www.theregister.com: Trying to resolve NS f.gtld-servers.net (1/13)
  f.gtld-servers.net: Looking for CNAME cache hit of 'f.gtld-servers.net|CNAME'
  f.gtld-servers.net: No CNAME cache hit of 'f.gtld-servers.net|CNAME' found
  f.gtld-servers.net: Looking for direct cache hit of 'f.gtld-servers.net|A', 0
  f.gtld-servers.net: Found cache hit for A: 192.35.51.30[ttl=172800] 
www.theregister.com: Resolved NS f.gtld-servers.net to 192.35.51.30, asking 'www.theregister.com|A'
www.theregister.com: Got 8 answers from f.gtld-servers.net (192.35.51.30), rcode=0
www.theregister.com: accept answer 'theregister.com|NS|ns1.theregister.com' from 'com' nameservers? YES!
www.theregister.com: accept answer 'theregister.com|NS|ns2.theregister.com' from 'com' nameservers? YES!
www.theregister.com: accept answer 'theregister.com|NS|ns3.theregister.com' from 'com' nameservers? YES!
www.theregister.com: accept answer 'theregister.com|NS|ns4.theregister.com' from 'com' nameservers? YES!
www.theregister.com: accept answer 'ns1.theregister.com|A|212.100.234.58' from 'com' nameservers? YES!
www.theregister.com: accept answer 'ns2.theregister.com|A|212.100.234.57' from 'com' nameservers? YES!
www.theregister.com: accept answer 'ns3.theregister.com|A|212.100.234.56' from 'com' nameservers? YES!
www.theregister.com: accept answer 'ns4.theregister.com|A|212.100.234.55' from 'com' nameservers? YES!
www.theregister.com: determining status after receiving this packet
www.theregister.com: got NS record 'theregister.com' -> 'ns1.theregister.com'
www.theregister.com: got NS record 'theregister.com' -> 'ns2.theregister.com'
www.theregister.com: got NS record 'theregister.com' -> 'ns3.theregister.com'
www.theregister.com: got NS record 'theregister.com' -> 'ns4.theregister.com'
www.theregister.com: status=did not resolve, got 4 NS, looping to them
www.theregister.com: Trying to resolve NS ns3.theregister.com (1/4)
  ns3.theregister.com: Looking for CNAME cache hit of 'ns3.theregister.com|CNAME'
  ns3.theregister.com: No CNAME cache hit of 'ns3.theregister.com|CNAME' found
  ns3.theregister.com: Looking for direct cache hit of 'ns3.theregister.com|A', 0
  ns3.theregister.com: Found cache hit for A: 212.100.234.56[ttl=172800] 
www.theregister.com: Resolved NS ns3.theregister.com to 212.100.234.56, asking 'www.theregister.com|A'
www.theregister.com: Got 9 answers from ns3.theregister.com (212.100.234.56), rcode=0
www.theregister.com: accept answer 'www.theregister.com|A|212.100.234.54' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'theregister.com|NS|ns1.theregister.com' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'theregister.com|NS|ns2.theregister.com' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'theregister.com|NS|ns3.theregister.com' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'theregister.com|NS|ns4.theregister.com' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'ns1.theregister.com|A|212.100.234.58' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'ns2.theregister.com|A|212.100.234.57' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'ns3.theregister.com|A|212.100.234.56' from 'theregister.com' nameservers? YES!
www.theregister.com: accept answer 'ns4.theregister.com|A|212.100.234.55' from 'theregister.com' nameservers? YES!
www.theregister.com: determining status after receiving this packet
www.theregister.com: answer is in: resolved to '212.100.234.54|A'
www.theregister.com: got upwards/level NS record 'theregister.com' -> 'ns1.theregister.com', had 'theregister.com'
www.theregister.com: got upwards/level NS record 'theregister.com' -> 'ns2.theregister.com', had 'theregister.com'
www.theregister.com: got upwards/level NS record 'theregister.com' -> 'ns3.theregister.com', had 'theregister.com'
www.theregister.com: got upwards/level NS record 'theregister.com' -> 'ns4.theregister.com', had 'theregister.com'
www.theregister.com: status=got results, this level of recursion done
www.theregister.com: Starting additional processing
www.theregister.com: Done with additional processing
answer to question 'www.theregister.com|A': 1 answers, 0 additional, took 3 packets, 0 throttled, rcode=0

	Bert

---

From: Masataka Ohta <[email-masked]>
Date: Fri, 07 Nov 2003 17:23:14 +0900

bert hubert;

> Ah - that would still allow the first answer to be spoofed.

I know and it is easy to stop it. But see the subject.

> How do you deal

That's why I wrote "compatible answer" in the first mail of the
thread.

> the "." nameserver because they are records for "COM." which is above ".".

"COM." is above "."? I'm totally confused. Are there any document
on the net?

							Masataka Ohta