PaloAlto Network Minemeldとbindを組み合わせたDNSシンクホールの作成

PaloAlto Networkがオープンソースで開発しているThreat Intelligence収集・配信システムである[Minemeld](https://www.paloaltonetworks.jp/products/secure-the-network/subscriptions/minemeld)とDNSサーバーであるBINDを組み合わせて、DNSシンクホールを構築しましたので、その内容についてです。

# Minemeldとは？
簡潔に表すと、「独立して流通しているOSINT情報を一括収集して、フォーマット整形・整理（重複排除）して、統一的なフォーマットに変更した上で再配信する仕組み」となります。 
ここではMinemeld自体の解説は省きますので、詳しいことはPaloAltoの[ドキュメントページ](https://www.paloaltonetworks.jp/products/secure-the-network/subscriptions/minemeld)をご参照ください。

# やる（やりたい）こと
MalwareやPhishingサイトなどの悪性サイトが利用しているドメイン名について、Minemeldを使って情報収集し、ローカルのDNSサーバー上で収集したドメイン名を強制的に解決出来ない様にすることで、ローカルネット内で誤って悪性サイトに接続を試みたとしても通信を失敗させてリスクを低減する、というシステムの実現を目指します。

# 用意する物
- Minemeldサーバー
Minemeldがオフィシャルには ubuntu 14.04のLTSで動作検証しているので、それに倣ってubuntu 14.04で構築
構築手順はMinemeldのGitHub repositoryのによくまとまっている[記事](https://github.com/PaloAltoNetworks/minemeld-ansible)があるので、そちらを参照して構築します

- DNSサーバー
当方の環境ではCentOS 7に入っているBINDで構築しているので、OSインストールしてnamedを使えるように基礎構築をしておきます
※キャッシュサーバーのみであれば、ほぼデフォルト設定で使える状態になっていると思います

# Minemeldの設定
## ノードの設定
### MINERの設定
何はともあれ、シンクホールに落としたいドメイン名を収集する必要があるので、ドメイン名を配信しているOSINTから情報を収集してくるMINERノードを登録します。
当方の環境では、 `itcertpa.DOMAINS` と `bambenekconsulting.c2_dommasterlist` を登録しています。

### Aggregatorの設定
複数のMINERを使用する場合、情報を集約する必要があるので、この機能を持っているAggregatorノードを登録します。
今回はドメイン名を取り扱うので、 `stdlib.aggregatorDomain` を登録します。
※登録したAggregatorの入力として、先に登録したMINERのノードを入れておくのを忘れずに（忘れると、いつまで経ってもデータが出てきません）

### Feedの設定
Aggregatorがまとめた情報を外部から取得出来るようにするための、Feedノードを登録します。
当方の環境では、 `stdlib.feedGreenWithValue` を使用して、情報緒共有レベルがGREENの情報を出力する条件指定付きのFeedノードを使用しています。
※登録したFeedの入力として、先に登録したAggregatorのノードを入れておくのを忘れずに（こちらも忘れると、いつまで経ってもデータ出てこないという事になります）

## 注意点
Minemeldのデフォルト設定のままだと https でのみ通信しますが、証明書が正しくない為、エラー発生してしまい、UserAgent側で証明書の例外設定をしないと通信が出来ません。
正しい証明書に入れ換えるか、Minemeldのサーバーを https ではなく http で通信するように設定変更する必要があります（当方の環境では、ローカルネット内利用のみでしたのでhttpで動作する様に設定変更して対応しました）。

# BINDの設定
## 設定ファイルへの細工
Minemeldと連携して悪性ドメイン名の解決を出来ない様にする為に、Bindの設定ファイルに若干の細工を行います。
細工としては、後に記述する連携スクリプトが出力する設定ファイルをincludeする様に1行ほど記述を追加します。
※追加する箇所は設定ファイルでゾーンファイルの読み込みをする直前くらいの場所が良いかと思います

    /* DNS Black list */
    include "/etc/named/dnsbl.conf";

※後述する連携スクリプトが出力する設定ファイルのパスが `/etc/named/dnsbl.conf` である想定です。変更する場合は、変更後のパスを記述します

## シンクホールゾーンファイルの作成
悪性サイトのドメイン名解決が施行された場合に、実際のアドレスではなくシンクホールのアドレスを返すようにするゾーンファイルを作成します。
当方の環境では、 `/var/named/masters/blackhole.zone` と言うパスで配置しています。
後述する連携スクリプト内でこのパスを想定していますので、変更する場合は、スクリプトの修正が必要となります。

	$TTL    3600
	@       IN      SOA     ns1.example.local. info.example.local. (
	                        2017102901      ; Serial
	                        7200            ; Refresh
	                        120             ; Retry
	                        2419200         ; Expire
	                        3600)           ; Default TTL
	                NS      ns0.example.net.
	
	                A       127.0.0.1
	
	*       IN      A       127.0.0.1

シンクホールとして `127.0.0.1` （要するにローカルホスト）のIPを返却するようにしています。

## Minemeldとの連携スクリプトの作成
MinemeldのFeedノードの出力を取得して、悪性サイトのドメイン名をシンクホールへ誘導するゾーン定義設定ファイルを生成するスクリプトを作成します。

	#!/bin/sh
	
	URL="http://[Minemeldサーバー名]/feeds/[Feed名]"
	CONFIG_FILE=/etc/named/dnsbl.conf
	
	tempfoo=`basename $0`
	TMPFILE=`mktemp -q /tmp/${tempfoo}.XXXXXX`
	if [ $? -ne 0 ]; then
	    echo "$0: Can't create temp file, exiting..."
	    exit 1
	fi
	
	curl -s -f -o $TMPFILE $URL
	if [ $? -ne 0 ]; then
	    echo "$0: Can't get Black list"
	    rm -rf $TMPFILE
	    exit 1
	fi
	
	:> $CONFIG_FILE
	
	cat $TMPFILE | while read line
	do
	    echo "zone \"$line\" { type master; file \"masters/blackhole.zone\"; };" >> $CONFIG_FILE
	done
	
	# reload named.conf
	rndc reload > /dev/null 2>&1
	
	rm -rf $TMPFILE
	exit 0

このスクリプトをCRON等で定期的に呼び出すことで、Minemeldが収集した悪性ドメイン名を自動的にシンクホールへ誘導する事が出来る様になります。
※スクリプトの作り自体はあまりスマートではありませんので、参考程度にして頂いて改良して頂けると幸いです