RFC 8482: Providing Minimal-Sized Responses to DNS Queries That Have QTYPE=ANY
こんにちは、まれいんです。
この記事は ひとりRFCの旅 Advent Calender 14日目の記事です。
今回はクエリタイプ "ANY" についてのRFC、RFC8482を読んでいきます。
RFC 8482 - Providing Minimal-Sized Responses to DNS Queries That Have QTYPE=ANY
概要
RFC1035ではクエリで指定できるタイプとして *
が存在していました。(俗にANYクエリなどと呼ばれる)
3.2.3. QTYPEの値 QTYPEフィールドは、問い合わせの問い合わせ部に現れる。QTYPEはTYPEのスーパー セットであるから、TYPEの値はすべてQTYPEでも有効である。それに加えて、 以下のQTYPEが定義される。 ... * 255 全レコードのリクエスト
このタイプでクエリを発行すると、対応するクエリ名の全リソースレコードを返すことになっていました。
これはデバッグだったり、複数種類のリソースレコード(例えばMX, A, AAAA)をまとめて取得するときのために使われていたのですが、amp攻撃の増幅率を増やすためだったり、権威サーバの情報を漁るために使われるようになってきました。
ちなみに増幅率はこんな感じ。(edns buffer sizeを4096とかで放置するのはやめましょう!!!)
$ dig . any @8.8.8.8 ; <<>> DiG 9.16.8-Debian <<>> . any @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41486 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 21, AUTHORITY: 0, ADDITIONAL: 1 ^^^^^^^^^^ ... ;; MSG SIZE rcvd: 2015 ^^^^^^^^^^
これはよろしくないということで、ANYクエリの新たな対処方法を定めたのがこのRFCです。
ちなみに権威サーバ側に限った話だと思います。多分。
対応方法
このRFCでは以下の3つの対応方法が用意されました。
- QNAMEに対応するRRsetを部分的に返す
- HINFO RRを返す
- クライアントが欲しがっていそうなものを返す
1. QNAMEに対応するRRsetを部分的に返す
対応するQNAMEのリソースレコードを全部ではなく一部だけ返します。 ちなみに返すレコードが署名されているのであれば、対応するRRSIGを必ず含めて返します(MUST)
分かりやすい解決策ですが、部分的に返していることを通知できないのが難点です。
2. HINFO RRを返す
HINFOリソースレコードを使って通知する方法です。
HINFOはRFC1035で定義されたホスト情報を返すためのリソースレコードで、RDATA部はCPU, OSの2つの文字列フィールドからなります。
全リソースレコードを返す代わりに、CPUフィールドに "RFC8482" と書いたHINFOリソースレコードを返します。
cloudflareがこれを実装しているみたいです。
$ dig cloudflare.com any @8.8.8.8 +dnssec ... ;; ANSWER SECTION: cloudflare.com. 3788 IN HINFO "RFC8482" "" cloudflare.com. 3788 IN RRSIG HINFO 13 2 3789 20201211212107 20201209192107 34505 cloudflare.com. tJdOL86xOwnh7zmZAk4eLLlj4PLGGARqZSylfpc7AnmobwwDxYMo2tOd rR2p0mF0s6XoF6pVcBEl94LC5W8SXg==
HINFOを使っている場合だと、本来と違うリソースレコードが返ってしまうのでよろしくないのですが、ほぼほぼ使われていないので問題ないっしょ!ということのようです。
3. クライアントが欲しがっていそうなものを返す
クライアントが欲しがってそうなものを返します。
これは元々は一部でそのような実装があったとのことで、全リソースレコードのうちMX, A, AAAA, CNAMEだけを返すなどの挙動を想定しているようです。
TXTやDNSKEYは乗らないので、応答サイズはある程度抑えられますが、1, 2よりは増えてしまうところが難点です。
その他
一応これでANYクエリについては対応が出来ました。
...が、増幅率が高めのクエリタイプがまだあります。RRSIGです。
単純にリソースレコードあたりのサイズが大きいので、数が少なくてもなかなかのサイズになります。
$ dig . rrsig @8.8.8.8 ; <<>> DiG 9.16.8-Debian <<>> . rrsig @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52887 ;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1 ^^^^^^^^^ ;; MSG SIZE rcvd: 1172 ^^^^^^^^^^
このRFCではRRSIGについては何も定めていませんが、今後定める必要があるかもね...とのことでした。
ちなみにcloudflareはクエリタイプをRRSIGにすると何も答えてくれません。
$ dig cloudflare.com a @8.8.8.8 +dnssec +noall +answer +comments ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6454 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ;; ANSWER SECTION: cloudflare.com. 277 IN A 104.16.132.229 cloudflare.com. 277 IN A 104.16.133.229 cloudflare.com. 277 IN RRSIG A 13 2 300 20201211213513 20201209193513 34505 cloudflare.com. eh4o/AKJ0L0zxoPPtvwzo2+IaBk5gOv7V+uuL5zuIK2gei1WJYL5opY+ Jj14YMQ1gv1RaS0ievyzPfbcWbWJ0Q== $ dig cloudflare.com rrsig @8.8.8.8 +dnssec +noall +answer +comments ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 58769 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512