6.4. DNSと暗号化

6.4.1. DNSの基本構造と概念

DNSの基礎構造

DNSとは

DNSはIPアドレスやその他のデータを保存し、名前によるクエリを可能にする階層型の仕組みのこと。
DNS サーバーはドメイン名のデータベースを保存し、ネットワーク内のクライアントからの DNS クエリに基づいてドメイン名を処理する。

DNSサーバの種類

DNSサーバには以下の種類がある。

  • マスタDNSサーバ(権威DNSサーバ)
    • ゾーンファイルを所有するDNSサーバ
    • A、AAAA、CNAME などのDNS名レコードを保持する
  • スレーブDNSサーバ(キャッシュDNSサーバ)
    • マスターDNSサーバのゾーン情報をコピーするDNSサーバ
    • ドメインに対する以前のクエリに基づいてキャッシュファイルを構築している

ドメインレジストラ

ドメインレジストラはパブリックゾーンのインターネットドメイン名の予約を管理する組織のこと。
レジストラは汎用トップレベル ドメイン (gTLD) レジストリまたは国コード トップレベル ドメイン (ccTLD) レジストリによって認定される必要がある。

ゾーンとレコード

DNSゾーンの種類

DNS構成はゾーンリソースレコードで構成される。
DNSゾーンの種類は以下の通り。

  • パブリックDNSゾーン
    • インターネットから参照できるゾーン
    • パブリックゾーンに DNS レコードを作成して、インターネット上にサービスを公開できる
  • プライベートDNSゾーン
    • パブリックインターネット経由でクエリできないゾーンのこと
  • サブゾーン
    • ゾーンの所有者が NS レコードを使用してサブドメインを別のネーム サーバーに委任できるもの
    • example.comの場合、aaa.example.combbb.example.com作成し、親ドメインのゾーンから見つけられるようにする(委任)するもの

スプリットビューDNS(スプリットホライズンDNS)

スプリットホライズンDNSを使用すると、要求に応じて同じ名前に対して異なる回答 (異なるリソースレコードセット) を提供できる

この機能は、クエリが開発ネットワークから送信された場合はアプリの開発/ステージング バージョンを提供し、クエリがパブリックインターネットから送信された場合はアプリの運用/公開バージョンを提供するといったことに利用できる。

リソースレコードの基礎

リソースレコードの役割と種類

リソースレコードはドメイン名と IP アドレスに関するデータを保存するために使用されるもの
DNSゾーンのデータベースは、リソース レコードのコレクションで構成される。 各リソース レコードは、特定のオブジェクトに関する情報を指定する。

リソースレコードタイプ説明
SOA管理情報の記述
NSゾーンを管理するDNSサーバを記述
MXメールサーバを記述(正引きのみ)
Aホスト名に対するIPアドレスを記述(正引きのみ)
AAAAホスト名に対するIPv6アドレスを記述(正引きのみ)
CNAMEホスト名の別名に対するホスト名を記述(正引きのみ)
PTRIPアドレスに対するホスト名を記述(逆引きのみ)
TLSAデジタル署名されたレコード。サーバ認証に使われる証明書や鍵の情報がドメイン名に対して関連付けられてDANE(DNSを使った認証の仕組み)で用いられる

レコードセット

レコードセットは同じ名前と同じタイプで、データ値が異なるレコードのこと。
以下は同じ名前とタイプを持つ複数のレコードを含むレコードセットの例。

DNS名タイプTTL (秒)データ
db-01.dev.gcp.example.comA5010.128.1.35
db-01.dev.gcp.example.comA5010.128.1.10

SOAレコードのシリアル番号

SOAレコードのシリアル番号はDNSゾーンのバージョン番号のこと。
すべてのネームサーバーがゾーンの最新のバージョンであるためには、それらのネーム サーバーが同じSOAシリアル番号を持っている必要がある。

DNSの拡張

EDNS

EDNSはDNSの拡張プロトコルEDNS(Extension mechanism for DNS)のこと。
DNSでUDPを用いる場合、パケットサイズが512byteを超えることができないという制約を緩和するためのものともいえる。 EDNS の最も一般的な実装は
DNSSEC
である。

また、EDNSは基本的なDNSプロトコルの枠組みは残したままで512byte以上の通信を可能にする。

DOビット/ADビット

EDNSによって拡張されたDNSパケットでは、DO bitという識別情報がやりとりされる。
DO=「DNSSEC OK」bitであり、このbitを識別できることがDNSSECを使用できる前提となる。つまりENDSを理解できない場合はDNSSECを利用といえる。

またDNSSECで認証確認が成立した場合は、DNS応答のAD(Authentic Data)ビットに1が格納される。

6.4.2. DNSSECによる応答の正当性保証

DNSSECとは

DNSSECはDNSの応答にデジタル署名の機能を使って正当性を付与し、改ざんされていないこと、正当な管理者の管理しているレコードであることを保証する仕組みのこと。
この仕組みはDNSキャッシュポイズニング攻撃への対策となる。

DNSはもともとルートサーバから始まる名前解決の木構造で、順に権限移譲しながら最終的な名前解決に辿り着くという仕組みとなる。 この際、自己の署名に対する公開鍵を上位DNSサーバへ登録することで、信頼される権威サーバであることを担保し、これによりその応答レコードも信頼される…という信頼の連鎖によって一覧のDNSレコードの信頼性を確保する。(信頼の連鎖)

DNSサーバは、ドメイン情報を保持・提供する権威DNSサーバと、権威DNSサーバに問い合わせをするキャッシュDNSサーバに分かれているが、DNSSECを使用するにはそれぞれがDNSSECに対応している必要がある。

DNSSECでは2種類の鍵を用いる。

  • ZSK(Zone Signing Key)_ゾーンの署名鍵 … ゾーン(上位サーバ)に署名するための鍵
  • KSK(Key Signing Key)_鍵の署名鍵 … ゾーンに署名した鍵に署名する

上記2つはそれぞれは公開鍵と秘密鍵のペアになっている。

DNSSEC認証サーバのリソースてコードと検証

DNSSECではZSK公開鍵(DNSKEY)に署名を行うKSK(Key-Signing Key)と残りのリソースコード(DNSレコード)に署名を行うZSK(Zone-Signing Key)が利用される。
鍵をKSKとZSKに分けることにより鍵強度、更新頻度を役割別に分けられる。
なおKSKの公開鍵はDSレコードとして上位ゾーンに登録される必要がある。

【DNS権威サーバにおけるリソースレコードの署名】

  1. ZSK秘密鍵で各リソースレコードに署名をする
  2. KSK秘密鍵でZSK公開鍵の署名をする
  3. KSK公開鍵のハッシュ値(DSレコード)を生成し、上位ゾーンへ登録する

【DNSキャッシュサーバにおけるリソースレコードの検証】

  1. 上位のDNS権威サーバから取得したDSレコードとKSK公開鍵を比較して検証
  2. KSK公開鍵を用いてKSK秘密鍵で署名されたZSK公開鍵を検証
  3. ZSK公開鍵を用いてZSK秘密鍵で署名された各リソースレコードを検証

DNSSEC関連のリソースレコード

DNSSECで使用されるリソースレコードは以下の通り。

リソースレコード説明
DSKSK公開鍵のハッシュ値を含む情報
上位ゾーンに登録すると信頼の連鎖を構築する
DNSKEY公開鍵の情報(KSK,ZSK公開鍵)
キャッシュDNSサーバが署名を検証するために公開鍵を使用する
RRSIG各リソースレコードへのデジタル署名
キャッシュDNSサーバが権威DNSサーバからの応答に対する正当性を検証するために使用
NSEC存在しないサーバへ問い合わせがあった際に不在証明のため辞書順で並べた際に次の位置するゾーン情報を示す
NSEC3NSECを改良したもの。直接のゾーン名ではなくハッシュ化されたゾーン名を示す
NSEC3PARAM権威DNSサーバがNSEC3を生成する際に必要な情報
TLSADANEにおいて用いられるレコード(ドメイン名にX.509証明書情報の紐づけ)

TLSAレコードを除き、基本的には署名を行うと署名や公開鍵を含んだレコード(ゾーンファイル)が作成される。
DNSKEYリソースレコードには上述の通りKSK・ZSKの公開鍵が含まれ、これらは各リソースレコードの検証に使用される。

6.4.3. BINDにおけるDNSSECの設定と運用

BINDにおけるDNSSECの設定

DNSSECを利用するためにはBINDの場合、設定ファイル/etc/named.confoptionsセクションへ以下の二つの項目を設定する必要がある。

options {
   dnssec-enable   yes; # DNSSECの有効(yes)/無効(no)を設定する
   dnssec-validation  auto; # DNSSEC検証の有効/無効を設定する (auto または yes)
# auto: DNSSEC検証を有効にし、トラストアンカー
# yes: DNSSEC検証を有効にする。トラストアンカー(trusted-key)を手動で設定する必要がある
# no : DNSSEC検証を無効にする
   :(以下省略)

これらのパラメータは、BINDのバージョンによってデフォルト値が異なる。
BINDのバージョンを確認するには、BINDサーバ上で直接named -vコマンドを実行するか、クライアントからBINDサーバへ向けて確認するには上述のdigコマンドを使用できる。

named -v

# DNSSECによるDNS問い合わせ
dig @127.0.0.1 +dnssec [ドメイン]

セキュリティのためにバージョンを隠す場合は設定ファイル/etc/named.confoptionsセクションに以下のように記載する。

options {
    version "表示したい文字列";
    :(以下省略)

BINDにおけるゾーン管理の自動化

署名されたゾーンについては、レコードの追加・更新時や、署名の有効期限内での鍵交換時など、鍵の管理とともに、署名や再署名を実施する管理業務が発生する。

こうしたゾーン管理を自動化するためにはBINDの場合、設定ファイル/etc/named.confzoneセクションへ以下の二つの項目を設定する必要がある。

zone "example.com" {
    file "example.com"
        :
    auto-dnssec maintain;
    inline-signing yes;
};
  • auto-dnssec … 鍵の管理およびゾーン署名を自動化する
  • inline-signing … BIND(named)が自動的にゾーンへの署名を行う

署名されたゾーンの管理

DNSサーバソフトウェアであるBINDには、サーバやKSK、ZSKの生成・管理などを行うための以下のようなコマンドユーティリティがある。

コマンド機能
dnssec-keygenDNSSECのZSK/KSKを生成する
dnssec-signzoneゾーンファイルへの署名を行う(NSEC, NSEC3, RRSIG, DNSKEYなどの生成)
dnssec-settime鍵ファイルのメタデータである時間の表示/変更
dnssec-dsfromkey鍵ファイルから上位サーバに登録するDSレコード生成する

dnssec-keygenコマンド

dnssec-keygenはDNSSECのキーを生成することができるコマンド。 具体的にはZSKKSKの作成が行える。

dnssec-keygen -a RSASHA256 -b 512 -n ZONE -f KSK myzone.
オプション説明
-aアルゴリズムの指定
-bキーサイズ
-nnametype
-f指定されたフラグをKEY/DNSKEYレコードのフラグフィールドに設定する

dnssec には、ゾーンに署名するための ZSK キーのペアも必要となる。

# KSKの作成
dnssec-keygen -f KSK -r /dev/urandom -a RSASHA256 -b 2048 -K /var/named/keys -n zone test.local

# ZSKの作成
dnssec-keygen -r /dev/urandom -a RSASHA256 -b 1024 -K /va/named/keys -n zone test.local

dnssec-signzoneコマンド

dnssec-signzone はゾーンに署名しゾーンの署名付きバージョンを生成するコマンド。
DNSKEY、NSEC、NSEC3、RRSIGなどのDNSレコードを生成する。

ZSKKSKを用いてゾーンファイルに署名を行うのに使用する。

dnssec-signzone -o myzone. -S db.myzoneFetching ZSK 63075/RSASHA256 from key repository.

ファイル内部は以下のようになる。

; File written on Mon Apr  9 01:45:42 2018
; dnssec_signzone version 9.10.3-P4-Ubuntu
myzone.            604800    IN SOA    myzone. root.myzone. (
                    51         ; serial
                    604800     ; refresh (1 week)
                    86400      ; retry (1 day)
                    2419200    ; expire (4 weeks)
                    604800     ; minimum (1 week)
                    )
            604800    RRSIG    SOA 8 1 604800 (
                    20180509074542 20180409074542 63075 myzone.
                    eHu3B0s9AcclEMfkaXK+zUcqnhYTRXO2BBoR
                    s4z9DGxbwcTXoy8MbIACkuVOhkM6+tQ8r7pr
                    clIKoUALm4I4mQ== )
オプション説明
-3 [ソルト値]NSEC3生成のためのソルト(16進数)を指定
-a署名の整合性を確認
-e [日時]署名の有効期限の設定、(指定しない場合は30日)
-f [ゾーンファイル]生成される署名済みゾーンファイルを指定
-o [ゾーン名]ゾーン名を指定
-xDNSKEYに対しKSKのみで署名
-K [ディレクトリ]ZSK,KSKの格納場所を指定
-Sスマート署名の利用
# ゾーンファイルの署名
dnssec-signzone -a -S -x -3 1234 -K /var/named/keys -o test.local /va/named/test.local.db

dnssec-dsfromkeyコマンド

特定の KSK の DSレコード を生成するために使用されるコマンド。
上位サーバに登録するレコードを作成できる。

dnssec-dsformkey [オプション] <キーファイル>
オプション説明
-1ハッシュ地生成アルゴリズムにSHA-1を使用
-2ハッシュ値生成アルゴリズムにSHA-256を使用
-a [アルゴリズム]ハッシュ値を生成するアルゴリズムを指定
# DSレコードの作成
dnssec-dsformkey Ktest.local.+008+42526.key

dnssec-settimeコマンド

指定されたキーの有効期間を管理するコマンド。

dnssec-settime [オプション] <キーファイル>
オプション説明
-p [確認対象]C/P/A/R/I/D/allのいずれかを指定し、設定内容の表示
-A [日時]鍵が有効となる日時の指定
-D [日時]署名をゾーンから削除する日時の指定
-I [日時]再署名する前提なしで鍵を取り消す日時の指定
-P [日時]鍵の公開日時の指定
-R [日時]再署名する前提で鍵を取り消す日時の指定
# ZSKの公開日時と有効化する日時の変更
dnssec-settime -P 20241001000000 -A 20241001000000

6.4.4. 高度な認証とセキュアな通信

DANEとCAA

DANE

DANE(DNS-based Authentication of Named Entities)はDNSSECの技術を応用した認証の仕組みのこと。 DNSSECの導入により、DNSサーバの応答の正当性が検証できるようになった。

具体的には認証局が発行する証明書認証の代わりにDNSを利用して通信相手の認証を行える仕組み。 DNSSECが持つトラストチェーンを用いて証明書の信頼性を担保する。

DANEで用いられるリソースレコードをTLSAレコードと呼ぶ。

TLSAレコード

TLSAレコードはTLS サーバー証明書または公開キーを、レコードが見つかったドメイン名に関連付けるために使用される。X.509証明書とドメイン名の紐付けのためのものと言える。
TLSAにはTLS証明書、証明書の種類、ハッシュアルゴリズムなどの認証情報が保存される。

# TLSAリソースレコードの例
_443._tcp.www.example.com. IN TLSA {
    1 1 2 92000ba5188dc892890d72687e282980e
          1b2572ec2829d279820a2829db2928c45
          8c9827f682766dfe2528ac67cbc1718bc
}

CAA

CAA (Certification Authority Authorization) とは、CAAレコードというリソースレコードを設定することで、ドメインの証明書を発行する認証局(CA)を指定する仕組みのこと。

この仕組みは攻撃者によってサーバ証明書を不正に発行・利用され、「ブラウザ上は目的のWebサイトを訪れていて鍵マークも表示されているのに、実際のアクセス先は不正なWebサイトである」といった事態にならないようにするためのものと言えます。

CAAレコードを設定することにより、証明書の誤発行や第三者による不正な発行のリスクを低減する。
ドメインの所有者は、DNSサーバにCAAレコードを設定することで、ドメインの証明書を発行できる認証局(CA)を指定する。CAは証明書を発行する前に指定されたドメインのCAAレコードを確認し、自身に発行権限がないことを確認した場合は証明書を発行しません。

opensslコマンドによる証明書やTLSAレコードの検証

openssl s_clientコマンド

openssl s_clientコマンドはTLSAレコードの検証を行えるコマンドで、さらにいくつかオプション(-dane_tlsa_domain, -dane_tlsa_rrdata)をつけて実行します。

openssl s_client -connect example.com:443 -dane_tlsa_domain "example.com" -dane_tlsa_rrdata "3 1 1 4ag45Hj1k39akIkaiwkn"
オプション説明
-connect接続先サーバを指定
-dane_tlsa_domainドメイン情報を指定
-dane_tlsa_rrdataTLSAリソースレコードを指定

TSIG

TSIGはDNSサーバとクライアント、DNSサーバ間でDNS情報を通信する際に使われる仕組み
メッセージ認証と呼ばれる認証方式を利用する。この方式は共有する秘密鍵とDNSメッセージを元にハッシュ関数から生成したMACを比較することにより、サーバ間の認証と通信内容の完全性を保証する。

Dynamic DNS(DDNS)やDNSスレーブサーバのDNS情報の更新の手段として用いられる

# ============================================
## マスターサーバ/スレーブサーバ間のゾーン転送にTSIGを設定する例(BIND)
# ============================================
# 共有鍵の作成
dnssec-keygen -a hmac-sha256 -b 128 -K /va/named/keys -n HOST test.local.key
# 使用する共有鍵の確認
cat Ktest.local.key.+163+43780.private
# マスターサーバ/スレーブサーバにおけるnamed.confの設定
vim /etc/named.conf
:
key "test.local.key" {
    alogorithm hmac-sha256;
    secret "i8Tsy16TsDmNWhnKs3hfQ==";
};
:
# スレーブサーバにおけるnamed.confの設定
vim /etc/named.conf
:
server 192.168.1.1 {
    keys "test.local.key";
};
:
# ゾーン転送要求の確認
dig @192.168.1.1 -y hmac-sha256:test.local.key:i8Tsy16TsDmNWhnKs3hfQ== test.local axfr

6.4.5. その他のDNSプロトコルと管理ツール

暗号化されたDNS通信

DNS over TLS (DoT)

DoTはTLSを使用してDNSクエリを暗号化し、専用のポート(853)で通信します。 これにより、通信経路上で発生する盗聴や改ざんを防ぎます。

DNS over HTTPS (DoH)

DoHは、HTTPSを使用してDNSクエリを暗号化し、通常のHTTPS通信と同じポート(ポート443)を使用します。
これにより、DNSクエリが他のHTTPSトラフィックに紛れて見えにくくなり、プライバシーとセキュリティの強化を実現します。

ローカルネットワークサービス

マルチキャストDNS (mDNS)

マルチキャストDNS(mDNS)とは、ローカルネットワークなど制限されたネットワーク内で、DNSサーバを使わずにホスト名の解決を行うプロトコルのこと。

mDNSは、クライアントが問合せをネットワーク内にマルチキャストで一斉に配信し、その問合せに一致するホストが直接応答する。これにより、DNSサーバがなくても同一ネットワーク内にあるデバイスを検出することができる。

通常、mDNSはIPv4では224.0.0.251、IPv6ではff02::fbというマルチキャストアドレスと、UDPポート5353を使用する。
mDNSは、スマートデバイスやプリンター、家庭内ネットワークデバイスなどで広く利用されており、ネットワーク内のデバイス同士の簡易な検出と通信を可能にする。

主要な管理・検証ユーティリティ

rndc

rndc (remote name daemon control)は、BIND にてローカルホストまたはリモートホストから指定されたデーモンをコマンドラインで管理できるようにするツール。
BIND 9.0以降で使用できる。

rndcは、デジタル署名された名前付きコマンドを TCP 接続経由で送信する。

rndc の設定ファイルは/etc/rndc.confとなる。 この構成ファイルには、接続するネームサーバーやデジタル署名に使用するキーなどの構成情報が保存される。

rndc ユーティリティは、初期化スクリプトを使用してnamedが開始されるときに開始される。 rndc.confファイルはrndc-confgenコマンドユーティリティを使用してランダムキーを使用して生成できる。

digコマンド

dig(Domain Information Groper)コマンドはDNSにクエリを実行するためのコマンド。
DNS 問題の検証とトラブルシューティングに使用できる。

dig <ドメイン名>
digコマンド説明
dig google.com MXドメインの MX レコードをクエリする
dig google.com SOAドメインの SOA レコードをクエリする
dig google.com TTLドメインの TTL レコードをクエリする
dig @8.8.8.8 google.comクエリに別の DNS サーバーを使用する
digdigコマンドのバージョンとルートDNS サーバーを表示します

delvコマンド

delvコマンドはBIND 9.10以降のdigコマンドの後継ツール
DNSSEC検証/解析ツールと言える。

delv <オプション> ドメイン名
オプション説明
+rtraceクエリされたすべてのレコードリソースをリストするだけ。DNSSEC の詳細は含まれない
+mtracertrace と同じだが、すべてのレコードリソースの完全な内容が含まれる
+vtrace多くの追加メモを含む検証プロセスの追跡