AQ Tech Blog

DNSSECの基礎を理解して、実際のレコードを確認してみた

作成者: tsuyoshi.watanabe|2023年12月16日

本記事はAsiaQuest Advent Calendarの16日目です。

はじめに

クラウドインテグレーション部の渡邊です。
今回は、DNSSECついて説明します。

偽のDNS情報をキャッシュさせる、DNSキャッシュポイズニングに対する根本的な解決策として、DNSSECがあります。
DNSSECにより、偽装や改ざんをキャッシュサーバで確認することで、キャッシュポイズニング攻撃を防ぐことができます。
今回は、そのDNSSECの仕組みを説明するとともに、実際のDNSSECのレコードを確認します。
また、仕組みを説明するにあたって、DNSSECで利用される公開鍵暗号技術を用いた、電子署名についても説明します。
DNSSECはセキュアなイメージがありますが、通信内容の暗号化は対象範囲としていないため、誤認しないように注意してください。

対象としていないもの
– 通信内容の暗号化
通信内容を暗号化し、問い合わせ内容を秘匿すること

引用元:DNSSECの基礎概要 , JPNIC , p 12

DNSSECの仕組み

DNSSECは受け取ったDNSレコードの出自・完全性を検証する仕組みです。
検証を実現するために、電子署名の仕組みを使います。
そのため、まずは電子署名の仕組みを部分的に説明します。


受信者側視点の電子署名の仕組み

電子署名によって、正しい送信者から、改ざんされていないメッセージを受信したことを確かめることができます。
その過程を、受信者側の立場から説明します。

  1. 受信者側が①、②を受け取る。
  • ①電子署名
  • ②メッセージ ※電子署名は送信者の秘密鍵によって、ハッシュ化したメッセージを暗号化したものです。
  1. それぞれをハッシュ化されたメッセージにした際に、同一であることを受信者側で比較する。
  • 送信者の公開鍵で復号化した① = ハッシュ化したメッセージ
  • ②をハッシュ化させたもの = ハッシュ化させたメッセージ

この過程で、以下2つのことがわかります。

  • 公開鍵で復号できたことで、正しい送信者が暗号化した。(出自の検証)
  • ハッシュ化したメッセージが一致したことで、改ざんがされていない。(完全性の検証)

※出自の検証に関しては、公開鍵が不正ではない前提です。


DNSSECの仕組み

本仕組みを説明するにあたり、複数のレコードが登場するため、下表にまとめます。 混乱しそうになったら、こちらをご参照ください。

本記事で登場するレコード一覧 説明
DNSKEY 公開鍵の情報(ZSK・KSK)
RRSIG 各RRsetへの署名
DS KSK公開鍵のハッシュ値を含む情報
KSK ゾーン内の公開鍵情報に署名するための鍵
ZSK ゾーンに署名するための鍵


DNS応答の出自および完全性を検証する

DNS応答に含まれるレコードを検証するために、電子署名の仕組みで登場した①、②を以下に置き換えて考えてみましょう。

  • ①電子署名=RRSIGレコード
  • ②メッセージ=Aレコード

電子署名と同様に、メッセージ(Aレコード)をハッシュ化したものを電子署名と比較することで、出自および完全性を検証できることがわかるかと思います。

  • ゾーンの管理者の公開鍵(DNSKEY)で復号した① = ハッシュ化したメッセージ
  • ②をハッシュ化させたもの = ハッシュ化させたメッセージ

DNSKEYの出自および完全性を検証する(信頼の連鎖)

しかし、前項で説明した仕組みのみでは、検証として不十分です。 なぜなら、検証に使用した公開鍵が、偽装される可能性があるためです。 以下の場合においても、DNS応答の検証が成立してしまいます。

  1. 受信者側が①、②を受け取る。
  • ①電子署名
  • ②メッセージ ※電子署名は偽のゾーンの管理者の秘密鍵によって、ハッシュ化したメッセージを暗号化したものです。
  1. それぞれが、ハッシュ化されたメッセージとして同一であることを受信者側で比較する。
  • 偽のゾーンの管理者の公開鍵で復号化した① = ハッシュ化したメッセージ
  • ②をハッシュ化させたもの = ハッシュ化させたメッセージ

よって、公開鍵が改ざんされていない(正規のものである)ことを確認するために、電子署名の仕組みで登場した①、②を以下に置き換えて考えてみましょう。

  • ①電子署名 = DSレコード
  • ②メッセージ = ゾーンの管理者の公開鍵(DNSKEYKSK))

電子署名の仕組みに習い、電子署名(DS)を復号したものと、公開鍵(KSK)をハッシュ化したものが一致することを検証します。
このような公開鍵の出自の検証が、信頼するゾーンまで行われることで、安心して所定のゾーンに対して連鎖的に検証を行うことができます。

参考:DNSSECチュートリアル~実践編~ p48など

このように、DNS応答の検証や信頼の連鎖は、電子署名の仕組みを利用していることがわかりますね。

環境情報

  • iTerm2
  • macOS 13.4

実際のDNSSECのレコードを確認してみた

ここではexample.comを対象に、各レコードの役割を確認してみます。


RRSIGレコード

まずは、RRSIGレコードを確認します。

$ dig example.com rrsig +dnssec

; <<>> DiG 9.10.6 <<>> example.com rrsig +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 21090
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;example.com. IN RRSIG

;; ANSWER SECTION:
example.com. 86393 IN RRSIG DS 8 2 86400 20231101062027 20231025051027 63246 com. TByGwUQGI7RzOULRGS3+oygUH9NoEhRC6yvb5wj7S/DQ+IKqmeWFYc1/ 9KhI4ms5TLJ/tqBiY1t3U2ANBIzSiyA9J4+CjsVWz8ChRNB+QVowYtjp A+f93RoQMlojFED0eUVgtgqtq0hrH5NM33th6buYpaopaZcQsf7NyWir sI/glveUxxP66RxjvXMg6xn2sPgwkhObvHwCtWxjAT+oIw==
example.com. 3578 IN RRSIG DNSKEY 13 2 3600 20231109195516 20231019095303 370 example.com. hhp9JzDjRhwFfkcS86h9udm3uv1QQRTmpWuvSQUeK+yzqqxMMxvN4Nbk khv+EPifYJDzF3TPyfvr+S2uyk9wKQ==
example.com. 84860 IN RRSIG NS 13 2 86400 20231109002917 20231019095303 2182 example.com. LhezD+LGEtT667lJ7RfRsi0sRB7Z0Ph4zHP7vGozUSHC/5o0melNv++W NAfI5A2nlPmX7VnMNPWNK4VhF70y2g==
example.com. 80913 IN RRSIG A 13 2 86400 20231108232841 20231019095303 2182 example.com. 3YtLrbIPwD2IeeWBtZcASMoBgDkU36y33Nah06DVt2R3WEFDkRrxHj7Z uNO5WNYD58XkBFgH92PTldXDgja5Yg==
example.com. 61475 IN RRSIG AAAA 13 2 86400 20231109083640 20231019095303 2182 example.com. +gTOtrAUavFeGe/u+Wfhc7Nw8AZu2W6ciZLxBgbjXjEwpZgroWGrg2P5 YK665A1BrDWLpOLQBYOuaaa1Xh36pg==

;; Query time: 9 msec
;; SERVER: 118.238.201.33#53(118.238.201.33)
;; WHEN: Fri Oct 27 16:29:41 JST 2023
;; MSG SIZE rcvd: 663

その中の、以下のレコードに注目します。

example.com.            80913   IN      RRSIG   A 13 2 86400 20231108232841 20231019095303 2182 example.com. 3YtLrbIPwD2IeeWBtZcASMoBgDkU36y33Nah06DVt2R3WEFDkRrxHj7Z uNO5WNYD58XkBFgH92PTldXDgja5Yg== → AレコードをZSKで電子署名したもの

RRSIGレコードの説明前に、言及するフィールドを表に示します。

フィールド名 フィールド値 説明
鍵タグ(Key Tag) 2182 署名検証するDNSKEYレコードの鍵のID
署名(signature) 3YtL(中略)5Yg== Base64で符号化した電子署名

RRSIGには、リソースレコードに対する電子署名が格納されています。
以上で示したレコードの場合は、DNSKEYZSK)による、Aレコードの電子署名です。
また、署名検証で使用する公開鍵を特定するために、鍵タグ(Key Tag)を指定します。

以下を比較することでDNS応答を検証します。

  • AレコードをZSKで電子署名したもの(3YtL(中略)5Yg==)を復号したもの
  • Aレコードのハッシュ値

(②に関しては、正確にはRRSIGの署名以外の部分 + 署名対象のAレコードのデータ から得られるハッシュ値で比較します)
ZSKは次の項で確認します。


DNSKEYレコード

公開鍵が含まれるDNSKEYZSKKSK)を確認します。

$ dig example.com dnskey +dnssec

; <<>> DiG 9.10.6 <<>> example.com dnskey +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13224
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;example.com. IN DNSKEY

;; ANSWER SECTION:
example.com. 3600 IN DNSKEY 256 3 13 /nRLBtx2AgW9shSZR4QVW6N3r0+tHCjiHc4gnlmY1VXggS0fiSfjsrkF OCZFGHrQWFlG839iIV7ToSFk0wRvOw==
example.com. 3600 IN DNSKEY 256 3 13 PAwmimrmweQdmio2mmVkbWI8HWyLv9ddPbUPuulE2Jf+Pc3DNTP0xwKm eSCgAeinSLZb8MKIMhcxL6Qt20L4Dg==
example.com. 3600 IN DNSKEY 257 3 13 kXKkvWU3vGYfTJGl3qBd4qhiWp5aRs7YtkCJxD2d+t7KXqwahww5IgJt xJT2yFItlggazyfXqJEVOmMJ3qT0tQ==
example.com. 3600 IN RRSIG DNSKEY 13 2 3600 20231109195516 20231019095303 370 example.com. hhp9JzDjRhwFfkcS86h9udm3uv1QQRTmpWuvSQUeK+yzqqxMMxvN4Nbk khv+EPifYJDzF3TPyfvr+S2uyk9wKQ==

;; Query time: 206 msec
;; SERVER: 118.238.201.33#53(118.238.201.33)
;; WHEN: Fri Oct 27 16:29:19 JST 2023
;; MSG SIZE rcvd: 387

レコードに注目すると複数のZSK、単一のKSKRRSIGがあります。
複数ZSKがありますが、各鍵タグの値を求めることで、一致するものが1つに決まるため、複数あっても問題ありません。
こちらのZSKを使用して、Aレコードの検証を行います。
また、KSKを検証することで、署名されたZSKは信頼できるものであることがわかります。
こちらの検証を実現するために、親レコードに登録しているDSKSKのハッシュ値)を利用します。
DSレコードは次の項で確認します。
なお、公開鍵フィールドはRFC3110を確認すると、指数長、指数、モジュラスで構成されております。
公開鍵フィールドを使用して、そのまま暗号化したデータを復号することができない点に注意してください。

example.com.            3600    IN      DNSKEY  256 3 13 /nRLBtx2AgW9shSZR4QVW6N3r0+tHCjiHc4gnlmY1VXggS0fiSfjsrkF OCZFGHrQWFlG839iIV7ToSFk0wRvOw== → ZSK
example.com. 3600 IN DNSKEY 256 3 13 PAwmimrmweQdmio2mmVkbWI8HWyLv9ddPbUPuulE2Jf+Pc3DNTP0xwKm eSCgAeinSLZb8MKIMhcxL6Qt20L4Dg== → ZSK
example.com. 3600 IN DNSKEY 257 3 13 kXKkvWU3vGYfTJGl3qBd4qhiWp5aRs7YtkCJxD2d+t7KXqwahww5IgJt xJT2yFItlggazyfXqJEVOmMJ3qT0tQ== → KSK
example.com. 3600 IN RRSIG DNSKEY 13 2 3600 20231109195516 20231019095303 370 example.com. hhp9JzDjRhwFfkcS86h9udm3uv1QQRTmpWuvSQUeK+yzqqxMMxvN4Nbk khv+EPifYJDzF3TPyfvr+S2uyk9wKQ== → KSKによって署名されたZSK


DSレコード

最後にDSレコードを確認します。

$ dig example.com ds +dnssec

; <<>> DiG 9.10.6 <<>> example.com ds +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3151
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;example.com. IN DS

;; ANSWER SECTION:
example.com. 86400 IN DS 370 13 2 BE74359954660069D5C63D200C39F5603827D7DD02B56F120EE9F3A8 6764247C
example.com. 86400 IN RRSIG DS 8 2 86400 20231101062027 20231025051027 63246 com. TByGwUQGI7RzOULRGS3+oygUH9NoEhRC6yvb5wj7S/DQ+IKqmeWFYc1/ 9KhI4ms5TLJ/tqBiY1t3U2ANBIzSiyA9J4+CjsVWz8ChRNB+QVowYtjp A+f93RoQMlojFED0eUVgtgqtq0hrH5NM33th6buYpaopaZcQsf7NyWir sI/glveUxxP66RxjvXMg6xn2sPgwkhObvHwCtWxjAT+oIw==

;; Query time: 8 msec
;; SERVER: 118.238.201.33#53(118.238.201.33)
;; WHEN: Fri Oct 27 16:29:34 JST 2023
;; MSG SIZE rcvd: 283

信頼の連鎖は、以下を比較することで検証します。

  • 親管理のDSレコード
  • 子が管理しているKSKレコードのハッシュ値

これらを比較することで、子が管理しているKSKの出自の証明ができます。

example.com.            86400   IN      DS      370 13 2 BE74359954660069D5C63D200C39F5603827D7DD02B56F120EE9F3A8 6764247C → KSKのハッシュ値

まとめ

  • DNS応答の検証や信頼の連鎖は、電子署名の仕組みを利用しています。
  • DNSSECによって以下を検証できます。
    • 完全性の検証
    • 出自の検証
  • ただし、上の検証で使用する公開鍵は子ゾーンが管理しているものであることを確認するために、信頼の連鎖を形成します。

【参考】

DNSSECにおけるZSKの役割

初歩から解説!BINDでシンプルDNSサーバー構築【構築編】

DNSSEC

手を動かしてDNSSECの検証をやってみよう

DNSSECチュートリアル ~実践編~