VPNサーバーで暗号化DNSを有効にすることは、漏えいを塞ぐことだとよく説明されますが、その説明はどの接続が変わったのかを隠しています。クライアントからリゾルバーへのホップと、リゾルバーから上流へのホップは、別々の所有者を持つ別々の接続です。片方を暗号化しても、もう片方はまったく変わらないままです。

設定ファイルに触れる前に、各段階で誰がクエリを受け取るのかを書き出してください。

二つの構成は設定画面では同じに見える

第一の構成では、端末自身がDNS over TLSを実行し、トンネルはその接続を選んだリゾルバーまで運ぶだけです。TLSセッションはリゾルバーで終わるため、リゾルバーはクエリを見ますが、VPNの出口が見るのは読めない暗号文です。第二の構成では、端末が通常のDNSをトンネル経由でVPNホスト上のフォワーダーに送り、そのフォワーダーが上流リゾルバーへの独自の暗号化接続を開きます。機能一覧ではどちらも「VPNによる暗号化DNS」に見えますが、読めるクエリを置く建物は異なります。

違いは哲学的ではなく測定可能です。クライアント側でTLSセッションを探すか、サーバー側で探すかで、実際にどちらの構成なのかが分かります。

変更する前にリゾルバーの連鎖を地図にする

経路上のリゾルバーを数え、それぞれの役割を名指ししてください。転送コンポーネントは要求を別のリゾルバーに渡し、再帰リゾルバーは答えを見つける作業を行い、権威サーバーと直接話すこともあります。これらの役割が別々に定義されているのはまさにこの理由であり、RFC 9076のリゾルバー定義は、上流の宛先が一つだけ存在すると決めつける前に読む価値があります。独自の再帰リゾルバーを動かすホストには暗号化すべき単一の「上流」が存在せず、計画全体が意味を失います。

次に、クライアントがどのコンポーネントを使うよう設定されているかを確認します。VPNプロファイルが配るDNSアドレスは、クエリがどこへ行くかを示すもので、どのプロセスが答えるかは示しません。

障害時の挙動にも注目してください。暗号化された上流に到達できなくなったとき、フォワーダーは閉じた状態で失敗するのか、平文に戻るのか、別のリゾルバーに切り替わるのか。この判断は記録に残すべきです。トンネルが最も不健全な瞬間に、プライバシーの保証が変わるからです。

どのホップが暗号化されているかを確認する

クライアントから始めて、ポート853へのTLSセッションを保持しているかを確認します。ポート53で正しく解決できるクエリは、暗号化について何も証明しません。

resolvectl status | grep -E "DNS Servers|DNS over TLS"
kdig +tls +tls-ca +tls-hostname=dns.example.net @198.51.100.53 example.com A

次にVPNホストへ移動し、フォワーダーが開いた外向きの暗号化接続を探します。ソケットテーブルを見れば、上流のTLSセッションが存在するか、どのプロセスが所有しているかが分かります。

ss -tunp '( dport = :853 )'
dig @127.0.0.1 example.com A +short

クライアントにTLSセッションがあり、サーバーにないなら、第一の構成であり、サーバーはIP層で転送するクエリを読めません。サーバーにTLSセッションがあり、クライアントがトンネル内でポート53の通常の通信を示すなら、第二の構成です。次のホップは保護されていますが、フォワーダーは端末が尋ねるすべての名前を依然として読んでいます。この第二の結果は失敗ではありませんが、それを端末間の暗号化と呼ぶのは誤りです。

所有者と障害時の挙動を記録する

所有権が、何を約束してよいかを決めます。端末の所有者はクライアント側の暗号化接続を管理し、VPN管理者はフォワーダーが作る次の接続を管理します。どちらも運用していない人は、経路を説明することしかできません。

何かを有効にする前に、内部の名前解決を確認してください。組織の名前を公開リゾルバーへ送るのは同等の設計ではなく、ネットワーク内にしか存在しないsplit-horizonゾーンは上流ではまったく解決されません。変更後に内部名と公開名を一つずつ試し、その結果を設定変更と一緒に保管してください。暗号化経路が内部ホストの解決を壊す場合、修正はより広いトンネルではなく、範囲を限定したリゾルバールールです。

最後に、ホップごとに一文を書いてください。どのコンポーネントがクエリを受け取ったか、そのホップが暗号化されていたか、誰が名前を読めるか。VPNホストについての文が今もクエリを読めると述べているなら、文書もそう述べるべきです。そうでないと主張する図は、コマンドを一度も実行していない人に信じられてしまいます。

関連記事