EC2上にハニーポットを設置してKibanaで分析できるようにする (lurker + fluentd + elasticsearch + kibana)

![Screen Shot 2016-01-03 at 6.27.44 PM.png](https://qiita-image-store.s3.amazonaws.com/0/27627/74bc9633-49c9-7a7b-828f-2fe2061f3a68.png)


概要
--------------------

備忘録を兼ねてAWS上のEC2に低インタラクション型のハニーポット（実際に侵入などはさせずに攻撃データの収集をするハニーポット）の構築方法をまとめます。構成としては以下のようになります。

![Screen Shot 2016-01-03 at 5.41.56 PM.png](https://qiita-image-store.s3.amazonaws.com/0/27627/df536e09-880d-818b-de48-2ab0909c3f39.png)

最初、ハニーポットを運用していた時はいちいちスクリプトを書いていろいろ調べていましたが、いい加減面倒くさくなってきたのでありもののインターフェースとしてKibanaを使うことにしました。

インスタンスはやや特殊な構成で、マネージメントとして使うデフォルトNICのeth0の他に、観測用のNIC（eth1）とグローバルアドレスを追加して観測データに余計なデータを混ぜないようにします。eth1にはIPアドレスは割り当てず、OSは一切の応答をしませんが、ハニーポットソフトウェアが適切にARPやTCPの応答などを返すことによって追加で割り当てたグローバルアドレスに対する攻撃をキャプチャします。

ログデータはfluentd経由でElasticsearchに格納し、sshdにトンネルをはってKibanaで閲覧できるようにします。今回は全部入りの構成としましたが、ログデータの受け渡しはfluentd経由になるのでハニーポット部分とデータ蓄積、集計部分を変更することもできます。


インスタンスの準備
--------------------

EC2上でインスタンスを用意します。インスタンスの払い出し方法については省略しますが、Elasticsearchを使うため最低でもt2.micro以上のスペックが必要と思われます。（t2.nanoだとメモリ不足で動かなくなる or 落ちました）当然、快適に動かしたいのであればそれ以上のスペックが必要です。

インスタンスを用意した後、まずは新しいElastic IP addressを割り当てます。ダッシュボードのNETWORK & SECURITY -> Elastic IPs から`Allocate New Address` を選択します。

![allocate-new-address.png](https://qiita-image-store.s3.amazonaws.com/0/27627/dc3fc388-b0ad-21d2-ebe8-c83556cb77c4.png)

次に全てのincoming通信を受け付けるSecurity Groupを作成します。通常のオペレーションで使うととても危険なため、誤って別のインターフェース・インスタンスに適用しないように気をつけてください。NETWORK & SECURITY -> Security Groups から `Create Security Group` です。

<img width="1147" alt="create-security-group.png" src="https://qiita-image-store.s3.amazonaws.com/0/27627/ae897a3a-6fbd-56f7-d8e6-fb38fd643ceb.png">

その後、ネットワークインターフェースを追加します。Subnetは作成したインスタンスと同じものを指定します。Security Groupは先ほど作成した全許可のものを選択します。Private IPはauto assignが無難です。

<img width="1150" alt="create-network-interface.png" src="https://qiita-image-store.s3.amazonaws.com/0/27627/60b14927-0100-fe3a-895f-e7556c41f6a5.png">

そして、IPアドレスをネットワークインターフェースにAssociateします。interfaceに先ほど作成したネットワークインターフェースのものを選択します。

<img width="1113" alt="associate-address.png" src="https://qiita-image-store.s3.amazonaws.com/0/27627/23969025-8e28-c7bc-e7bd-d2078ac7b25d.png">

最後にインスタンスにネットワークインターフェースをattachします。

<img width="1132" alt="attach-interface.png" src="https://qiita-image-store.s3.amazonaws.com/0/27627/1c8b206e-e610-c688-ce9e-b04cf17ee3c7.png">

これで２つのネットワークインターフェースと2つのグローバルIPアドレスをもつインスタンスが設定できました。ここからはインスタンスの中の設定に移ります。


Elasticsearchのセットアップ
-------------------

Elasticsearchについては必要なアプリケーションやリソースについては変化が大きいようなので、最新の情報は[公式ページ](https://www.elastic.co/guide/en/elasticsearch/reference/current/setup-repositories.html)の参照をお勧めします。ここで記載するのは2016年1月時点での情報です。

まず、Elasticsearchを動かすためのJavaをインストールします。ElasticsearchのページではJava8を推しているため、OracleのJava8をセットアップします。途中、ターミナル上で規約同意の入力があります。

```bash
$ sudo add-apt-repository ppa:webupd8team/java
$ sudo apt-get update -y
$ sudo apt-get install -y oracle-java8-installer
```

Javaのセットアップが終わったら、Elasticsearch本体のインストールになります。今回はレポジトリからのインストールになります。

```bash
$ wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
$ echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
$ sudo apt-get update && sudo apt-get install elasticsearch
```

インストールが終わったら、自動起動を有効化した後、サービスを起動します。

```bash
$ sudo update-rc.d elasticsearch defaults 95 10
 Adding system startup for /etc/init.d/elasticsearch ...
   /etc/rc0.d/K10elasticsearch -> ../init.d/elasticsearch
   /etc/rc1.d/K10elasticsearch -> ../init.d/elasticsearch
   /etc/rc6.d/K10elasticsearch -> ../init.d/elasticsearch
   /etc/rc2.d/S95elasticsearch -> ../init.d/elasticsearch
   /etc/rc3.d/S95elasticsearch -> ../init.d/elasticsearch
   /etc/rc4.d/S95elasticsearch -> ../init.d/elasticsearch
   /etc/rc5.d/S95elasticsearch -> ../init.d/elasticsearch
$ sudo /etc/init.d/elasticsearch start
 * Starting Elasticsearch Server
   ...done.
```

Kibanaのセットアップ
--------------------

Kibanaのパッケージをダウンロード＆展開します。この記事執筆時点ではElasticsearchの最新版とKibanaのリリース版である 4.1.4 は相性が悪いようなので、ベータの4.3.1を使います。

```bash
$ wget https://download.elastic.co/kibana/kibana/kibana-4.3.1-linux-x64.tar.gz
$ tar xzf kibana-4.3.1-linux-x64.tar.gz
$ cd kibana-4.3.1-linux-x64/
```

デフォルト設定のままで動くはずなので、試しに起動してみます。確認できたらひとまずCtrl-Cで抜けます。

```bash
$ ./bin/kibana
  log   [00:58:11.960] [info][status][plugin:kibana] Status changed from uninitialized to green - Ready
  log   [00:58:11.986] [info][status][plugin:elasticsearch] Status changed from uninitialized to yellow - Waiting for Elasticsearch
  log   [00:58:11.997] [info][status][plugin:kbn_vislib_vis_types] Status changed from uninitialized to green - Ready
  log   [00:58:12.001] [info][status][plugin:markdown_vis] Status changed from uninitialized to green - Ready
  log   [00:58:12.004] [info][status][plugin:metric_vis] Status changed from uninitialized to green - Ready
  log   [00:58:12.014] [info][status][plugin:spyModes] Status changed from uninitialized to green - Ready
  log   [00:58:12.025] [info][status][plugin:statusPage] Status changed from uninitialized to green - Ready
  log   [00:58:12.027] [info][status][plugin:table_vis] Status changed from uninitialized to green - Ready
  log   [00:58:12.040] [info][listening] Server running at http://0.0.0.0:5601
  log   [00:58:17.069] [info][status][plugin:elasticsearch] Status changed from yellow to yellow - No existing Kibana index found
  log   [00:58:20.655] [info][status][plugin:elasticsearch] Status changed from yellow to green - Kibana index ready
^C
```

ネットワークのセットアップ
----------------------

ifconfigコマンドで追加のネットワークインターフェース（`eth1`）が有効になっていることを確認します。

```bash
$ ifconfig  -a
eth0      Link encap:Ethernet  HWaddr 06:c0:a5:86:b9:57
          inet addr:172.30.1.113  Bcast:172.30.1.255  Mask:255.255.255.0
          inet6 addr: fe80::4c0:a5ff:fe86:b957/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:9001  Metric:1
          RX packets:256 errors:0 dropped:0 overruns:0 frame:0
          TX packets:260 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:33995 (33.9 KB)  TX bytes:30622 (30.6 KB)

eth1      Link encap:Ethernet  HWaddr 06:32:14:8c:48:cb
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B
```

`eth1`が確認できたら、起動時に有効になるよう設定ファイルを作成します。

```bash
$ sudo vi /etc/network/interfaces.d/eth1.cfg
auto eth1
iface eth1 inet manual
```




fluentdのセットアップ
---------------------

ハニーポットソフト（lurker）からElasticsearchへのデータ受け渡しにfluentdを使います。今回は専用インスタンスということでグローバルのgemとして直接インストールしてしまいます。次いで、fluentdのElasticsearch用プラグインもインストールします。

まず、Rubyをレポジトリからインストールします。

```bash
$ sudo add-apt-repository -y ppa:brightbox/ruby-ng
$ sudo apt-get update -y
$ sudo apt-get install -y ruby2.2 ruby2.2-dev
```

```bash
$ sudo gem install fluentd
$ sudo fluent-gem install fluent-plugin-elasticsearch
```

設定ファイルを用意します。fluentd形式からlogstash形式に変換するため `logstash_format true` とし、各メッセージに含まれるタグも消さずに埋め込むため `include_tag_key` と `tag_key` をそれぞれ設定します。

```bash
$ sudo mkdir -p /usr/local/etc/
$ sudo vi /usr/local/etc/fluentd.conf
<source>
  @type forward
  port 24224
  bind 127.0.0.1
</source>

<match lurker.**>
  type elasticsearch
  host localhost
  port 9200
  index_name lurker
  logstash_format true
  include_tag_key true
  tag_key _tag
</match>
```

両方用意したところで、起動を確認します。確認できたらひとまずCtrl-cで抜けます。

```
$ sudo /usr/local/bin/fluentd -c /usr/local/etc/fluentd.conf
2016-01-03 06:46:23 +0000 [info]: reading config file path="/usr/local/etc/fluentd.conf"
2016-01-03 06:46:23 +0000 [info]: starting fluentd-0.12.19
2016-01-03 06:46:23 +0000 [info]: gem 'fluent-plugin-elasticsearch' version '1.2.1'
2016-01-03 06:46:23 +0000 [info]: gem 'fluentd' version '0.12.19'
2016-01-03 06:46:23 +0000 [info]: adding match pattern="lurker.**" type="elasticsearch"
2016-01-03 06:46:23 +0000 [info]: adding source type="forward"
2016-01-03 06:46:23 +0000 [info]: using configuration file: <ROOT>
  <source>
    @type forward
    port 24224
    bind 127.0.0.1
  </source>
  <match lurker.**>
    type elasticsearch
    host localhost
    port 9200
    index_name lurker
    logstash_format true
    include_tag_key true
    tag_key _tag
  </match>
</ROOT>
2016-01-03 06:46:23 +0000 [info]: listening fluent socket on 127.0.0.1:24224
^C2016-01-03 06:46:33 +0000 [info]: shutting down fluentd
2016-01-03 06:46:33 +0000 [info]: shutting down input type="forward" plugin_id="object:d21298"
2016-01-03 06:46:34 +0000 [info]: shutting down output type="elasticsearch" plugin_id="object:d2cd8c"
2016-01-03 06:46:34 +0000 [info]: process finished code=0
```

Lurker（ハニーポットソフト）のセットアップ
------------------------

必要なパッケージをインストールします。

```bash
$ sudo apt-get install -y git build-essential libev4 libev-dev cmake libpcap-dev libmsgpack3 libmsgpack-dev
```

その後、必要なソースコードをコンパイルします。`libfluent`と`lurker`の2つをコンパイルする必要があります。それぞれホームディレクトリ（`/home/ubuntu/`）に展開するものとします。

```bash
$ cd
$ git clone https://github.com/m-mizutani/libfluent.git
$ cd libfluent
$ cmake . && make
$ cd ..
$ git clone https://github.com/m-mizutani/lurker.git
$ cmake -DWITH_FLUENT=../libfluent/ . && make
```

起動動作だけ確認します。

```bash
$ /home/ubuntu/lurker/bin/lurker -h
Usage: lurker [options]

Options:
  -h, --help            show this help message and exit
  -i STRING             Specify interface to monitor on the fly
  -r STRING             Specify pcap_file for dry run mode
  -f STR                Fluentd inet destination (e.g. 10.0.0.1:24224)
  -o STRING             Output file path. '-' means stdout
  -t STRING             File path of target list
  -H                    Enable hex format data log instead of binary data
```


起動スクリプトの作成
-----------------------

再起動後も動き続けるように以下の起動スクリプトを作成します。ADDRに代入するIPアドレスは環境にあわせて**追加したネットワークインターフェースの`Primary private IP`**を指定します。

```bash
$ sudo vi /etc/rc.local
#!/bin/sh -e

DEV=eth1
ADDR=172.30.1.xxx

iptables -I INPUT -i $DEV -j DROP
nohup /home/ubuntu/kibana-4.3.1-linux-x64/bin/kibana &
nohup /home/ubuntu/lurker/bin/lurker -i $DEV "$ADDR:*" -f localhost &
/usr/local/bin/fluentd -c /usr/local/etc/fluentd.conf -d /var/run.fluentd.pid &

exit 0
```

ここまでできたところでマシンを再起動させます。全ての設定がうまくできていればpsコマンドをうつと概ね以下の様な結果が得られるはずです。

```bash
$ ps ax | grep -e elasticsearch -e kibana -e lurker -e fluentd
 1170 ?        Sl     0:12 /usr/bin/java -Xms256m -Xmx1g -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -Dfile.encoding=UTF-8 -Djna.nosys=true -Des.path.home=/usr/share/elasticsearch -cp /usr/share/elasticsearch/lib/elasticsearch-2.1.1.jar:/usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch start -d -p /var/run/elasticsearch/elasticsearch.pid --default.path.home=/usr/share/elasticsearch --default.path.logs=/var/log/elasticsearch --default.path.data=/var/lib/elasticsearch --default.path.conf=/etc/elasticsearch
 1195 ?        Sl     0:05 /home/ubuntu/kibana-4.3.1-linux-x64/bin/../node/bin/node /home/ubuntu/kibana-4.3.1-linux-x64/bin/../src/cli
 1268 ?        Sl     0:00 /usr/bin/ruby2.2 /usr/local/bin/fluentd -c /usr/local/etc/fluentd.conf -d /var/run.fluentd.pid
 1271 ?        Sl     0:00 /usr/bin/ruby2.2 /usr/local/bin/fluentd -c /usr/local/etc/fluentd.conf -d /var/run.fluentd.pid
 1417 pts/0    S      0:00 sudo nohup /home/ubuntu/lurker/bin/lurker -i eth1 172.30.1.xxx:* -f localhost
 1418 pts/0    Sl     0:00 /home/ubuntu/lurker/bin/lurker -i eth1 172.30.1.64:* -f localhost
 1444 pts/0    S+     0:00 grep --color=auto -e elasticsearch -e kibana -e lurker -e fluentd
```

Kibanaに接続する
-----------

最後にKibanaに接続します。Kibanaはユーザ制限などの機能が弱いようなので、グローバルにポートは開けず、SSHのSOCKSでアクセスするようにします。

```bash
% ssh -i .ssh/ec2.pem ubuntu@52.68.xxx.xxx -D 4000
```

などと設定して、ブラウザの設定でローカルのポート4000でSOCKS Proxyを設定します。その後、`http://172.30.xxx.xxx:5601` のように指定（172.30.xxx.xxxは**eth0**のプライベートIPアドレス）してブラウザを開くことで、Kibanaの画面が開くはずです。

最初は以下の様なページがでてindex作成の設定をもとめられます。デフォルトのままでいいので、`Create`を選択します。

![kibana_config.png](https://qiita-image-store.s3.amazonaws.com/0/27627/f3968b0e-31a1-351c-a2a5-9299af418b76.png)

その後、上のメニューの`Discover`や`Visualize`などから必要な分析をすることができます。