それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

unboundでrootから引くdnsサーバを作り、DNSフィルタリングに備える

この記事は試験的なものです。

ちゃんと動作するか現在、調査検討中です。

public DNSDNSブロッキングされる可能性がある。

public DNS 1.1.1.1/ 8.8.8.8 は多くの人が使っていて、とても公共性が高いのですが。多くの人が使うがゆえにフィルタリングされ自由を失う懸念が拭えない。

IIJの例

IIJ Public DNSサービス

DNSフィルタリング・ブロッキングについて 本サービスでは、インターネットコンテンツセーフティ協会(ICSA)が定める基準に則り、児童ポルノ対策のためのDNSブロッキングを実施しています。 なお、IIJが2019年7月より順次導入予定の「マルウェア対策のためのDNSフィルタリング」は実施いたしません。

DNS の名前解決がロギングされる。

どのドメインのIPを調べたのかの名前解決が残されます。DNSのフィルタリングとロギングはDNSサーバへの問い合せを記録し、その内容を保存調査分析します。ということはログ収集機構が組み込まれている。

DNSブロッキングは、オプトアウトしない限りログは収集される。またオプトアウトしても懸念は残る。 分析はしないと言ってるが、ロギング をしない とはどこにも書いていないので、ロギングされているのであろう。また「オプトアウトした」という情報が漏れる懸念がある。つまり私達がどのサイトをみたのかドメイン名で丸わかりになってしまう。そして、ISPはこれらの個人情報をいつもどおり任意で警察に提供する懸念がある。警察の任意取得が問題視されてから任意をやめるというTポイントのパターンを悪用される懸念がある。

IIJの例

IIJのセキュリティに関する取り組み | インターネットイニシアティブ(IIJ)

分析はしないとはいってるけど、蒐集しないとは言ってない。

自前でDNS をrootなserver から引いてくれるDNS問い合わせサーバを作りたい。

これらを踏まえると、ISPへのDNSサーバーへの問い合わせの記録は漏れるものです。プライバシーは保護されるか全く見通したが立たない。そこでDNSの問い合わせは、root サーバから自分で引いてくる必要がある。DNS用意しても、ISPや/1.1.1.1/8.8.8.8にフォワードしたらプライバシーが丸見えで意味がない。

DNSの問い合わせ用のサーバを作って運用してみようと思い立った。要は、オレオレpublicDNS です。

自分自身で、root からDNSを引っ張ってくるサーバを持っていれば、ISPgoogle(8.8.8.8)にどのサーバに問い合わせたかのプライバシー情報が漏れ無いと考えた。

今回のポイント forwardしない。

よくあるdnsサーバーのインストール記事だと 8.8.8.8へforward するだけです。

今回は、ISPやpublicDNSへ フォワードせず に自力で名前解決を試みます。

今回使ったもの - unbound

debian / unbound で構築してみました。

インストール

unbound のインストール。とにかくこいつがないと始まらない。

sudo apt install unbound 

あと、必要に応じて dns の問い合わせを確認するコマンドを入れておく

## drill コマンドのインストール
sudo apt install ldns-utils
## dig コマンドのインストール
sudo apt install dns-utils
## unbound-hosts コマンドのインストール
sudo apt install unbound-hosts

これらのコマンドは必要に応じてdnsの問い合わせを確認するのに使います。

私はDebianで実験しています。ubuntu の場合はdns-utilsではなくdnsutilsです。

基本設定

/etc/unbound にある設定を変えていきます。

debianの場合は次のようなディレクトリ構造になっていました。

takuya@:unbound$ tree .
.
├── unbound.conf
├── unbound.conf.d
│   ├── qname-minimisation.conf
│   └── root-auto-trust-anchor-file.conf
├── unbound_control.key
├── unbound_control.pem
├── unbound_server.key
└── unbound_server.pem

/etc/unbound/unbound.conf.d/qname-minimisation.conf

Serverの項目を変えていきます。

ここでは、指定したネットワークアドレス範囲からの問い合わせを許可。 また、unbound がListenするIPアドレスを指定した

server:

    #qname-minimisation: yes
    #
    access-control: 192.168.0.0/16 allow
    interface: 192.168.11.1
    root-hints: root.hints

root-hints は次で準備します。

root.hints を用意、root から問い合わせしてたどるようにする

root-hints ファイルを入れると、root の nameserver '.' からたどるようになります。

curl --output /etc/unbound/root.hints https://www.internic.net/domain/named.cache

root.hints ファイルの中身は、ROOT-SERVERSのIPアドレスです。 半年に一度くらいは更新するようにするといいらしいです。。

設定したら再起動とと動作確認

systemctl restart unbound で再起動

unbound-hosts で動作テスト。

unbound-host を使って動作テストをしてみます。

takuya@:unbound$ unbound-host -4 -d pbs.twimg.com

動作テスト dig

dig @192.168.11.1 twitter.com

これで、unbound のサーバーになります。

dig +trace できるようにする。

このままでは、IPの応答はできるけど、なにかしらトラブルのときに問い合わせを +trace できないので、 dig クライアントが trace コマンドを使えるようにします。

#    access-control: 192.168.0.0/16 allow 
access-control: 192.168.0.0/16 allow_snoop

traceするときは、クライアントが再起問い合わせをするので、サーバーが再起問い合わせをする必要がないですよね。 なので、クライアントが非再起問い合わせをしてくるので、それを許可するわけです。

+trace してみる

snoop をオンにすると dig +traceができるようになります。やったね。

dig +trace   pbs.twimg.com @192.168.11.1

; <<>> DiG 9.10.3-P4-Debian <<>> +trace pbs.twimg.com @192.168.11.1
;; global options: +cmd
.           448024  IN  NS  d.root-servers.net.
.           448
(中略
pbs.twimg.com.      300 IN  CNAME   cs196.wac.edgecastcdn.net.
;; Received 81 bytes from 204.13.251.34#53(ns4.p34.dynect.net) in 15 ms

unbound-anchor は自動的に更新される

systemctl restart unbound で再起動したら、 root.key のアンカーは自動的に更新されるようですね。

takuya@:unbound$ sudo systemctl restart unbound
takuya@:unbound$ cat "/var/lib/unbound/root.key"
; autotrust trust anchor file
;;id: . 1
;;last_queried: 1561371009 ;;Mon Jun 24 19:10:09 2019
;;last_success: 1561371009 ;;Mon Jun 24 19:10:09 2019
;;next_probe_time: 1561411721 ;;Tue Jun 25 06:28:41 2019
;;query_failed: 0

今回試したこと

unbound と root.hints を使って、カジュアルに呼ぶならオレオレpublic dns 的なものを作った。正しくは再起問い合わせのリゾルバ。

DNSブロッキングに備える。

DNSブロッキングDNSのロギングは、いつどこで誰に提供されるか全くわからない。そのため自分でDNS再起問い合わせをできるようにして自衛に努める必要がある。

追記 可能であれば、iptablesISPDNSやpublicDNSを止める

疎通確認をどうするか。可能であれば設定後にUnbound以外のDNSiptables でフィルタリングしてしまうのが良いと思う。

たとえば、yahoo bb のDNSサーバーとの通信を停止してDNS名前解決がソフトバンクに流れないようにする。

Chain zone_wan_output (1 references)
target     prot opt source               destination
output_wan_rule  all  --  anywhere             anywhere           
zone_wan_dest_REJECT  tcp  --  anywhere             dns-b.bbtec.net      tcp dpt:domain 
zone_wan_dest_REJECT  udp  --  anywhere             dns-b.bbtec.net      udp dpt:domain 
zone_wan_dest_REJECT  tcp  --  anywhere             dns-a.bbtec.net      tcp dpt:domain 
zone_wan_dest_REJECT  udp  --  anywhere             dns-a.bbtec.net      udp dpt:domain 
zone_wan_dest_ACCEPT  all  --  anywhere             anywhere             

追記: 簡単なパフォーマンス測定

cloudflare の 1.1.1.1 と google の 8.8.8.8 と、今回のunbound、そして dnsmasq で 1.1.1.1 にフォワードする ルーターで、簡単に応答時間を比べてみました。

takuya@:unbound$ for dns in 1.1.1.1 8.8.8.8 192.168.11.1 192.168.12,1; do  echo $dns ; time for i in {1..100}; do dig  +short @$dns t.co > /dev/null ; done ; done
1.1.1.1

real    0m2.012s
user    0m0.852s
sys 0m0.268s

8.8.8.8

real    0m1.851s
user    0m0.756s
sys 0m0.276s

192.168.11.1

real    0m0.845s
user    0m0.444s
sys 0m0.120s

192.168.12.1

real    0m0.587s
user    0m0.332s
sys 0m0.092s

なんか、public dns よりローカルのほうが速くね?

追記 DNSSEC の動作テスト

とくになにも設定してないけど、デフォルトで有効になってました。

takuya@:unbound$ dig +cd +short  @192.168.2.5 dnssec-failed.org
69.252.80.75
takuya@:unbound$ dig +short  @192.168.2.5 dnssec-failed.org
takuya@:unbound$ dig +dnssec +short  @192.168.2.5 dnssec-failed.org

参考資料