docker-elkを使って過去のCloudTrailのログをサクッと分析してみた

こんにちは、佐伯です。CloudTrailのログを分析をする機会がありました。どうやって分析しようかなと考えていたところ、GitHubでdocker-elkを発見し、お手軽で便利だったので紹介させて頂きます。

環境

以下の環境で実施しています。

  • macOS High Sierra version 10.13.5
  • Docker CE for Mac version 18.03.1-ce-mac65
  • Docker Compose version 1.21.1

やってみた

docker-elkのclone

docker-elkをcloneします。

$ git clone git@github.com:deviantony/docker-elk.git
Cloning into 'docker-elk'...
remote: Counting objects: 1317, done.
remote: Total 1317 (delta 0), reused 0 (delta 0), pack-reused 1317
Receiving objects: 100% (1317/1317), 272.64 KiB | 254.00 KiB/s, done.
Resolving deltas: 100% (519/519), done.

Logstashの設定変更

logstash/pipeline/logstash.conf のinputにcodec => "json_lines"を追加します。

$ git diff
diff --git a/logstash/pipeline/logstash.conf b/logstash/pipeline/logstash.conf
index 10e442e..ea959de 100644
--- a/logstash/pipeline/logstash.conf
+++ b/logstash/pipeline/logstash.conf
@@ -1,6 +1,7 @@
 input {
        tcp {
                port => 5000
+               codec => "json_lines"
        }
 }

Dockerイメージのビルド

docker-compose build コマンドでElasticsearch, Logstash, KibanaのDockerイメージをビルドします。

$ docker-compose build
Building elasticsearch
Step 1/1 : FROM docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.0
6.3.0: Pulling from elasticsearch/elasticsearch-oss
7dc0dca2b151: Pull complete
a50481268b4a: Pull complete
ee5228de771f: Pull complete
da55b983e8eb: Pull complete
143eb5dd5e49: Pull complete
29d8a2d8ea47: Pull complete
be99c5384de1: Pull complete
Digest: sha256:0e0d73cb8bdce88c25adb9426aecabf89db4235d44ea29402f5f28b813f23d2e
Status: Downloaded newer image for docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.0
 ---> 345a3630eed8
Successfully built 345a3630eed8
Successfully tagged docker-elk_elasticsearch:latest
Building logstash
Step 1/1 : FROM docker.elastic.co/logstash/logstash-oss:6.3.0
6.3.0: Pulling from logstash/logstash-oss
7dc0dca2b151: Already exists
49bfedd6a110: Pull complete
a64a68a73a51: Pull complete
1cd2ef8fceec: Pull complete
9c36f545c69b: Pull complete
56834e932068: Pull complete
5cddbd76eb86: Pull complete
c3bb761ee199: Pull complete
1d22756d288c: Pull complete
73e34c1b50e9: Pull complete
054f809e4ee2: Pull complete
Digest: sha256:3bb06bac6367163d0e62476a92b93a24391b7d6a0bb9ac775031902eb67bee1c
Status: Downloaded newer image for docker.elastic.co/logstash/logstash-oss:6.3.0
 ---> 77bdbc2dc566
Successfully built 77bdbc2dc566
Successfully tagged docker-elk_logstash:latest
Building kibana
Step 1/1 : FROM docker.elastic.co/kibana/kibana-oss:6.3.0
6.3.0: Pulling from kibana/kibana-oss
7dc0dca2b151: Already exists
b9645d7e6c1f: Pull complete
b302e33a173a: Pull complete
dc79440b74ce: Pull complete
630d27689874: Pull complete
feca8dd48a11: Pull complete
294e4e758537: Pull complete
7200ec2d04f1: Pull complete
0728d5722948: Pull complete
Digest: sha256:61c80292ce97b05f460efe26409f176c20d8f493b9ec4bdd9da0a8fa78ff8f0a
Status: Downloaded newer image for docker.elastic.co/kibana/kibana-oss:6.3.0
 ---> 135bf752e257
Successfully built 135bf752e257
Successfully tagged docker-elk_kibana:latest

コンテナの起動

docker-compose up -dでElasticsearch, Logstash, Kibanaのコンテナを起動します。

$ docker-compose up -d
Creating network "docker-elk_elk" with driver "bridge"
Creating docker-elk_elasticsearch_1 ... done
Creating docker-elk_logstash_1      ... done
Creating docker-elk_kibana_1        ... done

CloudTrailログのダウンロード

AWS CLIを使って分析したい期間分のログをダウンロードします。今回は traillogs/ 配下に7/1〜7/7分のログをダウンロードしています。

$ aws s3 cp s3://<S3 Bucket Name>/AWSLogs/<AWS Account ID>/CloudTrail/<AWS Region>/2018/07/ traillogs/ --exclude "*" --include "*2018070[1234567]*.json.gz" --recursive

CloudTrailのログをLogstashへ送信

以下のコマンドでCloudTrailのログをLogstashへ送信します。

$ find traillogs -name *.json.gz | xargs gzcat | jq -r -c -M .Records[] | nc localhost 5000

docker-compose.ymlを見てもらえばわかりますが、Logstashは5000番ポートでListenしています。CloudTrailのログをgzcatで開き、更にjqで各イベントが一行ずつとなるようにして、標準出力をncコマンドを使って、localhostの5000番ポートへ渡しています。

Kibanaへアクセス

http://localhost:5061 をブラウザで開き、Kibanaにアクセスします。左メニューからDiscover, Visualize, Dashboardのいずれかをクリックするとインデックスパターン作成の画面が表示されます。

インデックスパターンの作成

今回は対象のログのみを送信しており、インデックスの分割もしてないので*を入力し全てのインデックスを対象にしました。

[Time Filter field name]はタイムスタンプが含まれているeventTimeを選択します。

ログの可視化

グラフなどの作成はVisualizeより作成します。今回は簡単に、私が使用しているIAMユーザーによってAPIコールされたイベントのグラフを作ってみました。特に理由はないですが円グラフを選択しました。

先程作成したインデックスパターン*を選択します。

送信したCloudTrailのログと同じ期間になるように、タイムレンジを2018/07/01-07に指定しました。ざっくりと[This year]などを選択しても問題ないです。

[Add a filter]からuserIdentity.userName is <Username>のフィルタを追加し、私の使用しているIAMユーザーでフィルタを行います。

[Buckets]は以下のような設定にして、[Apply changes]をクリックするとグラフが表示されました!

あとは作ったVisualizeを保存して、Dashboardに追加すればおっけーです。

Elasticsearchのデータ保持について

docker-compose downでコンテナを削除するとElasticsearchのデータは削除されます。データを保持したい場合は以下リンクのように、Dockerホストのディレクトリをマウントするように設定します。

How can I persist Elasticsearch data?

まとめ

Amazon Athena + Amazon QuickSightでの可視化も検討しましたが、過去のCloudTrailのログを分析するにあたりリアルタイム性や継続的な可視化は不要だったので、今回はお手軽に使えるdocker-elkを使用しました。(ログの量が多いと大変だけど…)