どさにっき AI 〜2018年5月下旬〜

by やまや
<< = >>

2018年5月23日(水)

1.1.1.1 いろいろ

_ ここのところブロッキングの話を追いかけてたもんだから、そのちょっと前にホットだった cloudflare の public DNS のネタを消化しきれてない。ということで、もうだいぶ遅れ気味だけどまとめて放出。

_ あ、JANOG41.5 でやったブロッキングの話の資料は ここにあります。周回遅れすぎて今さら見る必要ないかと思いますが。

DNS over TLS

_ お使いの unbound.conf に以下の設定を追加するだけで、cloudflare に対して DNS over TLS でクエリをやりとりするようになります。ただし最新の 1.7.x 以降のみ。

server:
    tls-cert-bundle: "/etc/ssl/cert.pem"	# ルート証明書束
forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 1.1.1.1@853
    forward-addr: 1.0.0.1@853
    forward-addr: 2606:4700:4700::1111@853
    forward-addr: 2606:4700:4700::1001@853

_ 1.6.x 以下でも TLS が使えないわけではないんだけど、以下のような問題があるのでやめておいたほうがよい。

なお、1.7 でも SSL プロトコルバージョンや ciphersuite などは指定できない。

DNS over HTTPS

_ コマンドラインから JSON 形式ではなく DNS wireformat 形式で叩く。実用性は皆無です、はい。

> drill -q /dev/stdout www.google.com | sed 's/;.*//; y/abcdef/ABCDEF/' | tr -dc 0-9A-F | sed 's/^./A/' | dc -e'16i?P' | curl -o - -H 'Content-Type: application/dns-udpwireformat' --data-binary @- https://1.1.1.1/dns-query | drill -i /dev/stdin
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   160  100   128  100    32   3368    842 --:--:-- --:--:-- --:--:--  4210
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 42641
;; flags: qr rd ra ; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; www.google.com.      IN      A

;; ANSWER SECTION:
www.google.com. 284     IN      A       74.125.124.99
www.google.com. 284     IN      A       74.125.124.103
www.google.com. 284     IN      A       74.125.124.104
www.google.com. 284     IN      A       74.125.124.105
www.google.com. 284     IN      A       74.125.124.106
www.google.com. 284     IN      A       74.125.124.147

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 0 msec
;; WHEN: Thu Jan  1 09:00:00 1970
;; MSG SIZE  rcvd: 128
drill にはパケットを投げたり受けとったりするかわりにファイルに読み書きする機能があるのでそれを使ってる。ただし、ファイルの読み書きはできるけど標準入出力の読み書きはできないので、/dev/std{in,out} を使ってムリヤリやらせてる。また、ファイルに書くときは実際のパケットフォーマットではなくテキスト形式でダンプするという大きなお世話をしてくれやがるので、それをバイナリに戻すという手間をかけてやる必要があって、sed やら dc やらはそれをやってる(読むときはバイナリのままでいい)。

_ DoH って期待してる人がすごく多そうに見えるんだけど、どうなのかねぇ。stub resolver として使えない以上ほとんど意味ないと思うんだけど。cloudflare は 専用のクライアントを用意してるけど、わざわざそれをインストールするぐらいなら unbound をインストールして TLS でもいいわけで(windows 版 unbound もあるよ)。

_ cloudflare は 1.1.1.1 という覚えやすい IP アドレスでそのまま HTTPS アクセスできるけど、一般的な HTTPS ではホスト名でアクセスする必要があって、DoH で使うためにはまずそのホスト名を名前解決しなけりゃならんという鶏と卵の問題があるんでめんどくさいんだよね(たとえば google の DoH は 8.8.8.8 ではなく dns.google.com でアクセスする必要がある)。ホスト名ではなく IP アドレスの証明書を発行してもらうという cloudflare のやりかたもあるし、その部分は /etc/hosts で名前解決するというやりかたもあるけど、いずれにしてもめんどくさい。

_ ホスト名の正引き逆引き以外の問い合わせを投げるツールを書くとき、いまどきのスクリプト言語であれば HTTP と JSON の処理ぐらいは標準装備してるからわざわざ DNS 用のライブラリを追加インストールしなくていい、というのは非常にメリットが大きいとは思うんだけど、それを生かせるのはかなり例外的なケースだよね。これをありがたいと思うのであれば、cloudflare なんかに頼らず、ローカルの環境に HTTPS -> DNS の proxy を自前で整備するべき。

1.1.1.1 の証明書

_ 証明書についてはすでに うるしまさんが書かれてますけれど、それとはまったく別方向で。

_ CT ログで証明書発行の記録を探してみると、cloudflare に対して 1.1.1.1 の証明書が最初に発行されたのは 3/22であることがわかる(現在の証明書とは異なる)。一方、 APNIC whowasで調べてみると、whois 情報に "APNIC and Cloudflare DNS Resolver project" という文言が入ったのは 3/30 だということがわかる。つまり、whois の情報を見ても cloudflare のものだとはわからん時期に cloudflare に対して証明書が発行されちゃったってことなんだよね。

_ じゃあ CA(digicert) はどうやって cloudflare 所有のアドレスだと確認したのか調べてたら、cloudflare(AS13335) が 1.1.1.0/24 の経路を流しはじめたのが 3/20 ごろだったということが判明。 このへんをポチポチいじるとわかる(直リンできない)。証明書が発行された 3/22 は whois の情報は変更されてなかったけど、すでに cloudflare に経路が向いてたので発行は問題なしと判断されたってことなんでしょう、たぶん。不正な手続きによる発行じゃなかったんだね、よかったよかった。

_ …で終わればいいんだけど。

_ 実は、これ以前にも 1.1.1.1 に対する証明書が発行されてるんだよ。 ここを見ると APNIC でも cloudflare でもないところに対して過去に3枚ほど 1.1.1.1 の証明書を発行されてるのがわかる(いずれも期限切れ)。どうやっても 1.1.1.1 を所有できていたと証明できるはずがないと思うんだけれど、なんでこんな証明書を CA は発行しちゃったんですかねぇ…。

_ ホスト名ではなく IP アドレスに対する証明書はチェックがザルな CA が多いという話をどこかでちらっと聞いたことがある。もしろくに確認もされずに 1.1.1.1 の証明書を誰でも取れるのが事実なのだとすれば、cloudflare が正当な手続きで取得していたのだとしても、証明書を見たたけじゃ正当に取得されたのか不当に取得されたのか客観的に区別できない以上、ぜんぶまとめて信頼できないとして扱うしかないんじゃないかなー、と思うんですがどうなんでしょう。


<< = >>
やまや