2026年6月14日

2026年6月14日

DoQ (DNS over QUIC) と DoH (DNS over HTTPS) を併用する設定|dnsdist で1台から両方を提供する構成と動作確認

DoQ と DoH は、同じリゾルバーの前に2つの入り口を並べる形で併用できます。DoH はブラウザや OS の対応が広く 443 番で通りやすいこと、DoQ は通信の遅延や再接続に強いことが利点なので、両方を用意しておくと端末ごとに合う方式を選べます。この記事では、dnsdist を入り口にして1台のサーバーから DoQ と DoH を提供する設定、ポートと証明書の設計、Web サーバーと同居させるときの注意、ポリシーをそろえる方法、動作確認までを説明します。

併用する理由と方式の違い

どちらも端末とリゾルバーの間の通信を暗号化する方式ですが、運ぶ土台が違います。

  • DoH(RFC 8484) は HTTPS の上で DNS をやり取りします。通常は TCP の 443 番で、Web の通信と見分けがつきにくいため、853 番が遮断されたネットワークでも使える可能性が高い方式です。主要なブラウザや Windows などが対応しています。HTTP/3(UDP の 443 番)で運ぶ DoH3 もあります。
  • DoQ(RFC 9250) は QUIC の上で DNS をやり取りし、通常は UDP の 853 番を使います。1つの問い合わせの遅れが他の問い合わせを待たせにくく、通信環境が変わったときの再接続も軽いため、モバイル回線などで利点があります。一方で、OS が標準で DoQ に対応している例はまだ少なく、主に対応アプリや DNS プロキシから使われています(2026年10月現在)。

つまり、DoH を「幅広い端末向けの標準の入り口」、DoQ を「対応した端末向けの軽い入り口」として並べるのが、併用の典型的な考え方です。どちらの入り口から来ても、後ろのリゾルバーは同じものを使います。

なお、DoQ で使う証明書や鍵の入れ替え手順は、この記事では扱いません。ここでは併用の構成に絞ります。

構成の全体像

端末(DoH) ── TCP 443 ──┐
端末(DoH3) ─ UDP 443 ──┤ dnsdist ── 127.0.0.1:5300 ── Unbound(DNSSEC 検証・キャッシュ)
端末(DoQ) ── UDP 853 ──┘

入り口に dnsdist を置くのは、DoH・DoH3・DoQ・DoT の待ち受けを1つのソフトウェアにまとめられ、アクセス制限やレート制限を共通のルールで書けるためです。後段のリゾルバーは Unbound や BIND など、普段使っているもので構いません。DoQ と DoH の待ち受けに対応しているのは dnsdist 1.9 以降で、ビルド時のオプションやパッケージによって有効な機能が異なるため、導入するパッケージの説明を確認してください。AdGuard Home や Technitium DNS Server のように、1つの製品で両方に対応しているものもあります。

事前準備

ホスト名と証明書

端末が接続先として指定するホスト名(例: dns.example.com)を1つ決め、その名前の証明書を用意します。DoQ と DoH は同じ証明書を共有できます。どちらも TLS 1.3 でハンドシェイクし、接続時の ALPN(DoQ は doq、DoH は h2 など)で方式を区別するためです。証明書は中間証明書を含む fullchain を使います。

ポートと Web サーバーとの関係

開けるポートは次のとおりです。

  • TCP 443: DoH(HTTP/2)
  • UDP 443: DoH3(使う場合のみ)
  • UDP 853: DoQ

注意が必要なのは、WordPress などの Web サイトを動かしているサーバーに同居させる場合です。nginx や Apache がすでに 443 番を使っていると、dnsdist は同じ IP アドレスの 443 番で待ち受けられません。対処としては次のような選択肢があります。

  1. DNS 用に別のサーバーか、別の IP アドレスを用意する(もっとも分かりやすい方法です)。
  2. DoH だけ別のポート(例: 8443)で待ち受け、端末側で URL にポートを含めて指定する。ただし、ポート指定に対応していない端末もあります。
  3. Web サーバーをリバースプロキシにして DoH を dnsdist へ渡す。dnsdist のドキュメントにリバースプロキシ配下での設定が説明されていますが、プロキシと dnsdist の間の HTTP のバージョンなど条件があるため、該当箇所を読んでから検証環境で試します。

DNS は止まると全サービスに影響するため、Web サイトの負荷や再起動の影響を受けない 1 の構成をおすすめします。

dnsdist の設定

作業前に既存の設定ファイルをバックアップし、検証用の環境で動作を確かめてから本番へ反映します。

-- /etc/dnsdist/dnsdist.conf(例)
-- 後段のリゾルバー
newServer({address="127.0.0.1:5300", name="unbound"})

local cert = "/etc/dnsdist/tls/fullchain.pem"
local key  = "/etc/dnsdist/tls/privkey.pem"

-- DoH(TCP 443、パスは /dns-query)
addDOHLocal("0.0.0.0:443", cert, key, "/dns-query")
-- DoH3(UDP 443。使う場合のみ)
addDOH3Local("0.0.0.0:443", cert, key)
-- DoQ(UDP 853)
addDOQLocal("0.0.0.0:853", cert, key)

-- 受け付ける送信元。dnsdist の既定ではプライベートアドレスなどしか許可されない
setACL({"127.0.0.0/8", "192.0.2.0/24", "198.51.100.0/24"})

-- 送信元ごとのレート制限(例: 1 秒あたり 50 件を超えたら破棄)
addAction(MaxQPSIPRule(50), DropAction())

-- 稼働中の確認用コンソール(ローカルからのみ)
controlSocket("127.0.0.1:5199")
setKey("your-console-key-base64")

設定のポイントは次のとおりです。

  • ACL は全入り口に共通です。 setACL で指定した範囲は DoH・DoQ のどちらにも効きます。dnsdist は既定でプライベートアドレスとループバックなどしか受け付けないため、社外の端末から使わせる場合はここを広げる必要があります。誰でも使えるリゾルバーとして公開するかどうかは、負荷や悪用対策、ログの扱いを含めて慎重に判断します。
  • ルールも全入り口に共通です。 addAction で書いたレート制限やフィルタは、どの方式で来た問い合わせにも適用されます。方式によって扱いを変えたい場合は、入り口を条件にしたルールを使います。ルールの書き方はバージョンで追加・変更があるため、ドキュメントで確認します。
  • 証明書ファイルの権限。 dnsdist の実行ユーザーが秘密鍵を読めるようにし、それ以外からは読めないようにします。
  • setKey の値はコンソールで makeKey() を実行して作るものです。記事中の値はダミーです。

設定の構文を確認してから再起動します。

sudo dnsdist --check-config
sudo systemctl restart dnsdist
sudo ss -lntup | grep dnsdist

ss の出力で、TCP 443、UDP 443(DoH3 を使う場合)、UDP 853 の3つが待ち受けになっていれば起動は成功です。続けて、ファイアウォールとクラウドのセキュリティグループで同じポートを許可します。UDP の許可を忘れると、DoH は使えるのに DoQ だけつながらない状態になります。

動作を確認する

端末側から、方式ごとに問い合わせます。kdig(Knot DNS のツール)は DoH と DoQ の両方に対応しています(DoQ はバージョン 3.3 以降)。

# DoQ
kdig @dns.example.com +quic +tls-ca +tls-hostname=dns.example.com www.example.com A

# DoH(パスを指定)
kdig @dns.example.com +https=/dns-query +tls-ca +tls-hostname=dns.example.com www.example.com A

# curl の名前解決を DoH 経由にして Web ページを取得する
curl --doh-url https://dns.example.com/dns-query -sI https://www.example.com/

サーバー側では、コンソールから後段のリゾルバーの状態と統計を見られます。

sudo dnsdist -c -e 'showServers()'
sudo dnsdist -c -e 'dumpStats()'

dumpStats() には方式ごとの問い合わせ件数などの項目が含まれます(項目名はバージョンで異なります)。DoH と DoQ の両方から問い合わせたあとで、それぞれの数字が増えているかを見ると、入り口ごとの動作を確かめられます。

端末に方式を知らせる(DDR)

端末が「このリゾルバーは DoH と DoQ に対応している」と自動で知る仕組みとして、DDR(Discovery of Designated Resolvers、RFC 9462)があります。リゾルバーが _dns.resolver.arpa という名前で SVCB レコードを返し、対応方式とホスト名を伝えます。

_dns.resolver.arpa. 300 IN SVCB 1 dns.example.com. alpn=h2 dohpath=/dns-query{?dns}
_dns.resolver.arpa. 300 IN SVCB 2 dns.example.com. alpn=doq

DDR を使って自動で暗号化 DNS に切り替える端末はまだ一部で、どの方式を選ぶかも端末によって違います。dnsdist や後段のリゾルバーで返す方法はソフトウェアごとに異なるため、導入する場合はそれぞれのドキュメントを確認してください。DDR を使わない場合は、端末ごとにホスト名と URL を手動で設定します。

運用で気を付けること

  • ログと個人情報。 問い合わせログには、誰がどのサイトを見たかに近い情報が含まれます。社外の利用者に提供する場合は、保存期間と利用目的を決め、プライバシーポリシーに記載します。必要がなければ送信元 IP アドレスを長く残さない設定にします。
  • 片方だけ止まる障害。 DoH は TCP、DoQ は UDP なので、ネットワーク側の変更で片方だけ通らなくなることがあります。監視は方式ごとに分けて行い、kdig +quic と kdig +https を定期的に実行して応答を確かめるとよいです。
  • 端末側のフォールバック。 端末によっては、暗号化 DNS が使えないと平文の DNS へ戻ります。戻らせたくない場合は、端末側の設定で「暗号化 DNS のみ」を選べるか確認します。

まとめ

  • DoH は対応端末が多く 443 番で通りやすい入り口、DoQ は遅延や再接続に強い入り口です。同じリゾルバーの前に両方を並べて併用します。
  • dnsdist では addDOHLocal・addDOH3Local・addDOQLocal で待ち受けを作り、同じホスト名の証明書を共有できます。
  • ACL やレート制限は全入り口に共通なので、まとめて管理できます。既定の ACL はプライベートアドレス中心である点に注意します。
  • Web サーバーと同じ IP アドレスでは 443 番が競合するため、DNS 用の IP アドレスかサーバーを分けるのが分かりやすい構成です。
  • 確認は kdig +quic と kdig +https、curl --doh-url で方式ごとに行い、監視も方式ごとに分けます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲