iPhone の HTTP(S) 通信を OWASP ZAP で覗いてみたたら 8.8.8.8, 8.8.4.4 に対して DNS over HTTPS の通信を見つけたのでどんなやり取りをしているのか確認してみた。
DNS over HTTPS でのリクエスト
リクエストは HTTP の GET メソッドで /dns-query に dns という QUERY STRING で送られていました。
GET /dns-query?dns=AAABAAABAAAAAAABCjQ3LWNvdXJpZXIEcHVzaAVhcHBsZQNjb20AAEEAAQAAKQIAAAAAAABKAAwARgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA HTTP/1.1
Host: 8.8.4.4
Content-Type: application/dns-message
Connection: keep-alive
Accept: application/dns-messagedns パラメータの値は UDP で使われているのと同じバイナリメッセージを Base64 でエンコードしたものでした。
base64 の padding は省略されるようです。
ではこの dns パラメータの中身を確認してみます。
dnspython を使うと便利でした。
| |
上のコードを decode-dns-query.py として保存したとして
| |
と実行すると次のように出力されます
id 0
opcode QUERY
rcode NOERROR
flags RD
edns 0
payload 512
option Generic 12
;QUESTION
47-courier.push.apple.com. IN HTTPS
;ANSWER
;AUTHORITY
;ADDITIONALおぉ! 47-courier.push.apple.com の HTTPS レコードを問い合わせてますね。Apple はもう HTTPS レコードを使っているとは聞いていたけど。
早速出くわすとは。
DNS over HTTPS でのレスポンス
次にレスポンスを確認します。レスポンスはバイナリなので curl ではファイルに出力しないと確認できません。
| |
$ file response
response: dataこのレスポンスも UDP でやり取りするのと同じフォーマットらしいのでリクエストと同様に dnspython で decode してみます。
次のコードを用意しました。
| |
| |
実行結果です
id 0
opcode QUERY
rcode NOERROR
flags QR RD RA
edns 0
payload 512
option Generic 12
;QUESTION
47-courier.push.apple.com. IN HTTPS
;ANSWER
47-courier.push.apple.com. 7107 IN CNAME 47.courier-push-apple.com.akadns.net.
47.courier-push-apple.com.akadns.net. 60 IN CNAME apac-asia-courier-4.push-apple.com.akadns.net.
;AUTHORITY
akadns.net. 38 IN SOA internal.akadns.net. hostmaster.akamai.com. 1629813934 90000 90000 90000 180
;ADDITIONALHTTPS レコードはまだよく知らないので、ふーん、こんなのが返ってくるんだ… としか。
dns.google.com/resolve で確認
dig コマンドが HTTPS レコードに対応してないので https:/dns.google.com/resolve で確認した結果も貼っておく。
| |
| |
dig では type65 と指定すれば良いらしい
その後 dig でも type65 と指定すれば良いと知った
$ dig 47-courier.push.apple.com type65
; <<>> DiG 9.10.6 <<>> 47-courier.push.apple.com type65
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65301
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;47-courier.push.apple.com. IN TYPE65
;; ANSWER SECTION:
47-courier.push.apple.com. 18413 IN CNAME 47.courier-push-apple.com.akadns.net.
47.courier-push-apple.com.akadns.net. 60 IN CNAME apac-asia-courier-4.push-apple.com.akadns.net.
;; AUTHORITY SECTION:
akadns.net. 179 IN SOA internal.akadns.net. hostmaster.akamai.com. 1629813934 90000 90000 90000 180
;; Query time: 37 msec
;; SERVER: 192.168.210.100#53(192.168.210.100)
;; WHEN: Sun Oct 16 00:48:47 JST 2022
;; MSG SIZE rcvd: 212Cloudflare の HTTPS レコードを引いてみる
47-courier.push.apple.com は CNAME が返ってきており、全然 HTTPS っぽさがないので HTTPS レコードが使われているという www.cloudflare.com で試してみる。
$ dig www.cloudflare.com type65
; <<>> DiG 9.10.6 <<>> www.cloudflare.com type65
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3173
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.cloudflare.com. IN TYPE65
;; ANSWER SECTION:
www.cloudflare.com. 300 IN TYPE65 \# 67 0001000001000C0268330568332D32390268320004000868107B6068 107C600006002026064700000000000000000068107B602606470000 0000000000000068107C60
;; Query time: 92 msec
;; SERVER: 192.168.210.100#53(192.168.210.100)
;; WHEN: Sun Oct 16 00:49:28 JST 2022
;; MSG SIZE rcvd: 126うーむ、読めないじゃん…
https://dns.google.com/resolve でも試してみる
| |
| |
わかりやすーい!!
www.google.com の HTTPS レコード
www.google.com でも確認してみた
| |
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": false,
"CD": false,
"Question": [
{
"name": "www.google.com.",
"type": 65
}
],
"Answer": [
{
"name": "www.google.com.",
"type": 65,
"TTL": 5820,
"data": "1 . alpn=h2,h3"
}
]
}HTTPS レコードが存在しない場合
先の 47-courier.push.apple.com では CNAME が返ってきていたけど HTTPS レコードが存在しない場合は
CNAME レコードがあればそれを返してくるっぽい。
思いがけず HTTPS レコードについても親しくなった。

