> Stephane Bortzmeyer <mailto:bortzme...@nic.fr> > Saturday, February 28, 2015 8:20 AM > For those who want to play with the zone cuts (finding them is > necessary for qname minimisation), here is a simple implementation of > appendix A of draft-ietf-dnsop-qname-minimisation-01: > > https://github.com/bortzmeyer/my-IETF-work/blob/master/draft-ietf-dnsop-qname-minimisation/zonecut.go > > Implemented in France, so I can safely ignore > <http://datatracker.ietf.org/ipr/2542/> (see > <http://en.wikipedia.org/wiki/Software_patents_under_the_European_Patent_Convention>)
fwiw, "dig +trace" has had this code in it for at least ten years. (and may serve as prior art for anyone who wants to challenge the above patent.) > > This code implements the "aggressive" strategy (the most > privacy-efficient) of section 2 of > draft-ietf-dnsop-qname-minimisation-01. > > Here are some interesting examples. Remember that this ultra-simple > program has no cache at all so it is the equivalent of a cold > resolver. First, a trivial case, www.icann.org: > > % ./zonecut -q=1 -v www.icann.org > Searching 1 for www.icann.org. > > Zone cut at "." > Querying type 2 for name org. at server k.root-servers.net > Result for "org.": Referral(s) > > Zone cut at "org." > Querying type 2 for name icann.org. at server d0.org.afilias-nst.org. > Result for "icann.org.": Referral(s) > > Zone cut at "icann.org." > Querying type 2 for name www.icann.org. at server a.iana-servers.net. > Result for "www.icann.org.": Answer(s) > Querying type 1 for name www.icann.org. at server a.iana-servers.net. > Final result: [www.icann.org. 21600 IN CNAME www.vip.icann.org.] [family.redbarn:amd64] dig +trace www.icann.org | awk '$4 ~ "(CNAME|NS)$" {print}' . 37722 IN NS l.root-servers.net. . 37722 IN NS h.root-servers.net. . 37722 IN NS g.root-servers.net. . 37722 IN NS e.root-servers.net. . 37722 IN NS j.root-servers.net. . 37722 IN NS a.root-servers.net. . 37722 IN NS f.root-servers.net. . 37722 IN NS b.root-servers.net. . 37722 IN NS d.root-servers.net. . 37722 IN NS m.root-servers.net. . 37722 IN NS k.root-servers.net. . 37722 IN NS i.root-servers.net. . 37722 IN NS c.root-servers.net. org. 172800 IN NS a0.org.afilias-nst.info. org. 172800 IN NS a2.org.afilias-nst.info. org. 172800 IN NS b0.org.afilias-nst.org. org. 172800 IN NS b2.org.afilias-nst.org. org. 172800 IN NS c0.org.afilias-nst.info. org. 172800 IN NS d0.org.afilias-nst.org. icann.org. 86400 IN NS a.iana-servers.net. icann.org. 86400 IN NS b.iana-servers.net. icann.org. 86400 IN NS c.iana-servers.net. icann.org. 86400 IN NS ns.icann.org. www.icann.org. 21600 IN CNAME www.vip.icann.org. vip.icann.org. 3600 IN NS gtm1.dc.icann.org. vip.icann.org. 3600 IN NS gtm1.lax.icann.org. > > > > Here, a case where there is a domain which is not a zone (gouv.fr): > > % ./zonecut -q=1 -v www.ssi.gouv.fr > Searching 1 for www.ssi.gouv.fr. > > Zone cut at "." > Querying type 2 for name fr. at server k.root-servers.net > Result for "fr.": Referral(s) > > Zone cut at "fr." > Querying type 2 for name gouv.fr. at server g.ext.nic.fr. > Result for "gouv.fr.": Referral(s) > Querying type 2 for name ssi.gouv.fr. at server g.ext.nic.fr. > Result for "ssi.gouv.fr.": Referral(s) > > Zone cut at "ssi.gouv.fr." > Querying type 2 for name www.ssi.gouv.fr. at server dns1.ssi.gouv.fr. > Result for "www.ssi.gouv.fr.": Referral(s) > Querying type 1 for name www.ssi.gouv.fr. at server dns1.ssi.gouv.fr. > Final result: [www.ssi.gouv.fr. 300 IN A 213.56.166.109] [family.redbarn:amd64] dig +trace www.ssi.gouv.fr | awk '$4 ~ "(CNAME|NS)$" {print}' . 37652 IN NS m.root-servers.net. . 37652 IN NS h.root-servers.net. . 37652 IN NS i.root-servers.net. . 37652 IN NS l.root-servers.net. . 37652 IN NS c.root-servers.net. . 37652 IN NS d.root-servers.net. . 37652 IN NS a.root-servers.net. . 37652 IN NS g.root-servers.net. . 37652 IN NS b.root-servers.net. . 37652 IN NS f.root-servers.net. . 37652 IN NS k.root-servers.net. . 37652 IN NS j.root-servers.net. . 37652 IN NS e.root-servers.net. fr. 172800 IN NS f.ext.nic.fr. fr. 172800 IN NS g.ext.nic.fr. fr. 172800 IN NS d.nic.fr. fr. 172800 IN NS d.ext.nic.fr. fr. 172800 IN NS e.ext.nic.fr. ssi.gouv.fr. 172800 IN NS dns1.ssi.gouv.fr. ssi.gouv.fr. 172800 IN NS dns1.certa.ssi.gouv.fr. ssi.gouv.fr. 300 IN NS dns1.certa.ssi.gouv.fr. ssi.gouv.fr. 300 IN NS dns1.ssi.gouv.fr. > > > > This is of course much more common in arpa domains: > > % ./zonecut -q=12 -v > 5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa > Searching 12 for > 5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. > > Zone cut at "." > Querying type 2 for name arpa. at server k.root-servers.net > Result for "arpa.": Answer(s) > > Zone cut at "arpa." > Querying type 2 for name ip6.arpa. at server m.root-servers.net. > Result for "ip6.arpa.": Referral(s) > > Zone cut at "ip6.arpa." > Querying type 2 for name 2.ip6.arpa. at server e.ip6-servers.arpa. > Result for "2.ip6.arpa.": Referral(s) > Querying type 2 for name 0.2.ip6.arpa. at server e.ip6-servers.arpa. > Result for "0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 0.0.2.ip6.arpa. at server e.ip6-servers.arpa. > Result for "0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 1.0.0.2.ip6.arpa. at server e.ip6-servers.arpa. > Result for "1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 0.1.0.0.2.ip6.arpa. at server e.ip6-servers.arpa. > Result for "0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 6.0.1.0.0.2.ip6.arpa. at server > e.ip6-servers.arpa. > Result for "6.0.1.0.0.2.ip6.arpa.": Answer(s) > > Zone cut at "6.0.1.0.0.2.ip6.arpa." > Querying type 2 for name 7.6.0.1.0.0.2.ip6.arpa. at server ns3.nic.fr. > Result for "7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name c.7.6.0.1.0.0.2.ip6.arpa. at server ns3.nic.fr. > Result for "c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 2.c.7.6.0.1.0.0.2.ip6.arpa. at server ns3.nic.fr. > Result for "2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns3.nic.fr. > Result for "2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns3.nic.fr. > Result for "1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns3.nic.fr. > Result for "8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Answer(s) > > Zone cut at "8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa." > Querying type 2 for name 0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns2.nic.fr. > Result for "0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for "0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for "3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for "0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. > at server ns2.nic.fr. > Result for "0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name 0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. > at server ns2.nic.fr. > Result for "0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name > 0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server ns2.nic.fr. > Result for "0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name > 0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server ns2.nic.fr. > Result for "0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server ns2.nic.fr. > Result for "0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns2.nic.fr. > Result for "0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns2.nic.fr. > Result for "0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at server > ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. > at server ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. at > server ns2.nic.fr. > Result for > "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 2 for name > 5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. > at server ns2.nic.fr. > Result for > "5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa.": > Referral(s) > Querying type 12 for name > 5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. > at server ns2.nic.fr. > Final result: > [5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. > 600 IN PTR web01.nic.fr.] [family.redbarn:amd64] dig +trace 5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.3.0.0.8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa | awk '$4 ~ "(CNAME|NS)$" {print}' . 37604 IN NS j.root-servers.net. . 37604 IN NS f.root-servers.net. . 37604 IN NS g.root-servers.net. . 37604 IN NS m.root-servers.net. . 37604 IN NS k.root-servers.net. . 37604 IN NS e.root-servers.net. . 37604 IN NS c.root-servers.net. . 37604 IN NS h.root-servers.net. . 37604 IN NS d.root-servers.net. . 37604 IN NS i.root-servers.net. . 37604 IN NS b.root-servers.net. . 37604 IN NS a.root-servers.net. . 37604 IN NS l.root-servers.net. ip6.arpa. 172800 IN NS d.ip6-servers.arpa. ip6.arpa. 172800 IN NS f.ip6-servers.arpa. ip6.arpa. 172800 IN NS c.ip6-servers.arpa. ip6.arpa. 172800 IN NS b.ip6-servers.arpa. ip6.arpa. 172800 IN NS a.ip6-servers.arpa. ip6.arpa. 172800 IN NS e.ip6-servers.arpa. 6.0.1.0.0.2.ip6.arpa. 86400 IN NS tinnie.arin.net. 6.0.1.0.0.2.ip6.arpa. 86400 IN NS sec1.apnic.net. 6.0.1.0.0.2.ip6.arpa. 86400 IN NS sns-pb.isc.org. 6.0.1.0.0.2.ip6.arpa. 86400 IN NS ns3.nic.fr. 6.0.1.0.0.2.ip6.arpa. 86400 IN NS pri.authdns.ripe.net. 6.0.1.0.0.2.ip6.arpa. 86400 IN NS sec3.apnic.net. 8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. 172800 IN NS ns3.nic.fr. 8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. 172800 IN NS ns1.nic.fr. 8.1.2.2.c.7.6.0.1.0.0.2.ip6.arpa. 172800 IN NS ns2.nic.fr. > > > > > The algorithm may work with broken name servers. Here, the name > servers of www.ratp.fr do not properly reply to NS domains, but the > program does not query them for qtype=NS if it is arrived at the leaf: > > % ./zonecut -q=1 -v www.ratp.fr > Searching 1 for www.ratp.fr. > > Zone cut at "." > Querying type 2 for name fr. at server k.root-servers.net > Result for "fr.": Referral(s) > > Zone cut at "fr." > Querying type 2 for name ratp.fr. at server g.ext.nic.fr. > Result for "ratp.fr.": Referral(s) > > Zone cut at "ratp.fr." > Querying type 2 for name www.ratp.fr. at server indom30.indomco.fr. > Result for "www.ratp.fr.": Answer(s) > > Zone cut at "www.ratp.fr." > Querying type 1 for name www.ratp.fr. at server lbns2.ratp.fr. > Final result: [www.ratp.fr. 30 IN A 195.200.228.10 www.ratp.fr. 30 IN > A 195.200.228.170] [family.redbarn:amd64] dig +trace www.ratp.fr | awk '$4 ~ "(CNAME|NS)$" {print}' . 37561 IN NS k.root-servers.net. . 37561 IN NS i.root-servers.net. . 37561 IN NS l.root-servers.net. . 37561 IN NS h.root-servers.net. . 37561 IN NS c.root-servers.net. . 37561 IN NS a.root-servers.net. . 37561 IN NS b.root-servers.net. . 37561 IN NS e.root-servers.net. . 37561 IN NS f.root-servers.net. . 37561 IN NS m.root-servers.net. . 37561 IN NS g.root-servers.net. . 37561 IN NS j.root-servers.net. . 37561 IN NS d.root-servers.net. fr. 172800 IN NS e.ext.nic.fr. fr. 172800 IN NS d.nic.fr. fr. 172800 IN NS g.ext.nic.fr. fr. 172800 IN NS d.ext.nic.fr. fr. 172800 IN NS f.ext.nic.fr. ratp.fr. 172800 IN NS indom30.indomco.fr. ratp.fr. 172800 IN NS indom10.indomco.com. ratp.fr. 172800 IN NS ns1.ratp.fr. ratp.fr. 172800 IN NS ns0.ratp.fr. www.ratp.fr. 300 IN NS lbns1.ratp.fr. www.ratp.fr. 300 IN NS lbns2.ratp.fr. > > > On the other hand, it fails here, where a broken name server replies > NXDOMAIN for an ENT: > > % ./zonecut -q=1 -v cdn.cdn-tech.com.c.footprint.net > Searching 1 for cdn.cdn-tech.com.c.footprint.net. > > Zone cut at "." > Querying type 2 for name net. at server k.root-servers.net > Result for "net.": Referral(s) > > Zone cut at "net." > Querying type 2 for name footprint.net. at server m.gtld-servers.net. > Result for "footprint.net.": Referral(s) > > Zone cut at "footprint.net." > Querying type 2 for name c.footprint.net. at server ns105.footprint.net. > Result for "c.footprint.net.": Referral(s) > > Zone cut at "c.footprint.net." > Querying type 2 for name com.c.footprint.net. at server > D.ns.c.footprint.net. > Error in retrieving the intermediate result: "NXDOMAIN" [family.redbarn:amd64] dig +trace cdn.cdn-tech.com.c.footprint.net | awk '$4 ~ "(CNAME|NS)$" {print}' . 37518 IN NS d.root-servers.net. . 37518 IN NS l.root-servers.net. . 37518 IN NS m.root-servers.net. . 37518 IN NS j.root-servers.net. . 37518 IN NS a.root-servers.net. . 37518 IN NS e.root-servers.net. . 37518 IN NS c.root-servers.net. . 37518 IN NS b.root-servers.net. . 37518 IN NS g.root-servers.net. . 37518 IN NS k.root-servers.net. . 37518 IN NS h.root-servers.net. . 37518 IN NS i.root-servers.net. . 37518 IN NS f.root-servers.net. net. 172800 IN NS m.gtld-servers.net. net. 172800 IN NS j.gtld-servers.net. net. 172800 IN NS i.gtld-servers.net. net. 172800 IN NS a.gtld-servers.net. net. 172800 IN NS b.gtld-servers.net. net. 172800 IN NS g.gtld-servers.net. net. 172800 IN NS c.gtld-servers.net. net. 172800 IN NS f.gtld-servers.net. net. 172800 IN NS k.gtld-servers.net. net. 172800 IN NS h.gtld-servers.net. net. 172800 IN NS d.gtld-servers.net. net. 172800 IN NS e.gtld-servers.net. net. 172800 IN NS l.gtld-servers.net. footprint.net. 172800 IN NS ns100.footprint.net. footprint.net. 172800 IN NS ns101.footprint.net. footprint.net. 172800 IN NS ns102.footprint.net. footprint.net. 172800 IN NS ns103.footprint.net. footprint.net. 172800 IN NS ns105.footprint.net. c.footprint.net. 86400 IN NS C.ns.c.footprint.net. c.footprint.net. 86400 IN NS D.ns.c.footprint.net. c.footprint.net. 86400 IN NS E.ns.c.footprint.net. c.footprint.net. 86400 IN NS F.ns.c.footprint.net. c.footprint.net. 86400 IN NS A.ns.c.footprint.net. c.footprint.net. 86400 IN NS B.ns.c.footprint.net. c.footprint.net. 86400 IN NS b.ns.c.footprint.net. c.footprint.net. 86400 IN NS us-ca-4.ns.c.footprint.net. c.footprint.net. 86400 IN NS e.ns.c.footprint.net. c.footprint.net. 86400 IN NS us-wa-1.ns.c.footprint.net. > > > You're welcome to test it on many domains and to report interesting > results (you can use the Github issues system > <https://github.com/bortzmeyer/my-IETF-work/issues>) i applaud this work. as i said at the dns-oarc meeting in poland last year, q-m will allow negative caching of nonexisting labels, which can in turn protect the authority servers (in aggregate) against some forms of random-subdomain ddos reflection/amplifier attacks. when ".foo" does not exist, you don't have to ask whether "bar.foo" exists, and so on. for the record i think the q-m patent is foolishness, and not merely because of "dig +trace". this patent should never have been granted, on the basis of obviousness. verisign ought to place it in "royalty free" status rather than face risk of embarrassment when the community works together to have it invalidated. dns is not a zero sum game. -- Paul Vixie
_______________________________________________ DNSOP mailing list DNSOP@ietf.org https://www.ietf.org/mailman/listinfo/dnsop