DNSフルリゾルバの実装への DNSSEC の組み込み – DNSSEC と反復検索

2024年04月24日 水曜日


【この記事を書いた人】
日比野 啓

技術研究所技術開発室で DNS 関連の開発を行なっています。最近、とくに重点的に取り組んでいるのは DNSフルリゾルバおよび DNSSEC の研究開発実装です。

「DNSフルリゾルバの実装への DNSSEC の組み込み – DNSSEC と反復検索」のイメージ

研究開発中のフルリゾルバ実装の実用性を向上する目的で、 DNSSEC検証機能を実装しました。
反復検索と DNSSEC の関係について説明した後に実装について紹介します。

ゾーンの階層とフルリゾルバの反復検索

DNSでは、ドメイン名全体が成す木構造を分散して管理します。
上位から下位へと部分木の管理を委任することで、管理を分割します。
この管理単位をゾーン(zone)と呼びます(図: ゾーンの階層)。

図: ゾーンの階層

ゾーンは上位から下位へ、委任情報によって紐付けられます。
委任情報は、委任先のゾーンの権威サーバの情報1を提供します。

名前解決を必要とするクライアントアプリケーションの要求を直接処理するのがDNSフルリゾルバの役割です。
フルリゾルバは委任情報を辿りながらゾーンの階層に沿って解決を行います。これを反復検索と言います。

以下(図: 反復検索)は iij.ad.jp の A レコードを解決する例です。

図: 反復検索

名前解決の結果は、ドメイン名と(A, NS といった)タイプに対して決まります。
結果のリソースレコード(RR)2が存在するとき、それが一つとは限らず複数存在することがあります。
ドメイン名とタイプに対して決まる、空でない RR の集合を RRset と言います。

 

反復検索と DNSSEC の認証の連鎖

DNSSECで検証することができるのは、次の 2種類です。

(1)
上位ゾーンから下位ゾーンへのDNSSECで署名されているゾーンへの委任が存在すること(2024/04/30:下線部分を追記)
(2)
ゾーンを管理する権威サーバから返答される RRset が正しいこと

DNSSEC検証をともなう反復検索では、この 2種類の検証を “.” ゾーンから繰り返し、連鎖を確認することで、最終的な返答内容の正しさを確認します。
これは認証の連鎖3と呼ばれます。

DNSSEC検証を行なうための RR として、DNSKEY、DS(Delegation Signer)、RRSIG があります。
DNSKEY は公開鍵の情報を格納し、RRsetに対する署名を格納する RRSIG とともに利用することで、RRset を署名検証することができます。DS は DNSKEY のダイジェスト値を格納し、上位のゾーンに登録されます。

(1)の委任の存在を検証するために必要な RR は DS と DNSKEY です。
委任先ゾーンが DNSSEC で署名されている場合、委任元から返る委任情報には DS RR が含まれています
(委任先ゾーンが未署名の場合には、DS RR は有りません。その場合には認証の連鎖は途切れることになり、最終的な返答内容を検証することはできなくなります)。

委任先ゾーンの DNSKEY RR のうち、そのダイジェスト値が、委任情報の DS RR と一致するものがあれば、DNSSECで署名されているゾーンへの委任が存在することになります(2024/04/30:下線部分を追記)
ダイジェスト値が一致する DNSKEY を SEP(Secure Entry Point)と言います(図: 委任とDNSSEC)。
委任元に DS があるにもかかわらず、SEP が見つからない場合は検証失敗です。

(2)の返答される RRset が正しいことを検証するために必要な RR は DNSKEY と RRSIG(RRset の署名値) です。
委任先ゾーンの DNSKEY RRset の署名を SEP DNSKEY で検証することで、DNSKEY RRset が正しいことが確認できます。
ここまでで、委任先の権威サーバから返る RRset が正しいかを確認できる準備ができたことになります。
なぜならば、ゾーン内の RRset は DNSKEY RRset 内のいずれかの DNSKEY で署名検証できるためです。
これは、DS RRset についても同様で、さらに下位の署名されているゾーンへ委任がある場合、その委任情報に含まれる DS RRset の署名を検証することができます(図: 委任とDNSSEC)。

図: 委任とDNSSEC

 

フルリゾルバ実装 bowline の反復検索への DNSSEC の組み込み

我々はプログラミング言語HaskellでDNSライブラリ群dnsext4
bowlineという名前のフルリゾルバを開発56しています。

今回、dnsextライブラリにDNSSEC検証7の機能を実装し、フルリゾルバの反復検索にその検証機能を組み込みました

反復検索への組み込みでは、具体的には委任の処理に以下の手順を組み込みます。

  1. 委任情報を取得
  2. 委任元 DNSKEY で DS の署名を検証
  3. 委任先 DNSKEY を取得
  4. 委任元 DS と 委任先 DNSKEY を照合して委任先 SEP DNSKEY を決定
  5. 委任先 SEP DNSKEY で DNSKEY の署名を検証

もともと委任情報は次のようなデータ型だと考えることができます。

data Delegation =
data Delegation =
  Delegation
  { delegationZone    :: Domain       {- 委任先ゾーン頂点 -}
  , delegationNS      :: [DEntry]     {- NS と A/AAAA のリスト -}
  }

これを次のようなデータ型に拡張します。
委任情報に含まれる DS と、委任先の DNSKEY RRset を保持できるようになり、DNSSEC 付きの反復検索を実現できます。

data Delegation =
  Delegation
  { delegationZone    :: Domain       {- 委任先ゾーン頂点 -}
  , delegationNS      :: [DEntry]     {- NS と A/AAAA のリスト -}
  , delegationDS      :: [RD_DS]      {- 委任元 DS RRset -}
  , delegationDNSKEY  :: [RD_DNSKEY]  {- DS による SEP の照合、SEP による署名検証済みの DNSKEY RRset -}
  }

反復検索で得られた、最終的な委任先が DNSSEC 署名されている場合には、そのゾーンの DNSKEY で、結果の RRset を署名検証することができます。
ここまでで、肯定的な応答に対する DNSSEC の検証が完了します。なお、DNSSEC の否定応答については、別途記事を執筆しています。

署名検証を行なう際には、RRsetのワイヤーフォーマットの正規形を再計算し、正規順序に並び換える必要があります。
当初の実装では、この正規順序の並び換え時に、RR の可変データ部の長さを含めてしまうバグ8がありました。
複数の NS の名前の長さが同じゾーン(ex. {ns1,ns2,ns3}.example.com.)では再現しない問題のため、気付きにくいバグとなっていました。

最後に、検証用に用意したdugコマンド9を紹介します。

dug は bind9 付属の dig コマンドと似た DNSクライアントのコマンドで、通常のテキスト出力の他にJSON出力に対応しています。
また、dig コマンドは DNS トランスポートとして、UDP、TCP、TLS、HTTP/2、HTTP/2(TLS無し)を利用できますが、dug はそれに加えて QUIC と HTTP/3 に対応しています。

さらに、bowlineで使われている反復検索アルゴリズムを使ってDNSを検索できます。これには‘-i’オプションを指定します。

以下が、www.iij.ad.jp. A への DNSSEC検証付き反復検索の実行例です。認証の連鎖が繋って、最終結果の署名検証が成功する様子が確認できます。

 % dug -v 1 -i www.iij.ad.jp. A +dnssec
...
root-priming: verification success - RRSIG of NS: "."
	"a.root-servers.net." [198.41.0.4,2001:503:ba3e::2:30]
	"b.root-servers.net." [170.247.170.2,2801:1b8:10::b]
	...
delegation - verification success - RRSIG of DS: "." -> "jp."
zone: "jp.":
	"a.dns.jp." [203.119.1.1,2001:dc4::1]
	"b.dns.jp." [202.12.30.131,2001:dc2::1]
	...
fillDelegationDNSKEY: query ("jp.",DNSKEY) servers: 210.138.175.244 2001:502:ad09::5
...
no delegation: "jp." -> "ad.jp."
...
delegation - verification success - RRSIG of DS: "jp." -> "iij.ad.jp."
zone: "iij.ad.jp.":
	"dns0.iij.ad.jp." [210.130.0.5,2001:240::105]
	"dns1.iij.ad.jp." [210.130.1.5,2001:240::115]
fillDelegationDNSKEY: query ("iij.ad.jp.",DNSKEY) servers: 210.130.1.5 2001:240::105
...
iterative: query ("www.iij.ad.jp.",A) servers: 210.130.0.5 2001:240::115
...
no delegation: "iij.ad.jp." -> "www.iij.ad.jp."
...
verification success - RRSIG of "www.iij.ad.jp." A
;; 41usec

;; HEADER SECTION:
;Standard query, NoError, id: 0
;Flags: Recursion Desired, Recursion Available


;; QUESTION SECTION:
;www.iij.ad.jp.		IN	A

;; ANSWER SECTION:
www.iij.ad.jp.	300(5 mins)	IN	A	202.232.2.180
www.iij.ad.jp.	300(5 mins)	IN	RRSIG	RD_RRSIG {rrsig_type = A, rrsig_pubalg = RSASHA256, rrsig_num_labels = 4, rrsig_ttl = 300(5 mins), rrsig_expiration = Fri, 19 Apr 2024 15:10:04 GMT, rrsig_inception = Wed, 20 Mar 2024 15:10:04 GMT, rrsig_key_tag = 54096, rrsig_zone = "iij.ad.jp.", rrsig_signature = \# 128 9c1fc9d353b3dae7269dde50051d737c94d31edbab0c1390406a5194b83813eb9a3d5c8d420cd2a57a94f3c1a8670271d81b51aa256b70309056f0319e55fe10b6d251fc08469a47e2ac613d712d90e5198cfeb1512295c32f6f6bb0498efb3d5c56ea9bbf1fbc0d1b2fdacc20ab8c4ea76cedb1f55782876315270a61b7dfb8}

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

 


  1. 委任情報には、委任先のゾーンの権威サーバの名前(NS)が含まれています。さらに、委任元から見て NS がサブドメイン名のときには、NS に対応する A あるいは AAAA レコードが委任情報に含まれます。これをグルー(glue)レコードと言います。委任元から見て NS がサブドメイン名でないときには、グルーが利用できないため、反復検索自身を再帰します。↩︎
  2. RFC 1034 section 3.6 – Resource Records↩︎
  3. RFC 4033 section 2 – Authentication Chain↩︎
  4. dnsextライブラリ群のレポジトリです(https://github.com/kazu-yamamoto/dnsext/)。↩︎
  5. フルリゾルバ実装については以前の記事[DNS の反復的な名前解決の仕組みとフルリゾルバの実装]をご覧ください。↩︎
  6. bowline の実装は dnsext内のサブディレクトリに置いています(https://github.com/kazu-yamamoto/dnsext/tree/main/dnsext-bowline/bowline/)。↩︎
  7. 検証機能のライブラリ実装については以前の記事 [DNSSECの基本的な検証機能とその実装]をご覧ください。↩︎
  8. https://github.com/kazu-yamamoto/dnsext/pull/129↩︎
  9. https://github.com/kazu-yamamoto/dnsext/tree/main/dnsext-bowline/dug/↩︎

日比野 啓

2024年04月24日 水曜日

技術研究所技術開発室で DNS 関連の開発を行なっています。最近、とくに重点的に取り組んでいるのは DNSフルリゾルバおよび DNSSEC の研究開発実装です。

Related
関連記事