【AWS】Elasticsearch Service（Elasticsearch＋Kibana）＋LogstashでALBアクセスログを分析し、 送信元の地域をマップ上に可視化する

#はじめに
先日、AWSのEC2でWebアプリを実行している環境で、国内のどの地域からのアプリ利用者が多いか知りたい、という要望に対応する機会がありました。

ElasticsearchのKibanaを使うと「Region Map」という地図を使ってデータを視覚化できます。

これを活用してALBのアクセスログに含まれる送信元IPアドレスの情報から送信元地域を特定し、Kibanaのマップ上に可視化することができましたので、今回の記事ではそのやり方を紹介したいと思います。

#対象者
* Elasticsearchについて知りたい方
* AWSのElasticsearch Serviceについて知りたい方
* ALBのアクセスログを可視化してみたい方
* KibanaのVisualizeでRegion Mapを使ってみたい方　など

#Elasticsearchとは
オープンソースのデータ検索エンジンです。
データ収集パイプラインのLogstash、視覚化ツールのKibanaと組み合わせることで、任意のデータの検索・分析・可視化を実現できます。

>Elasticsearchは、様々なユースケースを解決する分散型RESTful検索/分析エンジンです。
>データを一元的に格納することで、超高速検索や、関連性の細かな調整、パワフルな分析が大規模に、手軽に実行可能になります。
>（[公式ページ](https://www.elastic.co/jp/elasticsearch/)より抜粋）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/2d413a3e-3387-7305-7501-a8a112ea2a57.png" width=50%>

#Elasticsearch Serviceとは
Elasticsearchの実行環境を簡単にデプロイできるAWSのフルマネージド型のサービスです。
Kibanaがビルトインされており、デプロイ後すぐにデータ分析を開始できます。
フルマネージド型でインフラの管理が不要なのはもちろんですが、ESクラスターはVPCに作成されるため、外部との接続点を持たない内部ネットワークで完結する分析環境を簡単に作成できるというメリットがあります。

[Amazon Elasticsearch Service](https://aws.amazon.com/jp/elasticsearch-service/)


#実現すること
* AWSでElasticsearchの実行環境の作成する
* LogstashでALBのアクセスログを収集し、送信元IPから送信元の都道府県を特定する
* KibanaのVisualizeでRegion Mapの設定を行い、アクセスが多い地域・少ない地域が一目で分かるマップを作成する

#構成
Elasticsearchの導入にあたっては、管理の手間を削減するため、AWSのマネージドサービス「Amazon Elasticsearch Service（以下、Amazon ES）」を利用します。
Amazon ESで提供されるのはElasticsearch＋Kibanaですが、地理情報のマッピングにLogstashが必要なため、別途EC2を作成してLogstashをインストールします。
構成イメージは以下のとおりです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/ed411169-aa3d-9489-5923-fe285c8a0753.png" width=80%>

#注意点
* 2020年10月時点の情報です。
* AWSマネジメントコンソールを使用します。ルートユーザもしくは権限を満たすIAMユーザを利用できる前提で進めます。
* AWS利用料にご注意ください。利用料については、AWSの公式ページをご参照ください。

#環境構築
##前提
・Elasticsearch Service
　→バージョン：7.7
・Logstashサーバ
　→AMI：Amazon Linux2
　→インスタンスタイプ：t2.small
　　※microだとメモリ不足でlogstashがまともに動いてくれませんでした。small以上がおすすめです。
　→Logstashバージョン：7.9.0

##構築手順
#####1.ELBログの有効化と、出力用のS3バケット作成
参考手順は[こちら](https://qiita.com/Goi350ml/items/4ccc4c24650d734838b7) 

#####2.ESクラスター作成
* 本番稼働用はマルチAZ構成となるため、シングル構成で問題ない場合は開発／テスト用を選択
* インターネットでVPCの外からKibanaにアクセスしたいため、ネットワーク構成はパブリックアクセスを選択
* Cognitoの設定を行い、Kibanaログインに認証を追加

Cognito設定については、[こちら](https://docs.aws.amazon.com/ja_jp/elasticsearch-service/latest/developerguide/es-cognito-auth.html)を参照

#####3.Logstash用EC2インスタンス作成、ログイン

#####4.Logstashインストール
OpenJDKインストール

```
yum install java-1.8.0-openjdk -y
```

リポジトリ作成

```
vi /etc/yum.repos.d/logstash.repo
```
```/etc/yum.repos.d/logstash.repo
[logstash-7.x]
name=Elastic repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
```
Logstashインストール

```
yum install logstash -y
```

amazon_esのプラグインを追加

```
/usr/share/logstash/bin/logstash-plugin install logstash-output-amazon_es
```

#####5.logstash.conf設定
```
vi /etc/logstash/logstash.conf
```

```/etc/logstash/logstash.conf
input {
s3 {
    tags => "alb"
    bucket => "<バケット名>"
    region => "<リージョンコード>"
    interval => "60"
    sincedb_path => "/var/lib/logstash/sincedb_alb"
   }
}
filter {
    grok {
        match => [ "message", "%{ELB_ACCESS_LOG}" ]
    }

    date {
        match => [ "timestamp", "ISO8601" ]
        target => "@timestamp"
    }

    geoip {
        source => "clientip"
    }
    if [geoip][region_code] {
      mutate {
        add_field => {
          "[geoip][region_iso_code]" => "%{[geoip][country_code2]}-%{[geoip][region_code]}"
      }
    }
  }

    mutate {
        remove_field => ["timestamp", "message"]
    }
}
output {
    amazon_es {
        hosts => ["<Elasticsearch Serviceのエンドポイント>"]
        region => "<リージョンコード>"
        index => "<設定したいインデックス名>-%{+YYYY.MM.dd}"
    }
}
```

#####6.Logstash起動
```
cd /usr/share/logstash
bin/logstash -f "/etc/logstash/logstash.conf"
```

#####7.Kibanaログイン・設定
logstash.confに記載したindex名でindex patternを作成します。

以下の画面では、logstash.confのインデックス名に「elblogs」を設定したため、「elblogs-yyyymmdd」の形式でデータが作成されています。
この場合、index patternは「elblogs*」となります。
![スクリーンショット 2020-10-21 104057.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/1548b7f5-3b3b-c252-6553-c0ddf852e2d9.png)

index patternを作成したら、VisualizeでRegion Mapを選択し、作成したindex patternを選んで設定を行います。
以下はRegion Mapで国内の送信元地域を確認する場合の参考画面です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/1ecbaa5c-457e-d7a1-a0ea-18d1af58f89e.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/c1e5cb1b-719c-8d34-b183-05cfe16c518b.png" width=50%>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/6252af85-6f2d-4b17-bce0-5705249482ba.png" width=50%>
さらに上記に加えてFilterを設定すると、確認したい通信を絞って表示することができます。

##Visualize後のRegion Map
#####＜イメージ①＞国内のアクセス数確認
以下のマップでは、東京からのアクセスが多いことを確認できます。
(注)接続元のインターネットの回線によって、東京からアクセスしたものが埼玉にカウントされたり、千葉でアクセスしたものが東京にカウントされたりする場合があります。
都道府県というよりは、関東や関西といったおおまかな地域を判別するのに有効かと思います。
![スクリーンショット 2020-10-22 115608.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/ce4e99bc-74ea-ce3e-4e4a-9bebb51e5d75.png)

#####＜イメージ②＞国外のアクセス数確認
以下のマップでは、世界各地からのアクセス傾向を確認できます。
国内からのアクセスが多いのは当然ですが、想定していない海外からの通信（攻撃）がたくさん発生していることがわかりました（怖）

![スクリーンショット 2020-10-22 120041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/a6f5b516-446c-2ae2-0ed2-1c1c65ed9af2.png)


#参考元リンク
[logstash-output-amazon_esを使ってAmazon Elasticsearch Serviceにデータを投入する](https://dev.classmethod.jp/articles/amazon-es-using-logstash-plugin/)
[Amazon Linux2でLogstash7.5を動かす [起動編]](https://infraya.work/posts/amazonlinux_install_logstash/)

#さいごに
今回は送信元のマップ表示に焦点を当ててきましたが、ALBアクセスログを対象データとする場合には、日別や時間帯別のアクセス傾向などをグラフで可視化することもできます。
また、Kibanaでは、複数のグラフや表をダッシュボードにまとめて表示することも可能です。

↓ダッシュボードのイメージです
![ダッシュボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703690/c5c5d9d0-2ba8-21f1-e48d-99380ba565c8.png)

このように、アクセスログを分析するだけでも様々な情報を拾うことができます。
ALBを利用するシーンは多いですし、分析したデータはマーケティング等にも活用できると思いますので、試していない方は是非チャレンジしてみてください。