本記事はGeminiの出力をプロンプト工学で整理した業務ドラフト(未検証)です。
DNS over HTTPS (DoH) (RFC 8484) 解説
背景
従来のDNSはUDPまたはTCP上で平文で通信され、その性質上、盗聴や改ざんのリスクに晒されていました。また、ネットワーク上の監視者にとってはDNSクエリが明確に見えるため、ユーザーのインターネット利用履歴をプロファイリングされる可能性がありました。このようなプライバシーとセキュリティの課題に対処するため、DNSSECによる認証は進められましたが、通信経路の秘匿化は別途必要とされました。そこで、既存のセキュアなWeb通信基盤であるHTTPSを活用し、DNSクエリを暗号化されたHTTPメッセージ内にカプセル化する「DNS over HTTPS (DoH)」がIETFによって標準化されました。本記事では、ネットワークエンジニアの視点から、RFC 8484で定義されるDoHについて詳細に解説します。
設計目標
RFC 8484の主要な設計目標は以下の通りです。
プライバシーの向上: DNSクエリの内容を通信経路上の第三者から秘匿し、ユーザーのウェブ閲覧履歴などの情報が漏洩することを防ぎます。
セキュリティの強化: TLSによる暗号化と認証を利用することで、DNSクエリおよび応答の完全性と真正性を保証し、中間者攻撃やDNSスプーフィングを防ぎます。
検閲の回避: DNSトラフィックが一般的なHTTPSトラフィックに偽装されるため、特定のDNSクエリに対する検閲やブロックが困難になります。
既存インフラの活用: HTTP/2(および将来的なHTTP/3)の多重化機能やプロキシ、キャッシュといった既存のWebインフラストラクチャを活用し、効率的なDNS解決を実現します。
詳細
プロトコルスタック
DoHは、標準のDNSメッセージをHTTPメッセージのペイロードとしてカプセル化し、TLSによって暗号化されたTCP(HTTP/2の場合)またはQUIC(HTTP/3の場合)上で送信します。
graph LR
A["DNS Query/Response"] --> B["HTTP/2 or HTTP/3"];
B --> C["TLS 1.3"];
C --> D["TCP(#quot;for HTTP/2#quot;) or QUIC(#quot;for HTTP/3#quot;)"];
D --> E[IP];
E --> F["Link Layer"];
F --> G["Physical Layer"];
subgraph mermaid_group_8["DoH Protocol Stack"]
A --> B;
B --> C;
C --> D;
D --> E;
E --> F;
F --> G;
end図1: DoHプロトコルスタック
メッセージフォーマット
DoHは、DNSクエリと応答をHTTPリクエストおよびレスポンスのボディ、またはGETリクエストのURLクエリパラメータとして伝送します。RFC 8484は、以下のHTTPメソッドとメディアタイプを定義しています。
HTTP GETメソッド: DNSクエリは、
application/dns-messageまたはapplication/dns-json形式で、dnsという名前のURLクエリパラメータ内にBase64urlエンコードされて格納されます。主に単一のDNSクエリに使用されます。HTTP POSTメソッド: DNSクエリは、
application/dns-messageまたはapplication/dns-json形式で、HTTPリクエストのボディに格納されます。複数のクエリやより大きなクエリに適しています。
ヘッダ/フレーム/パケット構造
DoHにおけるHTTPリクエストの典型的な構造は以下のようになります。
HTTP/S Request (GET or POST for DoH)
-----------------------------------
[TLS Record Header]
Type: [e.g., Application Data]
Version: [e.g., TLS 1.2 or 1.3]
Length: [Length of encrypted payload]
[Encrypted TLS Handshake/Application Data]
[HTTP/2 or HTTP/3 Frame Header(s)]
Length: [Length of frame payload]
Type: [e.g., HEADERS, DATA]
Flags: [e.g., END_STREAM, END_HEADERS]
Stream ID: [Stream identifier]
[HTTP/2 or HTTP/3 Frame Payload]
(If HEADERS frame)
:method: [GET or POST]
:scheme: https
:authority: doh.example.com
:path: /dns-query[?dns=<base64url-encoded DNS query>]
accept: application/dns-message
content-type: application/dns-message (for POST)
content-length: [length of DNS query, for POST]
(If DATA frame for POST)
[DNS Wire Format Query (RFC 1035)]
-----------------------------------
ID:16bits (Transaction ID)
QR:1bit | OPCODE:4bits | AA:1bit | TC:1bit | RD:1bit | RA:1bit | Z:3bits | RCODE:4bits
QDCOUNT:16bits (Number of questions)
ANCOUNT:16bits (Number of answer RRs)
NSCOUNT:16bits (Number of authority RRs)
ARCOUNT:16bits (Number of additional RRs)
[Questions Section]
[Answers Section]
[Authority Records Section]
[Additional Records Section]
... (additional HTTP/2 or HTTP/3 frames for full request)
図2: DoH HTTPリクエスト(DNS Wire Formatペイロード)
DNS Wire Formatは、RFC 1035で定義された標準的なDNSメッセージ形式であり、DoHリクエストのボディやGETパラメータに埋め込まれます。
既存プロトコルとの比較
DNS over TLS (DoT) (RFC 7858) との比較
| 特徴 | DNS over TLS (DoT) (RFC 7858) | DNS over HTTPS (DoH) (RFC 8484) |
|---|---|---|
| ポート | 853/TCP (専用ポート) | 443/TCP (HTTPS標準ポート) |
| プロトコルスタック | DNS over TLS over TCP | DNS over HTTP/2 (or HTTP/3) over TLS over TCP (or QUIC) |
| 可視性 | 比較的容易にDNS-over-TLSトラフィックと識別・ブロック可能 | 一般のHTTPSトラフィックに紛れ込み、識別・ブロックが困難 |
| 多重化 | 1つのTCP接続で複数のDNSクエリを並行して処理可能 (TLSv1.3 Session Ticket) | HTTP/2のストリーム多重化により効率的に処理可能 |
| インフラ | 専用のDNS/TLSプロキシが必要となる場合がある | 既存のHTTPSプロキシ、ロードバランサー、キャッシュを流用可能 |
| オーバーヘッド | DoHと比較してプロトコルスタックがシンプルである分、軽量 | HTTPレイヤの追加により、DoTより若干のオーバーヘッドが増加 |
HTTP/2 と HTTP/3 (QUIC) の比較
DoHはHTTP/2上で動作するように設計されていますが、HTTP/3(QUIC)上での利用も可能であり、更なる性能向上が期待されます。
Head-of-Line (HOL) Blocking回避:
HTTP/2: 単一のTCP接続上で複数のHTTPストリームを多重化しますが、下層のTCPがHOL Blockingを起こす可能性があります。特定のTCPセグメントが失われると、その後のすべてのストリームの処理が停止する可能性があります。
HTTP/3: QUICをトランスポートとして利用するため、多重化はTCPではなくQUICストリーム上で行われます。QUICはUDPベースであり、個々のQUICストリームは独立しているため、一つのストリームでのパケット損失が他のストリームに影響を与えず、HOL Blockingを回避できます。
ハンドシェイク時間の短縮:
HTTP/2: TCPハンドシェイクとTLSハンドシェイクが順次発生し、最低でも2-RTT(ラウンドトリップタイム)が必要です(TLS 1.3の0-RTTを使用しない場合)。
HTTP/3: QUICハンドシェイクはTCPとTLSハンドシェイクを統合し、初回接続時は1-RTT、接続再開時には0-RTTでの接続確立が可能です。これにより、DoHクエリの初期レイテンシが大幅に削減されます。
接続マイグレーション: HTTP/3は、クライアントのIPアドレスやポート番号が変化しても接続を維持できる接続マイグレーション機能を持ちます。モバイル環境などでの接続安定性向上に寄与します。
相互運用性
DoHは標準のHTTPSプロトコルとWeb技術に基づいているため、広範な相互運用性が期待されます。
既存Webインフラとの互換性: 標準のポート443を使用し、HTTP/2やHTTP/3といった既存のWebプロトコルを利用するため、多くのファイアウォール、プロキシ、ロードバランサーはDoHトラフィックを特別な設定なしに処理できます。
多様なクライアントサポート: Webブラウザ、オペレーティングシステム、モバイルアプリなど、HTTPSをサポートするあらゆるクライアントでDoHを利用できます。
DNSサービスとの統合: Cloudflare, Google, Quad9などの主要なパブリックDNSサービスプロバイダは、DoHエンドポイントを提供しています。
セキュリティ考慮
DoHはTLSによって高いセキュリティを提供しますが、実装および運用において注意すべき点があります。
TLS 1.3と0-RTTの再送リスク:
TLS 1.3 (RFC 8446) は、ハンドシェイクを高速化するために0-RTT(Early Data)機能を導入しました。これにより、クライアントは最初のフライト(ClientHello)でアプリケーションデータを送信できます。
しかし、0-RTTデータは暗号化されているものの、リプレイ攻撃のリスクがあります。攻撃者が0-RTTデータを傍受し、サーバーに再送した場合、サーバーは同じ処理を複数回実行してしまう可能性があります。
DNSクエリは一般的に冪等(idempotent)な操作であり、複数回実行されても問題ない場合が多いですが、稀に非冪等な拡張(例: 動的更新)と組み合わせる場合は注意が必要です。DoHサーバーは、0-RTTデータに対して厳密なアンチリプレイメカニズムを実装すべきです。
sequenceDiagram participant C as クライアント participant S as DoHサーバー C->>S: TLS ClientHello (0-RTTデータ含む可能性) S->>C: TLS ServerHello, EncryptedExtensions, Certificate, CertificateVerify, Finished C->>S: TLS Finished (ハンドシェイク完了) alt 0-RTTデータが含まれない場合 C->>S: HTTP/2 (または HTTP/3) SETTINGS, HEADERS (DNSクエリ) S->>C: HTTP/2 (または HTTP/3) HEADERS (DNS応答) else 0-RTTデータが含まれる場合 Note right of S: 0-RTTデータに対するアンチリプレイチェック実行 S->>C: HTTP/2 (または HTTP/3) HEADERS (DNS応答) end C-->>S: 後続のDNSクエリ (多重化) S-->>C: 後続のDNS応答図3: DoHにおけるTLS 1.3ハンドシェイクと0-RTT
リプレイ攻撃:
- 上述の0-RTTデータに対するリプレイ攻撃に加え、HTTPレイヤでのリプレイ攻撃も考慮する必要があります。例えば、キャッシュされたDNS応答が古いものであったり、意図的に再送されたりする場合です。DNSクエリは通常冪等なので、多くの場合問題になりませんが、タイムスタンプやワンタイムトークンなどを利用することで、より堅牢なシステムを構築できます。
ダウングレード攻撃:
- 攻撃者が意図的にクライアントとサーバー間のTLSセッションを、より脆弱なプロトコルバージョンや暗号スイートに誘導しようとする攻撃です。TLS 1.3はダウングレード攻撃に対する強力な保護機構を持っていますが、サーバーは常に最新かつセキュアな設定を使用し、古いプロトコルバージョンや脆弱な暗号スイートを無効化すべきです。
キー更新:
- TLSセッションキーは定期的に更新されるべきです。TLS 1.3はPost-Handshake AuthenticationやKey Updateメッセージをサポートしており、これにより通信中にセッションキーを安全に更新し、前方秘匿性を維持できます。
プライバシー(IPアドレス、トラフィック分析):
DoHは通信経路上の第三者からのDNSクエリのプライバシーを保護しますが、DoHサーバー自体はクライアントのIPアドレスを認識し、すべてのDNSクエリを把握できます。したがって、信頼できるDoHプロバイダを選択することが重要です。
また、DNSトラフィックがHTTPSトラフィックに紛れ込むことで、企業ネットワークなどではDNSフィルタリングが困難になるという側面もあります。
実装メモ
MTU/Path MTU検出
DoHはHTTP/2またはHTTP/3上で動作し、その下層にはTCPまたはQUIC、さらにIPレイヤーがあります。大きなDNS応答(例: DNSSECレコード)は、IPフラグメンテーションを避けるため、Path MTU Discovery (PMTUD) が適切に機能することが重要です。
HTTP/2はTCPの上で動作するため、TCPのMSS (Maximum Segment Size) がPMTUDの結果を反映します。HTTP/3 (QUIC) はUDPの上で動作するため、QUIC実装自身がPMTUDを管理するか、または大きなデータグラム送信時にIPフラグメンテーションが発生しないように注意が必要です。
HOL blocking回避
HTTP/2: 単一のTCP接続上で多重化されるため、TCPレイヤーでのパケットロスは、その接続上のすべてのHTTPストリームの処理を停止させる可能性があります。これが「Head-of-Line Blocking」です。DoHクライアント/サーバーは、応答の遅延やタイムアウトを適切に処理する必要があります。
HTTP/3: QUICはUDPベースであり、個々のストリームは独立して多重化されます。1つのストリームでのパケットロスが他のストリームに影響を与えないため、HOL Blockingを回避できます。これにより、特にパケットロスが多い環境でのDoHパフォーマンスが向上します。
キュー制御と優先度
HTTP/2およびHTTP/3は、複数のストリームに対して優先度付けを行う機能を持っています。DoHクライアントやサーバーは、重要度の高いDNSクエリ(例: Webページの初期ロードに必要なもの)に対して、他のバックグラウンドクエリよりも高い優先度を割り当てることで、ユーザー体感を向上させることができます。
DoHサーバーは、着信する大量のクエリに対して適切なキュー制御とリソース割り当てを行うことで、サービス品質を維持する必要があります。
DNSキャッシュ管理
DoHはDNSプロトコルをカプセル化するだけなので、DNSキャッシュの概念は引き続き重要です。クライアントとサーバーの両方でDNS応答を適切にキャッシュすることで、冗長なネットワークトラフィックとレイテンシを削減できます。
HTTPキャッシュメカニズム(Cache-Controlヘッダなど)は、DoHの文脈でも利用できますが、DNSのTTL (Time To Live) との整合性を考慮する必要があります。
まとめ
DNS over HTTPS (DoH) は、RFC 8484として標準化された、DNS通信のプライバシーとセキュリティを大幅に向上させるプロトコルです。TLSによる暗号化とHTTP/2(およびHTTP/3)の多重化機能を活用することで、従来のDNSの課題を解決し、現代のインターネット環境に適応しています。ネットワークエンジニアとしては、そのプロトコルスタック、メッセージ構造、そして特にTLS 1.3の0-RTT機能がもたらすセキュリティリスクと、HTTP/2とHTTP/3の性能特性(HOL blocking回避など)を深く理解することが重要です。また、MTU、キュー制御、優先度、キャッシュ管理といった実装上の考慮事項を適切に対処することで、DoHの恩恵を最大限に引き出すことができます。2024年5月18日現在、多くのクライアントとサーバーでDoHが広く利用されており、今後もその利用は拡大していくでしょう。

