DNS over HTTPS/TLS (DoH/DoT)の設定方法

2023年10月05日 木曜日


【この記事を書いた人】
やまぐち

アプリケーションサービス部所属。そのへんのおっさん。

「DNS over HTTPS/TLS (DoH/DoT)の設定方法」のイメージ

はじめに

DNS over HTTPS/TLS (DoH/DoT)の設定の話をします。何言ってやがんだ、設定なんて画面からポチポチいじるだけやろ読むまでもない、と思ったあなた、甘いです。

DoH/DoTの前に、まずDoH/DoTではない、通常のDNSってどうやって設定しますか?

何言ってやがんだ、設定画面からポチポチいじるだけやろ、と思ったあなた、甘いです。そうやってする設定は、あくまで「デフォルトと異なるDNSサーバを利用するための設定」です。そんなことしなくてもデフォルトのDNSサーバは設定されていて使えるのです。じゃあデフォルトのDNSサーバはどうやって設定されているんでしょうか?

こたえは、「DHCPやIPv6 RAやPPPなど、IPアドレスを自動設定するプロトコルでDNSサーバの情報もいっしょに配布されるのでそれを設定している」です(※1)

話を戻しましょう。DoH/DoTってどうやって設定するんでしょうか? 設定画面からポチポチいじるんじゃなくて、自動的にDoH/DoTが使われるようにする方法ってありましたっけ?

DDRとDNR

このエンジニアブログでDoH、DoTについて最初に取り上げてからもう4年になります。あれから各種ブラウザやOSでの対応も進み、気軽に使えるようになってきました。

……と思うのは早計で、実は重要な機能が欠けています。

インターネット黎明期ならともかく、今ではDNSの設定を手作業ですることはめったにありません。有線でも無線でも、端末をネットワークにつないだら自動でIPアドレスやDNSの情報が降ってきて、自動で設定されます。しかし、DoH/DoTの設定を自動化できる仕組みはありませんでした。組織内部のネットワークで利用するためのDoHサーバを作っても、ネットワーク管理者がDoHサーバの情報を自動配布することはできず、ユーザが設定を手作業でおこなわなければならないのです。手作業だとどうしても設定ミスが発生する可能性があってサポートコストが上がるし、設定変更も手作業になるのでユーザの数が多いとDoHサーバの移行が困難になります。DoH/DoTは、従来のDNSほど成熟してはいないのです。

なので、ちゃんと設定を自動配布できるようにする仕組みが作られました。DDR (Discorvery of Designated Resolvers)とDNR (Discovery of Network-designated Resolvers)のふたつです。どちらもまだRFCにはなっていませんが、それぞれRFC9462RFC9463としてもうまもなく(たぶん今月中には)標準化される見込みです(リンク先は本稿執筆時点では存在しませんが、正式にRFCになると作成されるはず)。

DDRによるDoH/DoT自動設定の流れはこんな感じ。

1. 従来の方法(DHCPとかIPv6 RAとかPPPとか手動設定とか)でDo53サーバの情報を取得する
2. そのサーバに対して、「DoH/DoTサーバの場所を教えてくれー」という特殊なクエリを投げる
3. その応答に含まれるDoH/DoTサーバを利用する

DDRの手順はDo53 (DNS over UDP/TCP port 53; 暗号化されていない従来のDNSのこと)を使ってやりとりされるので、つまり将来的にDoH/DoTが常識という世の中がやってきたとしても、DDRが使われるかぎりはDo53を廃止できないことを意味します。

一方DNRは、DHCPやIPv6 RAで直接DoH/DoTサーバの情報を通知できるようにするためのオプションを新設しようというもの。DDRと異なりDNRはDo53に依存しませんが、DNRの対象プロトコル以外で設定する場合(PPPや手動設定)はDoH/DoTサーバの情報を得ることはできません。

ちなみに、DDRで使われるDo53はもちろん暗号化されておらず、DNRで使われるDHCPやIPv6 RAも暗号化されません。つまり、中間者攻撃によってDDR/DNRのやりとりを妨害してDoH/DoTを使わせない(=Do53を強制させる=盗聴できる)ようにしたり、DDR/DNRの応答を改竄して不正なDoH/DoTサーバに誘導したりすることへの防御がありません。ぶっちゃけこれはどうしようもないです。ネットワークに接続する前、何が信頼できて何が信頼できないかを判断するための情報を得られるようになる前に使われるプロトコルなので、受け取った情報を信じるしかないのです。ここが疑わしいネットワークにはそもそも接続するな、ということですね。もっとも、ここが信用できるネットワークなのであれば、DNSも暗号化せず平文のままでもそれほど問題はないんですが。

DDR in the wild

で、DDRのプロトコルで使われる「DoH/DoTサーバの場所を教えてくれー」という特殊なクエリが、昨年の秋ごろから実環境でも観測されるようになっています。前述のとおりDDRは正式にはまだRFCになっていないプロトコルなのですが、かなり早いうちからAppleが対応を表明していて、iOS16/macOS13から使えるようになっているのです。手元のunboundに記録されていたログがこちら(Oct 25ってのは今年じゃなくて昨年の10月です)。

Oct 25 11:17:53 dock unbound[43061]: [43061:0] info: 192.168.11.4 _dns.resolver.arpa. TYPE64 IN

この _dns.resolver.arpa に対するTYPE64 (SVCB)のクエリがそれです。SVCBレコードというのは、HTTPSレコードをHTTP以外のプロトコルでも汎用的に使えるようにしたもので(※2)、こちらもDDR/DNRと同日にRFC9460としてリリースされるはずです(リンク先は正式にRFCになった後に出現します)。

ちなみにApple以外では、WindowsはInsider ProgramでDDRが使えるようです(が、デフォルト無効で、有効にするには手動で設定変更する必要があるようです。それじゃ自動設定の意味なくない?)。AndroidはDDRに対応予定とは表明されていますが、時期については”in the future”というだけで、具体的にいつになるかは現時点では不明です。また、DNRについては今のところ実装について具体的な話は聞こえてきません。

DDRのクエリを受けて応答するキャッシュDNSサーバとしては、Cloudflareの1.1.1.1が対応しています

> kdig +noall +ans @1.1.1.1 _dns.resolver.arpa svcb

;; ANSWER SECTION:
_dns.resolver.arpa. 300 IN SVCB 1 one.one.one.one. alpn=h2,h3 port=443 ipv4hint=1.1.1.1,1.0.0.1 ipv6hint=2606:4700:4700::1111,2606:4700:4700::1001 key7="/dns-query{?dns}"
_dns.resolver.arpa. 300 IN SVCB 2 one.one.one.one. alpn=dot port=853 ipv4hint=1.1.1.1,1.0.0.1 ipv6hint=2606:4700:4700::1111,2606:4700:4700::1001

この応答を意訳すると「DoH/DoT両方に対応してるけど、DoHの方を優先して使ってね、DoHはHTTP/2とHTTP/3が使えるよ」とのことです。DoH URLのパス部分はRFC9461(これもDDR/DNRと同日にRFCになる見込み)にkdigが未対応なので key7=”…” と表示されていますが、対応すれば dohpath=”…” と表示されるはずです。

また、公式にアナウンスはされていない(?)ようですが、Google Public DNSやQuad9もDDRに対応しています。これらはDoTの方を優先してくれと言ってますね。

> kdig +noall +ans @8.8.8.8 _dns.resolver.arpa svcb

;; ANSWER SECTION:
_dns.resolver.arpa. 86400 IN SVCB 1 dns.google. alpn=dot
_dns.resolver.arpa. 86400 IN SVCB 2 dns.google. alpn=h2,h3 key7="/dns-query{?dns}"

> kdig +noall +ans @9.9.9.9 _dns.resolver.arpa svcb

;; ANSWER SECTION:
_dns.resolver.arpa. 	60	IN	SVCB	1 dns.quad9.net. alpn=dot port=853 ipv4hint=9.9.9.9,149.112.112.112 ipv6hint=2620:fe::fe
_dns.resolver.arpa. 	60	IN	SVCB	2 dns.quad9.net. alpn=h2 port=443 ipv4hint=9.9.9.9,149.112.112.112 ipv6hint=2620:fe::fe key7="/dns-query{?dns}"

ということで、最近のiOSとmacOSでは、DNSサーバとしてCloudflareの1.1.1.1やGoogle Public DNSの8.8.8.8、Quad9の9.9.9.9を手動設定していると、実際に使われるのはDo53ではなくDoHやDoTになります。

なおmacOSでは、DDRによりDoHを使うようになっていても、ChromeについてはDo53が使われることがあります。これは、Chromeは名前解決に自前の内蔵スタブリゾルバを利用し、OSの仕組みを使っていないためです。別途Chrome側で設定する必要があります。

DDR/DNR以外の自動設定の仕組み

このように自動設定のプロトコルとしてDDR/DNRが標準化されましたが、実はこれ以前にも自動設定する試みはありました。

プライベートDNSの自動設定

まず、Android9以降には、ネットワークの設定にプライベートDNSなるものがあります。プライベートDNSとは聞きなじみがありませんが、これは実はDoTのことです。で、このプライベートDNSの設定では「自動」を選択することができます。つまり、AndroidではDoTの自動設定がサポートされているのです。

AndroidがどうやってDoTを自動設定するかというと、Do53用に設定されているサーバのIPアドレスにDoTで接続を試してみて、使えるようなら以後DoTを使う、というわりと単純なものです。

ただ問題もあって、まず、Do53とDoTのサーバを分離しようと思ってもできません。かならず同一IPアドレスで一体運用されなければなりません。とはいえこれはサーバ運用する側が苦しむだけの話で、ユーザには関係ありません。

どうにもならないのが証明書の問題です。DoTはTLSを使うのでサーバ証明書が必要ですが、証明書はホスト名で取得するのが一般的です。しかし、Do53サーバはIPアドレスで設定します。つまり、証明書が正しいか検証しようにも、証明書のSAN (SubjectAltName)として使われるホスト名を事前に知ることができず、検証不可能なのです。結果として、AndroidのプライベートDNS自動設定ではサーバ証明書の検証を放棄していて、とりあえずルートCAからチェーンがつながってさえいれば、SANは何でもいいという実装になっているようです(厳密な調査はしていないので他にも条件があるかもしれません)。IPアドレス証明書というのも存在しないわけではないですが、発行してくれるCAは多くなく(たとえばLet’s Encryptは非対応)、わざわざ取得したところでAndroidはそれをチェックしないのだから意味がありません。もっとも、opportunistic encryption(日和見暗号化)な手順なので、証明書を厳格に検証する意義はそれほど大きくありません。

Same Provider Auto Upgrade

DoHの自動設定の仕組みとしては、Same Provider Auto Upgradeなる試みがあります。これは、Do53のサーバとDoHのサーバを同じ管理者(same provider)が提供しているとき、クライアントの使うDNSサーバとしてDo53サーバが設定されていたら自動的にDoHの方を使う(auto upgrade)というものです。具体例を挙げると、DNSサーバとして8.8.8.8 (Google Public DNS)を使うよう設定されていた場合、実際の名前解決は8.8.8.8へのDo53ではなく、同じGoogle Public DNSが提供する https://dns.google/dns-query へのDoHを使う、ということです。この仕組みはブラウザとしてChromeが、OSとしてWindowsが対応しています。

これはChromeの設定画面ですが、セキュアDNSというのが実はDoHのことです(プライベートDNSもそうですが、勝手な用語を作るのはやめてくれませんかねGoogleさん)。「現在のサービス プロバイダを使用する」というのが、つまりsame providerでDoHが使えるならauto upgradeするよ、という意味になります。

ところで、DHCPなどから得られるDNSサーバの情報は、あくまでDo53サーバのIPアドレスだけです。DoHサーバのURLの情報なんてどこにもありません。プライベートDNSの自動設定のように同一IPアドレスを決め打ちしたとしても、DoHではそれだけでは不足で、URLパス(/dns-queryの部分)の情報がわかりません。わかるならDDR/DNRなんていりません。では、わからないのに「8.8.8.8が設定されたらかわりに https://dns.google/dns-query を使う」という動作をどうやって実現しているのでしょうか?

こたえは「事前に対応リストを持つ」です。大手のpublic DNSであれば、Do53サーバのIPアドレスと、それに対応するDoHサーバのURLのリストがはじめからChromeやWindowsの中に内蔵されています。

なので、対応リストに含まれていないDoHサーバ、たとえば自前構築のサーバをSame Provider Auto Upgradeに対応させるには、まず対応リストを書き換えるというひどくめんどうな作業が必要になります。Chromeなら自分でソースを書き換えてコンパイルしなおすかあるいはChrome本家にソースを書き換えてもらって全世界的にリリースしてもらう必要がありますし(詳細)、WindowsではDNS設定が自動になっているとauto upgradeが使えないのでまず手動設定に変更して(いや、自動設定したいんですけど…)、さらにGUIではなくCLIで自前DoHサーバを対応リストに追加するという手順を踏む必要があります(詳細)。めちゃくちゃめんどうですね。設定の手間をはぶくために自動設定するはずなのに、実際は手動設定の方が100倍ラクです。事前に対応リストに入れてもらえる大手事業者優遇の仕組みといっていいでしょう。

また、家庭用ルータのDNSフォワーダー機能も問題になります。ISPのキャッシュDNSサーバがDoHに対応し、ChromeやWindowsが持っている対応リストに入れてもらえたとしても、家庭用ルータがLAN内の端末に配るDNSサーバのIPアドレスは、ISPのキャッシュサーバのものではなく、ルータ自身のプライベートアドレスになります。ルータのIPアドレスは当然ChromeやWindowsの対応リストには含まれていないので、auto upgradeが機能せず、Do53しか使われないことになります。

iOS/macOSでIIJ Public DNSを使いたい

さて、前述のとおりiOS/macOSはDDRに対応しており、これを利用することでDoH/DoTを使うことができます。つまり、iOS/macOSはDoH/DoTに対応済みです。

それでは問題です。iOS/macOSで、自動ではなく、手動でDoH/DoTを設定するにはどうすればいいのでしょうか?

何言ってやがんだ、手動なら今度こそ設定画面からポチポチいじるだけやろ、と思ったあなた、甘いです。実は、iOS/macOSにはDoH/DoTの設定画面なんてものは存在しないのです。嘘だと思うなら探してみてください。DoH/DoTに対応はしているけれど、ポチポチいじって設定する方法がないのです。

そして、弊社もCloudflare 1.1.1.1やGoogle Public DNSやQuad9と同じようにIIJ Public DNSというサービスを提供しています。CloudflareやGoogleやQuad9と同じようにDDRを使えばiOS/macOSでDoH/DoTを使えるよ、と言いたいところなんですが、CloudflareやGoogleやQuad9とは異なり、IIJ Public DNSはDoH/DoT専用で、Do53をサポートしていません。前述のとおりDDRはDo53を利用するプロトコルなので、Do53非対応のIIJ Public DNSではどう逆立ちしてもDDRに対応できません(サービスはじめたころにDDRなんてプロトコルは影も形もなかったもん……)。

iOS/macOSはDoH/DoTの手動設定ができない。IIJ Public DNSではDDRによる自動設定もできない。じゃあ、iOS/macOSでIIJ Public DNSを使う方法はないの?

そんなことはありません。人間がポチポチいじる設定画面は存在しませんが、プロファイルを読み込ませるという方法で設定はできるのです。構成プロファイルはMDM (mobile device management; 企業などで端末を集中管理する仕組み)と組み合わせて自動設定する用途で使われることが多いですが、手作業で読み込ませることもできます。

ということで、IIJ Public DNSのサイトからiOS/macOS用の構成プロファイルをダウンロードできるようにしておきました。具体的な設定方法についてはこちらをご覧ください。プロファイルは未署名と表示されますが、とくに問題なく利用できます。実体はただのテキストファイル(XML)なので、気になる方は中を確認してみてください。適切に書き換えればIIJ Public DNS以外のDoH/DoTサーバを使うプロファイルを作成することもできます。

なお、SafariやFirefoxはこの方法でDoH/DoTになりますが、前述のとおりChromeはOS側の用意したスタブリゾルバを使わず、自前の内蔵スタブリゾルバを使って名前解決するので、この方法ではDoH/DoTは使われません。Chrome側に設定が必要です。

まとめ

DoH/DoTはまだまだ発展の途上にあって、これまでは実質的に大手public DNS事業者専用に近いプロトコルでした。しかし、普及の大きな妨げになっていた「どうやって端末に設定するか」という極めて基本的な問題がようやく解決されようとしています。DDR/DNRはついにRFCになります。これに対応した実装が普及することで、public DNS以外でもDoH/DoTサーバが増えていくことになるでしょう。

DoH/DoTのプロトコルはまだこれで終わりではありません。さらにまだ権威サーバの暗号化対応という大きなタスクが残っており、こちらもインターネットドラフトが出て、議論が詰めの段階に入ってきています(※3)。暗号化DNSが成熟したものになるにはもう少し時間がかかることでしょう。


  1. 厳密には、PPPの中で使われるIPCPというプロトコルでIPアドレスやDNSサーバの設定が配布されます。[↑]
  2. 実際は主客が逆で、SVCBレコードのHTTP専用版がHTTPSレコード。[↑]
  3. ここでは詳しく説明はしませんが、あまり期待しないほうがよさそうです(筆者はがっかりしています)。[↑]

やまぐち

2023年10月05日 木曜日

アプリケーションサービス部所属。そのへんのおっさん。

Related
関連記事