メモ的ななにか

@Maleic1618

RFC 7873: Domain Name System (DNS) Cookies (Part 1)

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

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

qiita.com

今回はDNSトランザクションのセキュリティを強化する、DNS Cookiesを説明します。

RFC 7873 - Domain Name System (DNS) Cookies

概要

DNSトランザクション管理は主にUDPのSource PortとDNS HeaderのIDで行われます。 これらが一致すると正規の応答と判断されるため、それを利用した第1フラグメント便乗攻撃だったり、サイドチャネル攻撃でsource portを推測する攻撃(SAD DNS)などが考案されるわけです。

今回はこれらに追加でトランザクションを管理するためにwebのcookieと同じように、DNSのクエリ/レスポンスにもcookieを持たせる仕組みです。図があると分かりやすい気がしたので今回も図を作りました。

f:id:maleic1618:20201209024931p:plain

clientが生成したclient cookieとserver側が生成したserver cookieを常にクエリ/レスポンスそれぞれに入れながら通信を行います。 以前発行したものと異なるcookieが返ってきたり、そもそもcookieが返ってこない場合は不正な応答としてdiscardされます。

f:id:maleic1618:20201209025120p:plain

ちなみにEDNS0のRFC6891を読むと、6.1.2に知らないオプションは無視するようになっています。

レスポンダーまたはリクエスターに理解されないオプションコード値はどれも無視されなければならない(MUST)。

つまり、DNS cookieに対応していないサーバとは一生通信できません。(多分) そのため、DNS Cookiesを利用していることを前提と出来るrootやTLD限定で利用するもの、と考えた方が良さそうです。

今回の記事ではwire formatとcookie生成の方法について触れます。

wire format

OPT RRのオプションとして{client,server} cookieを通知します。 client cookieは8bytes, server cookieは8-32bytesのバイナリで、通信するときは

  • client cookieだけを送信する
  • client, serverのどちらのcookieも送信する

のどちらかで送信します。

client cookieだけを送信するときは以下のようなoptionを使います。

                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |        OPTION-CODE = 10      |       OPTION-LENGTH = 8        |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +-+-    Client Cookie (fixed size, 8 bytes)              -+-+-+-+
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

client + server cookieを送信するときは以下のようなoptionを使います。 Server cookieは可変長ですがclient cookieは8bytes固定なので、option-lengthからserver cookieの長さが分かります。

                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |        OPTION-CODE = 10      |   OPTION-LENGTH >= 16, <= 40   |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +-+-    Client Cookie (fixed size, 8 bytes)              -+-+-+-+
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    /       Server Cookie  (variable size, 8 to 32 bytes)           /
    /                                                               /
    +-+-+-+-...

Cookieの生成について

クライアント、サーバはそれぞれ以下の要素とランダムなsecretからランダム関数を使ってcookieのバイナリ列を生成します。 今のところはFNV64やHMAC-SHA256-64などを使うことを想定しているようです。

生成元
クライアント クライアントのIPアドレス、サーバのIPアドレス
サーバ クライアントのIPアドレスclient cookie

client cookieの生成元にクライアントのIPアドレスが含まれているのは、クライアントのIPアドレスがどんどん変わっていくような状況にtrackingされないようにするためです。

またserver cookieの生成元にclient cookieが含まれているのはNAT環境をケアするためです。 クライアントのIPアドレスとsecretだけでserver cookieを生成すると、同一のNAT配下からのクエリは(全て同一IPからクエリが飛ぶため)同じserver cookieになってしまい、攻撃者がNAT配下にいた場合はServer cookieを取得することが出来てしまうわけですね。

明日のpart 2では、DNS cookies対応のServer, Clientがどのようにクエリ, レスポンスを処理するかに触れます。