メモ的ななにか

@Maleic1618

RFC 7816: DNS Query Name Minimisation to Improve Privacy

こんにちは、まれいんです。

この記事は ひとりRFCの旅 Advent Calender 11日目の記事です。

qiita.com

本日はDNSのプライバシーをケアするために提案されたQNAME minimisationについて書かれた、RFC7816を読んでいきます。

概要

DNSは委任によってゾーンを"分割統治"することで成立するプロトコルです。

例えば example.com. ゾーンにある foo.bar.example.com. 名前解決しようとすると、以下のような通信が生じます。

f:id:maleic1618:20201208004719p:plain

(ちなみに図の「スタブリゾルバ」は全然スタブじゃないのですが、修正するのがつらいので脳内で置換をお願いします。)

しかし、このようにすると ., com., example.com. のすべての権威サーバに 「foo.bar.example.com. を解決しようとしている」ということが伝わってしまいます。

再帰解決で各権威サーバを巡るとき、最小限のクエリ名でクエリを投げるようにすることで、不要なデータを権威サーバに送らないようにするのが、このQNAME minimisationという仕組みです。

QNAME minimisation

百聞は一見に如かずということで、こちらにも対応するシーケンス図を作っておいたので最初に張っておきます。

f:id:maleic1618:20201208004437p:plain

この図ではルートゾーンから1つずつラベルを増やしながらNSを確認しています。 これによってどこにゾーンカットがあるのかが分かるので、クエリ名を権威を持たないサーバに送信しないようにすることができます。

そして、bar.example.com. までくれば、foo.bar.example.com. の権威を確実に持っている権威サーバが決まるので、ここで初めて元々のクエリタイプであるAレコードを聞きます。

障害

悲しいことに権威サーバの不正な実装のせいで、上記のように解決しようとするとうまく引けない場合があるようです。 というわけで紹介。

NSが引けない

AやAAAAは普通に引けるのに、NSだけは引けないサーバがいるようです。 (間にいるLBが勝手にREFUSEDを返したりするらしい)

とはいえ、クエリタイプにNSではなくAを使っても、ゾーンカットが途中にあればNSが返ってくるわけなのでこれで代用することが可能です。

Empty Non-Terminals にNXDOMAINを返す

自身はリソースレコードを持たないが、サブドメインは持つ、というドメインのことを Empty Non-terminals と言いました。

このドメイン名に対して名前解決をするときは当然NODATAが返ってくるべきなのですが、ものによってはNXDOMAINが返ってくるようです。 途中でNXDOMAINを返されてしまうと、それより下にはドメイン名が存在しないわけですから、オリジナルのドメイン名も不在ということになってしまいます。

一応、「NXDOMAINが返ってきたときは通常通りの方法でretryする」というので回避できますが(Knotがそういう実装らしい)、プライバシー的には意味がなくなるよねということでぐぬぬ...となっているようです。

メリット

ぱっと見だとQNAME minimisationは余計なクエリが増えがちなように見えますが、実はそうでないパターンがあります。

QNAME minimisationだとクエリ名が不在なときでも、どこまで存在していて、そこから存在しないのかがきっちりわかります。 これにより、普通に解決した場合では得られない情報をキャッシュすることができます。

例えば example. ドメインが存在しない状況で A.example., B.example., C.example. をまとめて解決したいとします。 この時、普通にやると3つそれぞれ解決しなくてはいけませんが、QNAME minimisationをすると、example. の不在が分かるので、1つのクエリだけで3つすべてのドメインの不在を示せます。

もう一つの利点は限定的ですが、TLDの権威サーバで解決するときに常に2ラベルのクエリが飛ぶため、基本的に委任しかしないTLDにとっては解決に最適化されるようになるというものです。(TLDに限らず、委任onlyなゾーンの権威サーバであっても同様)

デメリット

当たり前ですが、途中にゾーンカットがない、長いサブドメインについては無駄に通信することになるため基本的に損になります。

例えば example. ゾーンにある super.ultra.hyper.miracle.example. を解決しようとすると...

f:id:maleic1618:20201208012301p:plain

と、無駄なやり取りが多量に発生してしまいます。