Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What is going on with this article?
@girlfellfromsky

セキュリティの尻隠して頭隠さず...?Androidに実装されている「プライベートDNS」を利用しよう

本日のお題。
セキュリティの穴、DNSを何とかしましょう!

自宅用DNSサーバーを構築してからDNSがマイブームな今日この頃、プライベートDNSについての記事に出会いました。
以前から有効にはしていましたが、どんな動作をしているのか気になって調査してみました。

プライベートDNSとは?

Android 9 (Pie)以降のスマートフォンに実装されている機能で、以下のような感じでアクセスできると思います。

  • 設定その他の接続プライベートDNS
  • 設定ネットワークとインターネットプライベートDNS
  • 設定ネットワークとインターネット詳細設定プライベートDNS

取り敢えずはプライベートDNSを設定を選択してdns.googleone.one.one.oneなどと打ち込むと設定が完了します。
ほぼ同様の内容ですが、Google Public DNSに詳しい説明が記載されています。
なお、自動に設定した場合は、設定中のDNSサーバーが本機能に対応している場合に有効となります。

どういう機能?

Android Developers Blogによりますと...

Like HTTPS, DNS over TLS uses the TLS protocol to establish a secure channel to the server. Once the secure channel is established, DNS queries and responses can't be read or modified by anyone else who might be monitoring the connection. (The secure channel only applies to DNS, so it can't protect users from other kinds of security and privacy violations.)

要するに、DNSの問い合わせを安全にしようってことらしいです。

「DNSってなーに?」
DNSとは、電話でいうところの104番です。
104をダイヤルして「東京特許許可局の電話番号を教えてください。」と言えば「xxxx-xx-xxxxです。」と教えてくれるでしょう。

同様にDNSではドメイン名のIPアドレスを教えてくれます
ドメイン名とはtokyo-tokkyo-kyokakyoku.example.comのような人間が理解しやすい住所のこと。
対してIPアドレスは123.456.789.xxxというような機械が理解しやすい住所です。

例えば、example.comというWebサイトにアクセスしようとした場合、サーバーに到達するために必要なのは123.456.789.xxxというIPアドレスになりますからexample.com => 123.456.789.xxxという変換をしなくてはなりません。
この変換を担うのがDNSというわけです。

今日、IPアドレスを直打ちするという機会はほぼありませんので、DNSは全ての通信の起点といっても過言ではない重要なシステムです。

-- -- --

DNSが策定された1980年当時、インターネットは今より小規模で単純だったのでDNSに機密性等は求められていなかったのですが、近年の著しい発達に伴い安心安全なプロトコルが必要になったため偉い人がRFC 7858で策定したのがDNS over TLS(以下DoT)で、そのDoTを適用してDNSの問い合わせを行うのがプライベートDNSの機能です。

DNSの危険性
DNSを保護することはプライバシー・セキュリティの両面から重要です。
DNSを監視していれば、その人がどんなサイトにアクセスしているのかが分かりますし、偽のIPアドレスを教えれば偽のサイトに誘導することも可能です
DNSパケットの監視や偽の応答は比較的簡単に実行できますから、公衆無線LANなどで安全性が侵害されるハードルはとても低いです。

絶対にしませんし、してはいけませんが、私が(誰でも)Macbookを持ってスタバに行けば、スタバのフリーWi-Fiに接続している人達の接続先ドメイン名を「専門的知識がなくても」監視することができ、それはすなわち、誰でも容易に監視されうることを意味します。
害は無いですが、「漫画村」や児童ポルノに対するフィルタリングもDNSの問い合わせに対して偽のIPアドレスを返すことで行われています。
このように、十分に悪用される可能性があるのできちんと対策する必要があります。

-- -- --

DNS over TLS

DoTの仕組みはHTTPSと似たような感じとなっており、DNSサーバーとクライアント間で確立したセキュアなチャンネルを用いてDNSの通信を行い、第三者が閲覧・改竄できないようにしています。

読んで字のごとく、TLSというセキュアなトンネルを通るDNS通信というわけです。
実際にどのような通信をしているかは、以下の検証を見てください。

詳しく知りたい方はJPNICさんで公開されている資料「DoH/DoT入門」が分かり易いのでおすすめです。

実際の通信を見てみよう

DNSがどのようにやり取りされているのかWiresharkというパケット監視ソフトで調査してみました。
Androidのパケット監視方法は色々あるようですが、今回は手軽に以下のような構成で通信を監視しました。
プレゼンテーション1.png
こうやってパケットを監視していると、公衆Wi-Fiなどが如何に危険かが身に沁みます。
一般人でも超手軽にパケットをのぞき見できるわけですから、平文通信なんて以ての外ですね。
未だにHTTPしか対応していない企業HPなども見かけますが、早急に対応してほしいものです。
無知なユーザー(決して貶める意ではありません)を脅威から保護するために最善の努力を行うのは、私たちホスト側の責務だと思います。

今回は調査目的で自分の通信を覗いていますが、くれぐれも他人の通信を覗いたり悪用することのないようにお願いします。

プライベートDNSが無効のとき

PCなどのDNSクエリストリームも同様の動作となっていると思います。

プレゼンテーション3.png
スマホ(192.168.137.149)からGoogle Public DNS(8.8.8.8)にqueryが投げられ、Google Public DNSからスマホにquery responseとしてIPアドレス(黒塗り部分)が返ってきています。
どのサイトにアクセスしようとしたのかが、第三者からでも見えることが確認できます。

  • クエリとレスポンスが平文でやり取りされており、第三者から丸見え
  • 一回の問い合わせで発生する通信は上りと下りの一往復

問い合わせquery)と応答response)で一セットになる標準的なDNSのやり取りで、秘匿はされますがDoTでも同様の通信が行われます
Google Public DNSをPCのDNSサーバーに設定しているので8.8.8.8に問い合わせていますが、環境によってはISPのDNSサーバー等に投げていると思います。

DNSはスピード重視ですのでプロトコルにはUDPが用いられています。
ステートレスなプロトコルですのでハンドシェイクなどは行われず、シンプルな通信が可能です。
仮にどこかでパケットが消えても再問合せすれば良いだけですので合理的だと思いますが、パケットが丸見えですので安全性もへったくれもありません。
特に無線通信ではプライバシーが侵害されたり、改竄されたりする可能性が高まります。
ちなみに、これらのDNSに関する通信の標準ポートは53です。

dns.googleを設定したとき

Google Public DNSAndroid 9以降向けに紹介されている方法です。
TSLという暗号化方式を利用するにあたって、まずハンドシェイクという手順が行われます。

ハンドシェイク

パケットに付したコメントはさほど正確でないのであくまでイメージだと思ってください。
プレゼンテーション4.png
まず、プライベートDNSに入力できるのはホスト名のみなので、dns.googleを解決する必要があります。
もともとGoogle Public DNS (8.8.8.8)がDNSサーバーなので分かりにくいですが、グレー部分より上の8.8.8.8はネットワークに設定されていたDNSサーバーで、下はスマホに設定されたdns.googleを解決した結果のDNSサーバーです。
この部分はセキュアではない、伝統的なDNSのやり取りです。

dns.googleが解決されたらTLSのハンドシェイクが始まります。
詳しい説明は省きますが、DNSサーバーとクライアントの間で公開鍵乱数をやり取りして共通鍵を作成し、以後はその共通鍵を用いて暗号化を行い通信します。

TCPとTLSに関する疑問点
TCPTLSにそれほど詳しくないのですが、TCP3way ハンドシェイクといって3回パケットをやり取りしなければ始まりません。
また、TLSは基本的にClient Helloというパケットが始まりの合図で、それはTCPの接続が確立した後に行われるはずです。
ここでは3way ハンドシェイクClient Helloが同時に行われているように見えますが実際どうなっているのでしょうか。
他の場所では3way ハンドシェイクClient Helloが分かれていたりと様々でした。
詳しい方がいましたらご教授下さい。

-- -- --

DNSクエリストリーム

ハンドシェイクの後は以下のような通信が行われます。
通信内容は暗号化されているので付したコメントは想定ですが、仕組み上これで正しいと思われます。
プレゼンテーション5.png
通信の内容がTLSv1.2で暗号化されているため、内容はApplication Dataと表示されています。
これで第三者はこれらの通信を傍受しても内容を確認することはできず、それぞれのパケットはハンドシェイク時の相手から送られてきていることが証明されていますので、一定の信頼性と機密性が保証されています。

問い合わせ(クエリ)と応答(レスポンス)がペアで行われている基本的な点は伝統的なDNSと変わりませんが、使用しているプロトコルが投げ捨てのUDPから、確認付きのTCPに代わったためACKパケットが増えています。
このACKパケットは必ず送られるものでもなく、効率化のためにバッファ分をまとめて送信することになっているので若干不規則な並びになっています。

TCP Keep-Aliveというパケットが目を引きますが、これはTCPは一度接続が切れると再びハンドシェイクからやり直さなくてはならないため、一定期間通信が行われなかった時に切断されないよう送られるパケットです。

  • 通信開始時にハンドシェイクという手続きが必要
  • クエリとレスポンスが暗号化されており、第三者が確認できない
  • 通信は、一回の問い合わせで発生する上りと下り + TCPのパケット

伝統的なDNSに比べて複雑になっているものの、TCPTLSといった下層プロトコルに伝統的なDNSを載せているだけなので理解はし易いです。
一度ハンドシェイクが済んでしまえば、レイテンシーもそこまで増大せず安全に利用できるよくできた実装だと思います。

弱点

すこし話はずれますがDoTの弱点にも触れておきたいと思います。

あたりまえですが、DoTで保護されるのはDNSの通信のみで他の通信は暗号化されませんのでHTTPなんかで接続すれば内容は丸見えになってしまいます。
加えて、DoTが保証するのはクライアント⇔DNSサーバー間の信頼性と機密性のみです。
こちらが詳しいですが、接続先のDNSサーバー自体が不正な場合などの安全性や、ホップ先の機密性は担保されていません。
DoTHTTPSと同様にデジタル証明書で管理されますが、デジタル証明書は偽でないことを証明するだけで接続先が安全であるか否かは関知しません。

利便性の面では、通信環境の悪いところなどではTCPのコネクションが頻繁に切断され、ハンドシェイクが大量に行われ、それもなかなか上手くいかず…という感じでIPアドレスが取得できず接続エラーになってしまうことがあります。
自分も登山中に経験したことがあり、プライベートDNS無効にすることで普通に接続できるようになりました。

また、個々の負荷増大は軽微でもDNSサーバーにとっては大きな負荷になるのかと思います。
基本的にACKでパケットが1.5倍ですからネットワークトラフィックも増大しますし、暗号化と復号化の処理も負荷になりそうです。
それでも(無料で)安定したPublic DNSを提供して下さっているのですから、関係各社様には頭が上がりません。

DoTで保護されるのはDNSサーバーとクライアント間の通信のみであることは前述のとおりですが、ハンドシェイク前のホスト名解決が伝統的なDNSである点が気になりました。
dns.googleに対して偽のIPアドレスを解決すれば以後の通信が不正になるのではと思いましたが問題ないのでしょうか?
とはいえ、なりすましやスコープ外の危険性はDoTに固有のものではありませんので、導入を否定する要因にはなりません。

いたちごっこなのはセキュリティの性ですが、適用しておくべきプロトコルだと思います。

自動を設定したとき

Google Public DNSによると、自動に設定した場合は、まず853ポートへの接続を試行し、成功したらDoTで、失敗したら53ポートへ伝統的なDNSで問い合わせを行うようです。

当方の環境ではdns.googleを明示した時と同じでした。
google_public_dns_auto.png
DNSサーバーが既定のままだったり、コネクションがうまくいかなかったりすると伝統的なDNSで問い合わせが行われると思われます。

一度、自動に切り替えた後TCPの接続に失敗して伝統的なDNSでやり取りしていた時がありました。
手動で再接続したらDoTに切り替わりましたが、どうやらDoTに執着するよりも接続性を優先する実装のようです。

one.one.one.oneを明示した時

自称最速DNSサーバー、Cloudflareの1.1.1.1です。
前述の通り設定できるのはホスト名のみなのでone.one.one.oneと設定します。

cloudflare_auto.png

こちらもDoTで秘匿された通信ができています。

OpenDNSを明示した場合

国内にサーバーがあり優秀な部類に入ると思われるOpenDNSですが、DoTには対応してなさそうです。
ホスト名をnslookupで検索してプライベートDNSに明示してみましたが、853ポートへアクセスできませんでした。
パケットを監視しているとエラーのパケットが返ってきているのが見えますが、スマホからはIPアドレスが取得できない状態(=通信不可)が見えるだけです。
対応していない(または存在していない)ホスト名を打ち込むと通信ができなくなるのでよく確認する必要がありますね。

おまけ(Windows)

WindowsではDNS over HTTPS(以下DoH)という技術でDNS通信を暗号化しようとしています。
これはHTTPS443ポートを用いてDNSを行うもので、UDPパケットTCPパケットの両方が用いられます。
2020年9月10日時点ではOSレベルの標準実装は行われていませんが、ChromeなどのブラウザはDoHでDNSの問い合わせを行っています。
プレゼンテーション6.png
このように伝統的なDNSの問い合わせとDoHが混在していて、ブラウザから投げられるDoHUDPプロトコルを利用しています。
DoHでもホスト名解決から始まるのは変わらないんですね。

ちなみにWindows insider Program (Dev Channel)に登録していてBuild 19628以降がインストールされていれば、レジストリを弄ることでOSレベルでもDoHを適用することができます。
プレゼンテーション7.png
基本的に全ての通信がDoHで行われているのが確認できます。
nslookupはDNSサーバーを明示している扱いなのでDoHの適用から外れているのだと思われます。
ブラウザレベルでの実装と違ってTCPTLSv1.2が用いられているのが面白いですね。
Dev Channelはだいぶ不安定になりますが気になる方は是非自己責任でどうぞ。
設定方法は公式ブログを参照してください。

所感

悪意ある第三者は虎視眈々と我々の通信を狙っています。
コロナ禍で社内だけだったビジネス関係の通信環境も多種多様になったことと思いますが、セキュリティ対策まで手が回りにくいのも実情かと思います。
Wi-Fiやファイアウォール、VPNなど、セキュリティは多角的にアプローチする必要がありますが、全ての通信の起点といっても過言ではないDNSを意識することはあまりありませんでした。
手軽に、どこでも使えるスマートフォンだからこそ、少しでも安全な通信ができるよう適用しておきたい「プライベートDNS」、皆様もこの機会に是非設定してみてはいかがでしょうか。

2
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What is going on with this article?