メモ的ななにか

@Maleic1618

RFC 8482: Providing Minimal-Sized Responses to DNS Queries That Have QTYPE=ANY

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

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

qiita.com

今回はクエリタイプ "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つの対応方法が用意されました。

  1. QNAMEに対応するRRsetを部分的に返す
  2. HINFO RRを返す
  3. クライアントが欲しがっていそうなものを返す

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