DNS over TLS を本番に持ち込む前に整理しておくこと
DNS クエリが平文のまま飛んでいることへの懸念は、以前から運用現場でたびたび話題になってきました。2026年現在、ISP レベルの DNS 傍受や広告挿入の事例は依然として報告されており、とくにクラウド VPC 外のエッジ拠点や在宅勤務端末を管理する担当者にとって、DNS over TLS(DoT)の導入は現実的な選択肢になっています。
一方で「設定してみたら名前解決が遅くなった」「フォールバックの挙動が読めない」という声も多く、本番投入を見送っている現場は少なくありません。本記事では stubby と systemd-resolved を組み合わせる構成を軸に、移行前の準備・計測・切り戻し判断まで一連の流れを整理します。
前提として扱う環境は Ubuntu 24.04 LTS および Debian 12(Bookworm)です。RHEL 系については末尾の差分セクションで補足します。
stubby と systemd-resolved の役割分担を理解する
systemd-resolved は systemd スタック標準のスタブリゾルバーで、Ubuntu 18.04 以降はデフォルトで有効です。127.0.0.53 でローカルクエリを受け、アップストリームへ転送します。DoT 対応は systemd 239 で追加され、現行の Ubuntu 24.04(systemd 255系)では DNSOverTLS=opportunistic または yes を設定するだけで動作します。
stubby は getdns ライブラリを基盤とするスタンドアロンの DoT フォワーダーで、RFC 7858 の厳密実装として知られています。systemd-resolved の DoT 実装がシンプルな一方、stubby は証明書ピン留め(SPKI ハッシュ)・接続プールの細かな制御・複数アップストリームへの同時クエリ(GETDNS_CONTEXT_TCP_SEND_BUFFER_SIZE 調整)といった機能を持ちます。
現場でよく採用される構成は「systemd-resolved をスタブとして残し、アップストリーム転送先を localhost:853 の stubby に向ける」二段構えです。アプリケーション側は既存の /etc/resolv.conf → 127.0.0.53 の流れを変えずに済み、DoT の処理は stubby が担います。移行コストが低い反面、stubby プロセスが落ちたときの挙動設計が必要になる点は後述します。
systemd-resolved 単体構成との比較
stubby を挟まず systemd-resolved だけで DoT を完結させる構成は、管理コンポーネントが減るという利点があります。/etc/systemd/resolved.conf に DNS= と DNSOverTLS=yes を書くだけで動作するため、小規模な固定サーバーや個人管理のクライアント端末にはこちらが適しています。ただし SPKI ピン留めが不要で、サーバー証明書の検証は OS の信頼ストアに依存します。厳格な証明書管理が求められる環境では stubby 経由を選ぶべきです。
移行手順:stubby + systemd-resolved の設定
まず stubby をインストールします。Ubuntu/Debian では apt install stubby で取得できます。2026年時点の安定版は 0.4.3 系です。
インストール後、/etc/stubby/stubby.yml を編集します。最低限変更すべき箇所は次のとおりです。
listen_addresses:127.0.0.1@853と0::1@853を指定(systemd-resolved からのループバック転送を受ける)upstream_recursive_servers: 利用する DoT プロバイダー(Cloudflare 1.1.1.1、Google 8.8.8.8、Quad9 9.9.9.9 など)の SPKI ハッシュを含む設定ブロックを記述round_robin_upstreams:1に設定し、複数アップストリームを均等利用
次に systemd-resolved のアップストリームを stubby に向けます。/etc/systemd/resolved.conf の [Resolve] セクションに以下を記述します。
DNS=127.0.0.1
DNSOverTLS=no
Domains=~.
ここで DNSOverTLS=no としているのは意図的です。systemd-resolved から stubby へのクエリはループバック内の平文転送であり、TLS は stubby がアップストリームとの間で担います。systemd-resolved 側で yes にすると stubby との接続が失敗します。
設定後は stubby を先に起動してから systemd-resolved を再起動します。順序を誤ると resolved が起動時にアップストリームへの接続試験を行い、stubby 未起動のまま代替 DNS にフォールバックすることがあります。
sudo systemctl enable --now stubby
sudo systemctl restart systemd-resolved
動作確認は resolvectl status でアップストリームが 127.0.0.1 になっていることを確認し、resolvectl query example.com で名前解決が通ることを見ます。stubby のログは journalctl -u stubby -f でリアルタイム確認できます。
名前解決遅延の計測と判断基準
DoT を導入すると TLS ハンドシェイクのコストが加わります。初回接続では 20〜80ms 程度の増加が観測される環境が多く、接続プールが温まった状態では平文 DNS と同等かそれ以下に収まることもあります。問題は「温まるまでの間」に遅延スパイクが発生するケースです。
計測には hyperfine を使った繰り返し計測が実用的です。
hyperfine --warmup 3 --runs 50 \
'resolvectl query --type=A example.com' \
'dig @1.1.1.1 example.com +time=2 +tries=1'
最初の3回をウォームアップに使い、50回の中央値・p95・p99 を比較します。stubby 経由の中央値が平文直接比較の2倍以上になる場合、接続プールの設定(idle_timeout の延長や num_conns の増加)を見直します。
キャッシュヒット率を分離して評価する
systemd-resolved はローカルキャッシュを持つため、同一ホスト名への反復クエリは DoT の遅延を受けません。計測時にキャッシュの影響を除外したい場合は resolvectl flush-caches をループ内で挟むか、dig で直接 stubby のリスニングポート(127.0.0.1#853)を指定します。
実運用での影響を把握するには、移行前後で同一の負荷条件下における HTTP リクエスト全体のレイテンシを比較する方法が現実に即しています。多くの現場では DNS が律速になるシーンは限定的で、p99 が 200ms 以内であれば本番継続の判断が取られます。
切り戻し手順とフォールバック設計
切り戻しのトリガーとなる代表的な状況は次のとおりです。
- stubby プロセスのクラッシュが頻発し、名前解決が断続的に失敗する
- 特定のアップストリームプロバイダーで障害が発生し、全クエリが詰まる
- p99 遅延が移行前比で3倍以上になり、アプリケーション側タイムアウトに影響する
即時切り戻しは stubby を停止し、resolved.conf のアップストリームを直接 DoT 対応リゾルバー(1.1.1.1#cloudflare-dns.com 形式)または平文 DNS に戻すだけです。
sudo systemctl stop stubby
# resolved.conf の DNS= を外部リゾルバーに変更後
sudo systemctl restart systemd-resolved
フォールバック設計として、systemd-resolved の FallbackDNS= に平文 DNS のアドレスを設定しておくことが推奨されます。stubby 停止時に resolved が自動的にフォールバックへ切り替わります。ただしこの挙動は「DoT が効かない状態でも名前解決は続く」ことを意味するため、セキュリティ要件が高い環境では意図的にフォールバックを無効化(FallbackDNS= を空にする)し、障害時は明示的な切り戻し操作を必要とする設計にすることもあります。
stubby の自動再起動は systemd のサービスユニットで Restart=on-failure と RestartSec=3 を設定しておくと、一時的なクラッシュからの復帰が自動化されます。永続的な障害かどうかは systemctl show stubby --property=NRestarts で再起動回数を見て判断します。
2026年現行環境での差分と注意点
Ubuntu 24.04(Noble)では systemd-resolved の DNS ドメインルーティング機能が強化され、VPN 接続時に特定ドメインを社内リゾルバーに向けつつ、残りを DoT 経由でパブリックリゾルバーに流す構成がより安定して動作します。resolvectl domain コマンドでインターフェースごとのドメインスコープを確認しながら調整します。
RHEL 9 / AlmaLinux 9 系では systemd-resolved はデフォルトで無効のため、stubby を単独で動かして /etc/resolv.conf を直接書き換える構成が一般的です。NetworkManager の dns プラグインを none に設定し、stubby が 127.0.0.1:53 でリッスンする構成にします。
コンテナ環境(Docker / containerd)では、ホストの systemd-resolved の設定がコンテナの名前解決に影響しないケースが多く、コンテナ内の /etc/resolv.conf は Docker デーモンが管理します。DoT をコンテナワークロードまで適用したい場合は、CoreDNS を DoT フォワーダーとして Kubernetes クラスター内に配置する構成が 2026 年の標準に近づいています。
DNS over HTTPS(DoH)との比較では、DoT はポート 853 を使うため企業ファイアウォールでブロックされやすいという現実があります。ファイアウォールポリシーを変更できない環境では、stubby の代わりに cloudflared や dnscrypt-proxy を DoH フォワーダーとして使う構成も選択肢です。ただし DoH はトラフィックが HTTPS と混在するため DPI による識別が難しく、セキュリティチームとの合意形成が必要になる場合があります。
DNSSEC との併用は特に問題なく動作しますが、stubby の dnssec_return_status を GETDNS_EXTENSION_TRUE にすると DNSSEC 検証の失敗がクエリエラーになるため、既存インフラで DNSSEC が不整合になっているドメインがある場合は段階的に有効化することを推奨します。まずは dnssec_return_only_secure を無効にしたままで運用し、ログで検証結果を確認してから有効化するのが安全です。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
PR・広告
Linuxで動かしながら学ぶTCP/IPネットワーク入門(Amazon)
IPアドレス・ルーティング・名前解決などネットワークの基礎をLinux上で手を動かして学べる入門書。
※ Amazonのアソシエイトとして、当サイトは適格販売により収入を得ています。
