Android 9 (Pie)からプライベートDNS機能が実装されているが、どうやらDNSoverTLSかDNSoverHTTPSのことを指しているらしい？

# 更新履歴
2019/07/12;  
cloudflareが正式なDNSoverTLS/DNSoverHTTPSアプリケーションを発行していたのでiPhone/Android9以前で使ってみる部分を変更しました。また、暗号化して名前解決ができているか確認する手順を追加しました。


# はじめに
私の愛用機（Xperia XZ Premium）にたまたま（必然的に）Android Pieが降ってきました。
そこで色々といじくり回していたところ、プライベートDNSなるものが...
`[設定]>[ネットワークとインターネット]>[詳細設定]>[プライベートDNS]`
...プライベートDNSってなんだ...

## 一般的なDNS名前解決
まずは当たり前であろう前提知識を書きます...
（MACアドレスは？とかいうツッコミ要りませんレイヤが下がるので今回は書きません）  

1. コンピュータは**TCP/IP プロトコル**（人間でいう言語）を採用して通信しています。
2. **IPアドレス**（人間でいう住所）というものがコンピュータの**NIC**（ネットワークインタフェースカード：WiFiとか有線LANとか呼んでる部分）に割り当てられており、そのアドレスを指定して通信をしています。
3. そのIPアドレスは**IPv4**または**IPv6**の2つが存在します、IPv6は今回無視します。
4. IPv4アドレスは**xxx.xxx.xxx.xxx**の4オクテット区切り10進数の32ビット。  

...見てお判りかと思いますが**www.google.com**では**xxx.xxx.xxx.xxx**の10進数32ビットアドレスとして指定できません。＝通信できない。

### じゃあどうやって10進数のxxx.xxx.xxx.xxx形式に変換してるの？  

という疑問が出てきたらエクセレント。
やっとここでDNSが登場します。
### DNSは、接続したいサーバの名前とIPアドレスを台帳として持っていてそれをリクエストが来たら回答するというサーバです。（超極端）

```
0.www.google.comに接続したいとする。

---------------------------------------------------------------

1. PCはDNSサーバに向かってUDPパケット(平文）のクエリを投げます。 

     www.google.comってどこ？
[PC]       >>[UDP]>>        [DNS]
　　　　　　　                  `-[www.google.com : 172.217.161.195]

---------------------------------------------------------------

2. DNSサーバは、それに対してレスポンスを返します（これもまた平文）
     172.217.161.195だよ！
[PC]       <<[UDP]<<        [DNS]
　　　　　　　                  `-[www.google.com : 172.217.161.195]

---------------------------------------------------------------

3. PCは目的のwww.google.comへアクセスできるようになります
(図はルーティングをガン無視してますが気にしないでください)

[PC]       <<<<        [DNS]
　| 　　　　              `-[www.google.com : 172.217.161.195]
  `-------[www.google.com]


```
このDNS設定はDHCPによって供給されているため、ユーザーが意図していないことが多い。
この仕組みで、おかしいなと思う部分が...

 - DNSへのリクエストは**平文のUDPパケット**である。

これです。 
**HTTPSの通信で安全！**と思いきや残念...名前解決の時点で攻撃されてしまえばおしまいですね。
無料WiFiで通信する時をイメージしてみましょう。

```
0.www.google.comに接続したいとする。

[シナリオ上の設定]
  IP addr : 192.168.1.19
  subnet  : "今回は無視"
  DNS     : 192.168.1.1
  gateway : "インターネットの出口という認識で今回はOK、単にルータ"

---------------------------------------------------------------

1. PCはDNSサーバ(192.168.1.1)に向かってUDPパケット(平文）のクエリを投げます。 

     www.google.comってどこ？
[PC]       >>[UDP]>>        [DNS:192.168.1.1]
　　　　　　　                  `-[www.google.com : 172.217.161.195]

---------------------------------------------------------------

2. DNSサーバ(192.168.1.1)は、それに対してレスポンスを返します（これもまた平文）
     172.217.161.195だよ！
[PC]       <<[UDP]<<        [DNS:192.168.1.1]
　　　　　　　                  `-[www.google.com : 172.217.161.195]

---------------------------------------------------------------

3. それでは...攻撃者が居たとして、同じIPアドレスのDNSを立てて攻撃用サーバのIPを設定していると？


                       [DNS:192.168.1.1]
　  　　　　              `-[www.google.com : 172.217.161.195]
[PC]       >>>>> 
                       [DNS:192.168.1.1]
　  　　　　              `-[www.google.com : 10.2.0.15] 

...そうです、もし正しいDNSより攻撃者のDNSの応答が早かった場合
利用者は、めでたく攻撃サーバに接続してしまうことになりますね...恐ろしや。
正しいDNSサーバの後ろに攻撃者のDNSが権威DNS（親DNSサーバ）として割り込んだ場合も同じく危険。

```
##### Q.HTTPSは安全じゃないの？
A. 安全ですが、しっかり目視で認証局情報などを見て起きましょう。意図していないサーバに繋がっている場合もあります。

##### Q.HTTPSって暗号化してるんじゃないの？
A. 確かに暗号化していますが、名前解決の時点で違うサーバに飛んだら意味無し（今はブラウザ側が対応してるのか）。


...上記の恐ろしい事態を回避するために生まれたのが



 - DNSSEC(親DNSから子DNSサーバ)
   - UDPパケット 
   - DNSSECはデジタル署名をDNSデータに追加します。
   - DNSのクライアントが、DNSクエリへの応答として返される情報が、権威サーバーで保持されている情報の正確で忠実なコピーであることを保証する。
 - DNSoverTLS(子DNSサーバからPC)
   - UDPパケット
   - クエリ内容をTLSにより保護する
   - 次へのホップ情報は保護されないため、問い合わせたDNSサーバがどこかはわかる。
   - 経路上の他のDNSで攻撃者が書き換えた場合、不正な応答としてリジェクトできる。  
 - DNSoverHTTPS(子DNSサーバからPC)
   - TCPパケット
   - クエリ自体HTTPSパケットとして外部のDNSにリクエストする
   - DNSサーバ側の実装がDNSoverTLSより容易
   - 外部DNSを使わせないプロバイダ（学校や会社）などでも効果がある。
   

# DNSoverTLSとかDNSoverHTTPS使ってみたい

簡単に使うことができます。

#### Android 9(Pie)を利用している場合
**利用可能**
 - DNSoverTLS(システム標準機能を利用する＋VPNアプリケーションでも利用可能)
 - DNSoverHTTPS(VPNアプリケーションを使用は`Android 9以前のOSを利用している場合`の項へ)

 
`[設定]>[ネットワークとインターネット]>[詳細設定]>[プライベートDNS]`
**自動**:
DNSoverTLSに対応しているDNSサーバの場合自動でTLSモードになります
**プライベートDNSプロバイダのホスト名**:
自身でDNSoverTLS対応サーバを指定できます。



ここで以下のようにサーバを指定してください。
[参考:cloudflare -Setting up 1.1.1.1 for Android-](https://developers.cloudflare.com/1.1.1.1/setting-up-1.1.1.1/android/)

```

1dot1dot1dot1.cloudflare-dns.com
```

#### Android 9以前のOSを利用している場合

**利用可能**
 - DNSoverHTTPS(VPNアプリケーションを使用)
 - DNSoverTLS(VPNアプリケーションを使用)
 
**残念ながら、設定では使えません。**
VPNアプリケーションを利用することでDNSoverHTTPS/DNSoverTLSを利用可能です。
VPNを利用して自分自身に変換機を置いて通信します。

##### Intraを利用する
[Intra - GooglePlay](https://play.google.com/store/apps/details?id=app.intra&hl=ja)

1. 起動したら、右上のトグルスイッチを押すとアプリが赤色から青色に遷移するので、それを確認する。

##### 1.1.1.1: Faster & Safer Internetを利用する
[1.1.1.1: Faster & Safer Internet](https://play.google.com/store/apps/details?id=com.cloudflare.onedotonedotonedotone)

1. 起動したら、トグルスイッチでVPNを有効にします（VPN接続確認のプロンプトが立ち上がりますので許可）
2. [cloudflare](https://1.1.1.1/help)にアクセスして**DNSoverHTTPS**または**DNSoverTLS**が`yes`表記になっていれば名前解決を暗号化できています。

#### iOS(iPhone)を利用している場合

**利用可能**
 - DNSoverHTTPS(VPNアプリケーションを使用)
 - DNSoverTLS(VPNアプリケーションを使用)

**こちらも残念ながら、OSデフォルトに機能が実装されていません**
こちらも、アプリケーションを利用します。  

##### 1.1.1.1: Faster & Safer Internetを利用する
[1.1.1.1: Faster Internet](https://apps.apple.com/us/app/1-1-1-1-faster-internet/id1423538627)
1. VPN接続を確認するプロセスを許可し、画面左上にVPNのマークが出ていることを確認する。
2. [cloudflare](https://1.1.1.1/help)にアクセスして**DNSoverHTTPS**または**DNSoverTLS**が`yes`表記になっていれば名前解決を暗号化できています。


#### macOS(iMac/MacBookなど)を利用している場合。
工事中👷‍♂️

# 結論：Android9に搭載されたプライベートDNSとは...
どうやらDNSoverTLSのようです。他のサイトでDNSoverHTTPSと言われてる方いらっしゃいますが、おそらく違います。

# 参照
[DNS over TLS support in Android P Developer Preview ](https://android-developers.googleblog.com/2018/04/dns-over-tls-support-in-android-p.html)

[Sunrise DNS over TLS, sunset DNSSEC?](https://blog.apnic.net/2018/08/17/sunrise-dns-over-tls-sunset-dnssec/)

[JPNIC - DNSoverHTTPS -](https://www.nic.ad.jp/ja/basics/terms/dns-over-https.html)

[Center for the Cultivation of Technology](https://techcultivation.org/)