2026年6月18日
2026年6月18日
DoT (DNS over TLS) と DoQ (DNS over QUIC) を併用する設定|853番の TCP と UDP で両方を待ち受け、端末ごとに使い分ける
DoT と DoQ は、どちらも標準のポート番号が 853 番で、DoT は TCP、DoQ は UDP を使います。そのため、1台のサーバーの同じ IP アドレスで両方を待ち受け、証明書と後ろのリゾルバーを共有する形で併用できます。対応端末が多い DoT を基本の入り口にし、対応したアプリや DNS プロキシには DoQ を使わせる、というのが現実的な組み合わせです。この記事では、併用する理由、dnsdist と AdGuard Home での設定例、ファイアウォールと証明書の扱い、クライアント側で片方が止まったときに切り替える設定、方式ごとの監視までを説明します。
併用する理由
DoT(RFC 7858)と DoQ(RFC 9250)は、端末とリゾルバーの間の DNS を暗号化する点では同じですが、得意な場面が違います。
- DoT は TCP の上で TLS を使います。Android の「プライベート DNS」が DoT に対応しているほか、Unbound や systemd-resolved など、サーバー側の DNS ソフトウェアでも上流への接続方式として広く使われています。
- DoQ は QUIC(UDP)の上で動きます。1つの問い合わせの遅れが後続の問い合わせを待たせにくく、通信環境が変わったときの再接続も軽いため、モバイル回線などで利点があります。一方で、OS が標準で DoQ に対応している例はまだ少なく、主に対応アプリや DNS プロキシから使われています(2026年10月現在)。
DoQ だけを提供すると使える端末が限られ、DoT だけを提供すると DoQ の利点を活かせません。両方を並べ、端末の対応状況に合わせて選ばせるのが併用の目的です。さらに、DoT は TCP、DoQ は UDP なので、ネットワーク側の都合でどちらか一方が通らない環境でも、もう一方で名前解決を続けられる可能性があります。
構成の全体像
端末(DoT) ── TCP 853 ──┐
├─ 入り口(dnsdist など)── 127.0.0.1:5300 ── リゾルバー(DNSSEC 検証・キャッシュ)
端末(DoQ) ── UDP 853 ──┘
入り口と後ろのリゾルバーを分けておくと、暗号化の処理とキャッシュ・検証の処理を別々に調整でき、後ろのリゾルバーは普段使っている Unbound や BIND をそのまま使えます。1つのソフトウェアで両方の待ち受けとリゾルバーの機能を持つ製品(AdGuard Home や Technitium DNS Server など)を使う方法もあります。
なお、Unbound は比較的新しい版で DoQ の待ち受けにも対応していますが、ビルド時に QUIC のライブラリを組み込む必要があり、配布パッケージでは無効になっていることがあります。BIND は DoT と DoH の待ち受けに対応していますが、DoQ の待ち受けに対応しているかは版ごとの文書で確認してください。
事前準備
ホスト名と証明書
端末が接続先として指定するホスト名(例: dns.example.com)を1つ決め、その名前で証明書を取得します。DoT は TLS、DoQ は QUIC に組み込まれた TLS 1.3 でサーバーを認証するため、同じ証明書と秘密鍵を共有できます。DoQ は接続時の ALPN で doq を名乗るため、同じ 853 番でも方式が混ざることはありません。証明書は中間証明書を含む fullchain を使います。
Let's Encrypt などで証明書を自動更新する場合は、更新後に入り口のソフトウェアへ新しい証明書を読み込ませる処理(再読み込みや再起動)を、更新の後処理として登録しておきます。DoT だけ新しい証明書になり、DoQ が古い証明書のまま期限切れになる、という片側だけの事故を防ぐためです。
ポートとファイアウォール
開けるのは次の2つです。
- TCP 853:DoT
- UDP 853:DoQ
# ufw の例。送信元を絞る場合は from で範囲を指定する
sudo ufw allow proto tcp from 198.51.100.0/24 to any port 853
sudo ufw allow proto udp from 198.51.100.0/24 to any port 853
クラウドのセキュリティグループやネットワーク境界のファイアウォールでも、TCP と UDP を別々に許可する必要があります。UDP の許可を忘れて「DoT は使えるのに DoQ だけつながらない」状態になるのが、もっとも多い設定漏れです。
dnsdist で両方を待ち受ける
dnsdist は DoT の待ち受け(addTLSLocal)と DoQ の待ち受け(addDOQLocal)を持っています。DoQ は dnsdist 1.9 以降の機能で、パッケージによって有効な機能が異なるため、導入するパッケージの説明を確認してください。作業前に既存の設定ファイルをバックアップします。
-- /etc/dnsdist/dnsdist.conf(例)
newServer({address="127.0.0.1:5300", name="resolver"})
local cert = "/etc/dnsdist/tls/fullchain.pem"
local key = "/etc/dnsdist/tls/privkey.pem"
-- DoT(TCP 853)
addTLSLocal("0.0.0.0:853", cert, key)
addTLSLocal("[::]:853", cert, key)
-- DoQ(UDP 853)
addDOQLocal("0.0.0.0:853", cert, key)
addDOQLocal("[::]:853", cert, key)
-- 受け付ける送信元(既定ではプライベートアドレスなどに限られる)
setACL({"127.0.0.0/8", "198.51.100.0/24"})
-- 送信元ごとのレート制限(例: 1 秒あたり 50 件を超えたら破棄)
addAction(MaxQPSIPRule(50), DropAction())
-- ローカルからだけ使える管理コンソール
controlSocket("127.0.0.1:5199")
setKey("your-console-key-base64")
setACL と addAction のルールは、DoT と DoQ の両方の入り口に共通で効きます。方式ごとに別の扱いをする必要がなければ、ルールを1か所で管理できるのが dnsdist を使う利点です。setKey の値は、コンソールで makeKey() を実行して作るもので、記事中の値はダミーです。
sudo dnsdist --check-config
sudo systemctl restart dnsdist
sudo ss -lntup | grep ':853'
ss の出力に TCP と UDP の両方の 853 番が表示されていれば、待ち受けは成功です。証明書を更新したあとは、コンソールの reloadAllCertificates() で再起動せずに読み込み直せます。
sudo dnsdist -c -e 'reloadAllCertificates()'
AdGuard Home で両方を提供する場合
AdGuard Home は、暗号化の設定で証明書を登録すると、DoT と DoQ(あわせて DoH)を同じ証明書で提供できます。設定ファイル AdGuardHome.yaml の tls の項目では、DoT と DoQ のポートを別々に指定でき、通常はどちらも 853 番です。管理画面の項目名や配置は版で変わるため、目的(証明書の登録と、DoT・DoQ のポート指定)を手がかりに探してください。設定を変える前に AdGuardHome.yaml のバックアップを取ります。
AdGuard Home を誰でも使える状態で公開すると、悪用や負荷の問題が起きます。許可する送信元を設定で絞るか、ファイアウォールで制限します。
クライアント側で併用する
サーバー側を用意したら、クライアントがどちらを使うかを決めます。
- Android:「プライベート DNS」にホスト名(
dns.example.com)を入れると DoT で接続します。DoQ は使いません。 - Unbound を上流への中継に使うサーバー:上流への接続は DoT に対応しており、
forward-tls-upstream: yesで使えます。上流への DoQ には対応していないため、Unbound からは DoT を使います。 - DNS プロキシ(AdGuard Home、dnsproxy など):上流を複数並べられるため、DoQ と DoT を両方登録しておくと、片方が止まってももう片方で名前解決を続けられます。
# AdGuard Home の上流 DNS サーバーの欄に書く例(1行に1つ)
quic://dns.example.com
tls://dns.example.com
複数の上流をどう使い分けるか(並列に問い合わせる、速い方を選ぶ、順番に使うなど)は、製品の設定で選びます。選び方の名前やオプションは版で異なるため、使っている版の文書で確認してください。
端末に「このリゾルバーは DoT と DoQ に対応している」と知らせる仕組みとして、DDR(RFC 9462)の SVCB レコードで alpn=dot と alpn=doq を告知する方法もあります。ただし、DDR で自動的に暗号化 DNS に切り替える端末はまだ一部です。
動作を確認する
方式ごとに、クライアントの立場で問い合わせます。Knot DNS に付属する kdig は DoT と DoQ の両方に対応しています(DoQ はバージョン 3.3 以降)。
# DoT
kdig @dns.example.com +tls-ca +tls-hostname=dns.example.com www.example.com A
# DoQ
kdig @dns.example.com +quic +tls-ca +tls-hostname=dns.example.com www.example.com A
+tls-ca はシステムの CA で証明書を検証する指定、+tls-hostname は照合するホスト名の指定です。証明書の検証を外した状態で成功しても、端末では失敗することがあるため、検証付きで確かめます。サーバー側では、dnsdist のコンソールで dumpStats() を実行し、方式ごとの件数が増えているかを見ます(項目名は版で異なります)。
運用で気を付けること
- 監視は方式ごとに分ける。 TCP と UDP は別々に止まり得るため、上の
kdigを定期的に実行し、DoT と DoQ を別の監視項目にします。 - 証明書の期限も方式ごとに確かめる。 同じ証明書を共有していても、読み込み直しが片方だけ漏れることがあります。
- ログと個人情報。 問い合わせログには、誰がどのサイトを見たかに近い情報が残ります。社外の利用者に提供する場合は、保存期間と目的を決めてプライバシーポリシーに記載し、不要な送信元 IP アドレスを長く残さないようにします。
- 平文へのフォールバック。 端末によっては、暗号化 DNS がつながらないと平文の DNS に戻ります。戻らせたくない場合は、端末側で暗号化 DNS のみを使う設定があるかを確認します。
設定の変更は検証用の環境で試し、端末を数台つないで両方式の動作を確認してから本番に反映してください。
まとめ
- DoT は TCP 853、DoQ は UDP 853 を使うため、同じ IP アドレスで両方を待ち受け、証明書とリゾルバーを共有して併用できる
- 対応端末の多い DoT を基本にし、対応アプリや DNS プロキシには DoQ を使わせる
- dnsdist では
addTLSLocalとaddDOQLocalを並べ、ACL とレート制限を共通で管理できる - ファイアウォールは TCP と UDP を別々に許可し、証明書の読み込み直しも両方に効いているかを確かめる
- クライアント側では DoQ と DoT を両方登録して切り替えられるようにし、監視も方式ごとに分ける