メインコンテンツまでスキップ

6. Name Server Implementation (ネームサーバー実装)

本章では、DNSネームサーバーの実装に関する考慮事項について説明します。


6.1. Architecture (アーキテクチャ)

ネームサーバーの最適な構造は、ホストオペレーティングシステムと、ネームサーバーが再帰サービスをサポートするか、リゾルバとデータベースを共有することでリゾルバ操作と統合されているかによって異なります。

このセクションでは、リゾルバとデータベースを共有するネームサーバーの実装に関する考慮事項について説明しますが、これらの懸念事項のほとんどは、あらゆるネームサーバーに存在します。


6.1.1. Control (制御)

ネームサーバーは、ホストのOS内の個別のタスクとして実装されるか、単一のネームサーバープログラム内で多重化されるかに関係なく、複数の並行アクティビティを採用しなければなりません (MUST)。

要件:

  • UDPノンブロッキング: ネームサーバーがリフレッシュまたはクエリアクティビティのためにTCPデータを待機している間に、UDPリクエストのサービスをブロックすることは容認できません

  • 並列処理: ネームサーバーは、そのようなリクエストを並列で処理せずに再帰サービスを提供しようとすべきではありません (SHOULD NOT)。ただし、次のことを選択できます:

    • 単一のクライアントからのリクエストをシリアル化する
    • 同じクライアントからの同一のリクエストを重複とみなす
  • ノンブロッキングゾーン操作: ネームサーバーは、次の間、リクエストを大幅に遅延させるべきではありません (SHOULD NOT):

    • マスターファイルからゾーンをリロードする
    • 新しくリフレッシュされたゾーンをデータベースに組み込む

6.1.2. Database (データベース)

ネームサーバーの実装は、選択した任意の内部データ構造を自由に使用できますが、推奨される構造は3つの主要部分で構成されます:

推奨されるデータベース構造

1. カタログデータ構造 (Catalog Data Structure):

  • このサーバーで利用可能なゾーンをリストします
  • ゾーンデータ構造への「ポインタ」を含みます
  • 主な目的: 到着する標準クエリの最も近い先祖ゾーン (存在する場合) を見つけること

2. ゾーンデータ構造 (Zone Data Structures):

  • ネームサーバーが保持する各ゾーンの個別のデータ構造
  • ゾーンの権威データを含みます

3. キャッシュデータ構造 (Cache Data Structure):

  • キャッシュされたデータのためのデータ構造
  • 異なるクラス用に個別のキャッシュを持つ場合があります

実装の考慮事項

ツリー構造: これらのデータ構造はすべて、同一のツリー構造形式で実装でき、異なる部分のノードから異なるデータがチェーン化されます:

  • カタログ内: データはゾーンへのポインタです
  • ゾーンとキャッシュデータ構造内: データはRRになります

クエリ処理要件: ツリーフレームワークを設計する際、設計者は次のことを認識すべきです (SHOULD):

  • クエリ処理は、大文字小文字を区別しないラベル比較を使用してツリーをトラバースする必要があります
  • 実際のデータでは、少数のノードが非常に高い分岐係数 (100-1000以上) を持ちます
  • 大多数は非常に低い分岐係数 (0-1) を持ちます

大文字小文字を区別しないストレージソリューション

大文字小文字の問題を解決する1つの方法は、各ノードのラベルを2つの部分に格納することです:

  1. すべてのASCII文字が単一のケースである標準化されたケース表現 (Standardized-Case Representation)
  2. 実際に異なるケースである文字を示すビットマスク (Bit Mask)

分岐係数の最適化

分岐係数の多様性は次の方法で処理できます:

  • 分岐係数がしきい値を超えるまで、ノードに単純なリンクリスト (Linked List) を使用
  • しきい値を超えた後、ハッシュ構造 (Hash Structure) に移行

重要: ツリーセクションを格納するために使用されるハッシュ構造は、ハッシュ関数とプロシージャがDNSの大文字小文字規則を保持することを保証しなければなりません (MUST)。

個別構造の利点

データベースの異なる部分に個別の構造を使用することは、いくつかの要因によって動機付けられています:

1. カタログの安定性:

  • カタログ構造はほぼ静的な構造にすることができます
  • システム管理者がサーバーがサポートするゾーンを変更する場合にのみ変更する必要があります
  • リフレッシュアクティビティを制御するために使用されるパラメータを格納することもできます

2. アトミックゾーン置換:

  • ゾーン用の個別のデータ構造により、カタログ内のポインタを変更するだけでゾーンを置き換えることができます
  • ゾーンリフレッシュ操作は新しい構造を構築でき、完了すると単純なポインタ置換を介してデータベースにスプライスできます
  • 重要: ゾーンがリフレッシュされるとき、クエリは古いデータと新しいデータを同時に使用すべきではありません (SHOULD NOT)

3. データの優先順位:

  • 適切な検索プロシージャにより、ゾーン内の権威データは常にキャッシュされたデータを「隠し」、したがって優先されます

4. エラーの分離:

  • 重複するゾーンなどを引き起こすゾーン定義のエラーは、クエリへの誤った応答を引き起こす可能性があります
  • 問題の判定が簡素化されます
  • 1つの「不良」ゾーンの内容は別のゾーンを破損できません

5. キャッシュ管理:

  • キャッシュは最も頻繁に更新されるため、システムの再起動中に破損する可能性が最も高くなります
  • 期限切れのRRデータでいっぱいになることもあります
  • いずれの場合も、ゾーンデータを妨げることなく簡単に破棄できます

クラッシュ回復

データベース設計の主要な側面は、ネームサーバーがネームサーバーのホストのクラッシュに対処できる構造を選択することです。

ネームサーバーがシステムクラッシュ全体で保存すべき (SHOULD) 状態情報:

  • カタログ構造 (各ゾーンのリフレッシュ状態を含む)
  • ゾーンデータ自体

6.1.3. Time (時間)

RRのTTLデータとリフレッシュアクティビティのタイミングデータの両方は、秒単位の32ビットタイマーに依存します。

時間表現

概念モデル:

  • データベース内部では、リフレッシュタイマーとキャッシュされたデータのTTLは概念的に「カウントダウン」します
  • ゾーン内のデータは一定のTTLのままです

推奨される実装戦略:

時間を2つの方法で格納します: 相対増分として、および絶対時間として。

これを行う1つの方法は、次を使用することです:

  • 1つのタイプに正の32ビット数を使用
  • もう1つのタイプに負の数を使用

使用法:

  • ゾーン内のRRは相対時間 (Relative Times) を使用します
  • リフレッシュタイマーとキャッシュデータは絶対時間 (Absolute Times) を使用します
  • 絶対数は既知のオリジンに対して取得され、クエリへの応答に配置されるときに相対値に変換されます
  • 絶対TTLが相対に変換された後に負の場合、データは期限切れであり、無視すべきです (SHOULD)

6.2. Standard Query Processing (標準クエリ処理)

標準クエリ処理の主要アルゴリズムはRFC-1034で提示されています。

特殊なケースとルール

*QCLASS=処理:

  • QCLASS=*、または複数のクラスに一致する他のQCLASSでクエリを処理する場合
  • サーバーが応答がすべてのクラスをカバーすることを保証できない限り、応答は決して権威的であるべきではありません (SHOULD NOT)

重複RR処理:

  • 応答を作成する際、追加セクションに挿入されるRRが、回答または権威セクションのRRと重複する場合
  • 追加セクションから省略できます (MAY)

切り詰めポリシー:

  • 応答が非常に長く、切り詰めが必要な場合
  • 切り詰めは応答の終わりから開始し、データグラム内で前方に進むべきです (SHOULD)
  • したがって、権威セクションにデータがある場合、回答セクションは一意であることが保証されます

SOA MINIMUMフィールド:

  • SOA内のMINIMUM値は、ゾーンから配布されるデータのTTLの下限を設定するために使用されるべきです (SHOULD)
  • この下限関数は、データが応答にコピーされるときに実行されるべきです (SHOULD)
  • これにより、将来の動的更新プロトコルがあいまいなセマンティクスなしでSOA MINIMUMフィールドを変更できるようになります

6.3. Zone Refresh and Reload Processing (ゾーンリフレッシュとリロード処理)

エラー処理

サーバーの最善の努力にもかかわらず、次のことができない場合があります:

  • 構文エラーなどのためにマスターファイルからゾーンデータをロードする
  • 有効期限パラメータ内でゾーンをリフレッシュする

この場合: ネームサーバーは、ゾーンを所有すべきではないかのようにクエリに応答すべきです (SHOULD)。

ゾーン転送の一貫性

マスターがAXFRを介してゾーンを送信していて、転送中に新しいバージョンが作成された場合:

  • マスターは可能であれば古いバージョンを送信し続けるべきです (SHOULD)
  • いずれにせよ、1つのバージョンの一部と別のバージョンの一部を送信してはなりません (MUST NOT)
  • 完了が不可能な場合、マスターはゾーン転送が行われている接続をリセットすべきです (SHOULD)

6.4. Inverse Queries (Optional) (逆引きクエリ - オプション)

逆引きクエリはDNSのオプション部分です。

サポート要件

  • ネームサーバーは逆引きクエリのいかなる形式もサポートすることを要求されません (NOT REQUIRED)
  • ネームサーバーがサポートしない逆引きクエリを受信した場合、ヘッダーに「未実装 (Not Implemented)」エラーが設定されたエラー応答を返します
  • 逆引きクエリのサポートはオプションですが、すべてのネームサーバーは少なくともエラー応答を返すことができなければなりません (MUST)

6.4.1. The Contents of Inverse Queries and Responses (逆引きクエリと応答の内容)

逆引きクエリは、標準クエリ操作によって実行されるマッピングを逆にします:

  • 標準クエリがドメイン名をリソースにマップする一方
  • 逆引きクエリはリソースをドメイン名にマップします

:

  • 標準クエリはドメイン名をホストアドレスにバインドする可能性があります
  • 対応する逆引きクエリはホストアドレスをドメイン名にバインドします

形式

逆引きクエリは次の形式をとります:

  • メッセージの回答セクション内の単一のRR
  • 空の質問セクション
  • クエリRRの所有者名とそのTTLは重要ではありません

応答

応答は、ネームサーバーが知っているクエリRRを所有するすべての名前を識別する質問を質問セクションに運びます。

重要な制限:

  • どのネームサーバーもドメイン名空間のすべてについて知らないため、応答が完全であると仮定することはできません
  • したがって、逆引きクエリは主にデータベース管理とデバッグアクティビティに役立ちます
  • 逆引きクエリはホストアドレスをホスト名にマップする許容可能な方法ではありません。代わりにIN-ADDR.ARPAドメインを使用してください

大文字小文字を区別しない比較

可能な場合、ネームサーバーは逆引きクエリに大文字小文字を区別しない比較を提供すべきです (SHOULD):

  • Venera.isi.eduのMX RRを求める逆引きクエリは、VENERA.ISI.EDUのクエリと同じ応答を取得すべきです
  • HINFO RR IBM-PC UNIXの逆引きクエリは、IBM-pc unixの逆引きクエリと同じ結果を生成すべきです

注意: これは保証できません。なぜなら、ネームサーバーは文字列を含むRRを所有している可能性がありますが、ネームサーバーはデータが文字であることを知らないためです。

処理結果

ネームサーバーが逆引きクエリを処理するとき、次のいずれかを返します:

  1. 質問セクション内のQNAMEとして、指定されたリソースのゼロ、1つ、または複数のドメイン名
  2. ネームサーバーが指定されたリソースタイプの逆マッピングをサポートしていないことを示すエラーコード

応答の変更

逆引きクエリへの応答に1つ以上のQNAMEが含まれる場合:

  • 逆引きクエリを定義する回答セクション内のRRの所有者名とTTLは、最初のQNAMEで見つかったRRと正確に一致するように変更されます

キャッシュの制限

逆引きクエリで返されたRRは、標準クエリへの応答に使用されるのと同じメカニズムを使用してキャッシュできません (CANNOT)。

理由: 名前は同じタイプの複数のRRを持つ可能性があり、1つだけが表示されます。たとえば、マルチホームホストの単一アドレスの逆引きクエリは、1つのアドレスのみが存在するという印象を与える可能性があります。


6.4.2. Inverse Query and Response Example (逆引きクエリと応答の例)

インターネットアドレス10.1.0.52に対応するドメイン名を取得するための逆引きクエリの全体構造:

クエリ:

+-----------------------------------------+
| Header | OPCODE=IQUERY, ID=997 |
+-----------------------------------------+
| Question | <empty> |
+-----------------------------------------+
| Answer | <anyname> A IN 10.1.0.52 |
+-----------------------------------------+
| Authority | <empty> |
+-----------------------------------------+
|Additional | <empty> |
+-----------------------------------------+

説明:

  • このクエリは、インターネットスタイルのアドレス10.1.0.52が答えである質問を求めています
  • 所有者名が不明なため、任意のドメイン名をプレースホルダーとして使用できます (無視されます)
  • 通常、ルートを示すゼロの単一オクテットが使用されます。これはメッセージの長さを最小化するためです
  • RRのTTLは重要ではありません

応答:

+-----------------------------------------+
| Header | OPCODE=RESPONSE, ID=997 |
+-----------------------------------------+
| Question | QTYPE=A, QCLASS=IN, |
| | QNAME=VENERA.ISI.EDU |
+-----------------------------------------+
| Answer | VENERA.ISI.EDU A IN |
| | 10.1.0.52 |
+-----------------------------------------+
| Authority | <empty> |
+-----------------------------------------+
|Additional | <empty> |
+-----------------------------------------+

注意: 逆引きクエリへの応答のQTYPEは、逆引きクエリの回答セクションのTYPEフィールドと同じです。逆引きが一意でない場合、逆引きクエリへの応答には複数の質問が含まれる場合があります。


6.4.3. Inverse Query Processing (逆引きクエリ処理)

逆引きクエリをサポートするネームサーバーは、データベースの徹底的な検索を通じてこれらの操作をサポートできますが、データベースのサイズが大きくなるにつれて、これは非実用的になります。

代替アプローチ: 検索キーに従ってデータベースを反転します。

大規模サーバーの推奨事項

複数のゾーンと大量のデータをサポートするネームサーバーの場合、推奨されるアプローチは:

  • 各ゾーンの個別の反転
  • リフレッシュ中に特定のゾーンが変更された場合、その反転のみをやり直す必要があります

注意: このタイプの反転の転送のサポートは、ドメインシステムの将来のバージョンに含まれる可能性がありますが、このバージョンではサポートされていません。


6.5. Completion Queries and Responses (完了クエリと応答)

RFC-882およびRFC-883で説明されているオプションの完了サービスは削除されました

再設計されたサービスは将来利用可能になる可能性があります。


: 7. Resolver Implementation (リゾルバ実装)