Edited at

Homebrew で DNSCrypt を試してみる

More than 1 year has passed since last update.

注: DNS について特に専門ではないので、この記事の内容は大きく誤解して書いている可能性がある。


DNS とは

DNS は IP とドメイン名を変換してくれるプロトコル・サービス。

これは生の TCP や UDP で通信する。このままでは改ざんし放題、盗聴し放題。


DNS を守るための手立て

デジタル署名を付加して応答することで、完性を保証する DNSSEC がある。

(完全性の保証はしてくれるが、盗聴は防げない)。あまり普及していないらしい。

一方、盗聴をも防げる手段として DNSCrypt というプロトコル・ソフトウェアがある。

ローカルに DNSCrypt プロキシサーバを立て、そのプロキシサーバ経由で通信することで、

生の DNS 問い合わせはキャプチャできなくなるという寸法だ。

実際に tcpdump で自分の DNS 問い合わせと応答を盗聴し、通常時と DNSCrypt 有効時で比較してみた。

たしかに DNS の盗聴には有効そうだったので、ここに自分の調べた手順を残す。

(そして、もちろん、オーバーヘッドがある分、 DNS 問い合わせ時に通信速度は低下する。

また、 DNS の盗聴は防げても、ほかの通信については従来のままなので、やはり VPN や TLS などで保護する必要がある。

地理による最適化などの恩恵が受けられず、 CDN からのダウンロード速度が向上しない可能性がある。

また、 OS 本体のアップグレート時やシングルユーザーモードなど、特殊な状況下でも正しく通信可能か否か、私は検証していない。)


Homebrew でインストール・起動


インストール

$ brew install dnscrypt-proxy --with-plugins


起動

$ sudo brew services restart dnscrypt-proxy

なるほど簡単。


実験方法


tcpdump の使い方

en0 のところは、 ifconfig コマンドなどで、自分の環境での、主として使っているネットワークインターフェースをしらべて指定する。

port 53 というのは、 DNS が 53 番ポートで通信するため。

$ sudo tcpdump -i en0 'port 53'

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size xxxxxx bytes
(略。キャプチャした結果がでる)


DNSCrypt の有効化・無効化

メニュー > システム環境設定 > ネットワーク > 詳細... > DNS > DNS サーバ

と開いていき、 127.0.0.1 を追加すれば有効、削除すれば無効という設定になる。

確定するには 1 つ前の「ネットワーク」の画面で「適用」を押す必要がある。

(私は普段、英語ロケールで使っているので、↓の図と↑の文言が多少違うかもしれない。)


DNS の問い合わせ

nslookup コマンドで盗聴したいサンプルの問い合わせを行うことにする。

$ nslookup example.com

Server: XXX.XXX.XXX.XXX
Address: XXX.XXX.XXX.XXX#53

Non-authoritative answer:
Name: example.com
Address: 93.184.216.34


DNS キャッシュのクリア

実験する際には、 DNS キャッシュがあると正しく比較できない可能性を考え、次のコマンドでキャッシュをクリアする。

(通常 nslookup コマンドはキャッシュを無視するはずだが、そこを信頼するよりも確実にクリアして比較したい。)

$ sudo killall -HUP mDNSResponder


結果

DNSCrypt 無効時には次のようなパケットが記録できる。有効時には記録できない。

$ sudo tcpdump -i en0 'port 53'

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on en0, link-type EN10MB (Ethernet), capture size ?????? bytes
HH:MM:SS.ssssss IP XXX.XXX.XXX.XXX.AAAAA > YYY.YYY.YYY.YYY.domain: ?????+ A? example.com. (29)
HH:MM:SS.ssssss IP YYY.YYY.YYY.YYY.domain > XXX.XXX.XXX.XXX.AAAAA: ????? 1/2/4 A 93.184.216.34 (181)
HH:MM:SS.ssssss IP XXX.XXX.XXX.XXX.BBBBB > YYY.YYY.YYY.YYY.domain: ?????+ PTR? XXX.XXX.XXX.XXX.in-addr.arpa. (44)
HH:MM:SS.ssssss IP YYY.YYY.YYY.YYY.domain > XXX.XXX.XXX.XXX.BBBBB: ????? NXDomain* 0/1/0 (100)
HH:MM:SS.ssssss IP XXX.XXX.XXX.XXX.CCCCC > YYY.YYY.YYY.YYY.domain: ?????+ PTR? YYY.YYY.YYY.YYY.in-addr.arpa. (42)
HH:MM:SS.ssssss IP YYY.YYY.YYY.YYY.domain > XXX.XXX.XXX.XXX.CCCCC: ????? NXDomain* 0/1/0 (98)

また、有効時に port 443 をキャプチャすると、 DNSCrypt によって暗号化された通信が記録できる。 (どんな問い合わせをしたのかまではわからない。)