Elastic StackによるAkamaiログの保存1 ～Elastic Stackの構築～


## この記事の目的
Akamaiの提供している複数のソリューションでは、SIEMによるログ連携をサポートしています。本記事では、Linodeで構築したLinuxサーバーにElastic Stackをインストールし、各種ログを集約して可視化できるようにします。
Elastic Stackの構築から準備までの前半を今回の記事で、続く後半では、SIEM Integrationによるセキュリティイベントログの取得を２回に分けて紹介します。

## SIEM Integrationとは
SIEM Integrationは、Akamaiプラットフォームで発生するセキュリティイベントログを収集し、SIEMツールへ配信する方法を提供する仕組みです。例えば、Akamai WAAP(WAF)ソリューションのApp & API Protectorには、この機能が標準で含まれていますので、Linode等のクラウドサーバー上にSIEMを用意すれば、簡単にApp & API Protectorのセキュリティログイベントの収集・長期保存・分析を行うことができます。
今回構築する環境では、WAFやDoS対策などを提供するApp & API Protector、ボット対策や不正ログインの対策を行うBot Manager Premier、Account Protectorなど複数のセキュリティイベントログをElastic StackからPullする形で取得します。なお、Elastick Stack以外のSIEM製品を用いる場合でもAkamaiのSIEM IntegartionではPull型で取得を行う必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/cf709a3c-610f-ee1e-bb9a-07cb43f9bca2.png)


## Elastic Stackとは
Elastic Stack（エラスティックスタック）は、検索・分析・可視化などを行うためのオープンソースのソフトウェアスイートです。Elasticsearchに、Logstash、Kibana、Beatsという3つのツールが加わり、現在ではElastic Stackとして提供されています。
Elasticsearchは、分散型の全文検索エンジンであり、非常に大量のデータに対して高速に検索を行うことができます。Logstashは様々な形式のデータを収集して加工し、Elasticsearchに格納することができます。KibanaはElasticsearchに格納されたデータを可視化するためのツールであり、ダッシュボードやグラフ、チャートなどを作成することができます。Beatsは軽量なデータ収集エージェントであり、Logstashと同様に様々な形式のデータを収集してElasticsearchに送信することができます。

Elastic Stackは、大量のログデータやセキュリティイベントログ、システムログなどを収集して、分析や可視化を行うことができるため、ビジネスインテリジェンスやセキュリティ監視などの用途に利用されています。また、Elastic Stackはオープンソースであり、コミュニティーによって積極的に開発・改善されているため、柔軟性や拡張性に優れています。

今回はElasticsearch、Kibana、Fleetを用いています。Logstashは今後SIEM Integartion以外で利用する予定です。またFleetにはBeatsの要素も含まれているということもあり、本記事では便宜上、Elastic Stackと表現しています。

Elastic Stackは複数のサブスクリプションにて提供されており、無料できる範囲、有償でできる範囲は、以下で示すページにて記載されています。必要に応じて使い分けてください。

https://www.elastic.co/jp/subscriptions


今回はログを取得することに重点をおいていますのでElastic Stackの冗長構成やホストの分割などは行わず、可能な限り単一のサーバーで構成しています。実際に業務で構築する際は下記ドキュメントなどを参照の上、設計・構築を行ってください。

https://www.elastic.co/guide/en/elasticsearch/reference/current/high-availability.html


## StackScriptを用いたElastic Stackの展開
本記事ではElastic Stackを手動でインストールして進めますが、LinodeのStackScriptを用いてElastic StackとDataStream2を連携する手順については、こちらでも記事を公開していますので参考にしてください。

https://qiita.com/hideki_okamoto/items/6a2bcc9b1964c071eb12


## Linodeインスタンスの作成
それでは始めていきましょう。
まずはLinodeインスタンスを作成します。

今回はUbuntu 22.04 LTSを選択します。RegionやLinode Planもそれぞれ選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/edbf2102-c2e7-29ac-f663-c55f829fece5.png)

Linode LabelやRoot Passwordを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/053c81c4-1459-5f00-85f0-611df4761ba6.png)

任意でBackupsのチェックをいれ、「Create Linode」ボタンをクリックしてLinuxインスタンスを展開します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/95889bc6-0b98-dce3-7e7b-3b0e94512cf9.png)



### Linux初期設定
Linodeインスタンスが（Linux）作成できたら初期設定を行います。初期設定は以下のリンクもご参考ください。

https://qiita.com/tarooishi/items/5f8ec51323eeed919818

ここでは以下の通りいくつかの初期設定を行います。
まずは、ユーザーの追加及びホスト名の設定します。任意のユーザー名を作成してください。
```
# adduser -a user01
# gpasswd -a user01 sudo
# hostnamectl set-hostname el-stack
```

時刻関連の設定をします。
```
# vi /etc/systemd/timesyncd.conf
```
```bash:timesyncd.conf
NTP=pool.ntp.org
```

```
# systemctl restart systemd-timesyncd
# systemctl status systemd-timesyncd

# timedatectl set-timezone Asia/Tokyo
# timedatectl
               Local time: Tue 2023-03-21 10:43:51 JST
           Universal time: Tue 2023-03-21 01:43:51 UTC
                 RTC time: Tue 2023-03-21 01:43:51
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no
```

最新のパッケージに更新し、追加でいくつかのパッケージをインストールします。
```
# apt update && apt upgrade -y
# apt install net-tools httpie jq -y
```

標準Firewallの設定を行います。SSH及び、Elastic Stackに必要なポートのみを公開します。
必要に応じて送信元IPの制御も行ってください。
```
# ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup

# ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

# ufw allow 22
Rule added
Rule added (v6)

# ufw allow 9200
Rule added
Rule added (v6)

# ufw allow 5601
Rule added
Rule added (v6)
root@el-stack:~#

# ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         ALLOW IN    Anywhere
9200                       ALLOW IN    Anywhere
5601                       ALLOW IN    Anywhere
22 (v6)                    ALLOW IN    Anywhere (v6)
9200 (v6)                  ALLOW IN    Anywhere (v6)
5601 (v6)                  ALLOW IN    Anywhere (v6)

```

SSHのルートログインを無効化します。
```
# vi /etc/ssh/sshd_config
```

```bash:sshd.conf
PermitRootLogin no
```


初期設定が完了したら一旦OSを再起動します。
```
# reboot
```



## Elasticsearchのインストール
ここからは先ほど作成したユーザーでSSHログインを行い、インストールを継続します。

JDK(Java)をインストールします。
```bash
$ sudo apt install default-jdk -y
$ java --version
openjdk 11.0.18 2023-01-17
OpenJDK Runtime Environment (build 11.0.18+10-post-Ubuntu-0ubuntu122.04)
OpenJDK 64-Bit Server VM (build 11.0.18+10-post-Ubuntu-0ubuntu122.04, mixed mode, sharing)
```

Elasticsearchをインストールします。
```bash
$ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK

$ sudo echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-8.x.list
deb https://artifacts.elastic.co/packages/8.x/apt stable main

$ sudo apt update
$ sudo apt install elasticsearch
```


インストール完了時に以下のようなメッセージが表示されます。elasticユーザーのパスワードが記載されているため、メモをしておきます。
```bash:
--------------------------- Security autoconfiguration information ------------------------------

Authentication and authorization are enabled.
TLS for the transport and HTTP layers is enabled and configured.

The generated password for the elastic built-in superuser is : ＜ここにパスワード＞

If this node should join an existing cluster, you can reconfigure this with
'/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <token-here>'
after creating an enrollment token on your existing cluster.

You can complete the following actions at any time:

Reset the password of the elastic built-in superuser with
'/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'.

Generate an enrollment token for Kibana instances with
 '/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana'.

Generate an enrollment token for Elasticsearch nodes with
'/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node'.

-------------------------------------------------------------------------------------------------

```


### インデックス保存用Volumeの作成
Linodeインスタンスのディスクは後で容量を増やせないため、一旦ここでLinodeにてNVMe Volumeを別途追加し、Elasticsearchのインデックスを保存する領域を確保します。

Linodeにて「Create Volume」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/b7357e08-f47d-e0af-ac4b-12c1d2a76b35.png)

任意のラベル名や容量などを入力して「Create Volume」をします。ここでは100GBとしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/f557e5ef-3278-756b-f500-c7cb92696bc3.png)

Volumeをマウントする手順が表示されます。基本はこのままですが、今回はElasticsearchのインデックスを保存するディレクトリとして利用しますので、マウント先のみ変更します。
<img width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2705a1e9-aa00-6642-e407-259e8ab34bd7.png">

以下のようにVolumeの初期化やマウントなどを行います。
```
$ su -
# mv /var/lib/elasticsearch /var/lib/elasticsearch-old
# mkfs.ext4 "/dev/disk/by-id/scsi-0Linode_Volume_El-Stack"
# mkdir "/var/lib/elasticsearch"
# mount "/dev/disk/by-id/scsi-0Linode_Volume_El-Stack" "/var/lib/elasticsearch"
# chmod 2750 /var/lib/elasticsearch
# chown elasticsearch. /var/lib/elasticsearch
# vi /etc/fstab
```
/etc/fstabに追記して再起動後もマウントされるようにします。
```bash:fstab
/dev/disk/by-id/scsi-0Linode_Volume_El-Stack /var/lib/elasticsearch ext4 defaults,noatime,nofail 0 2
```

```
# df -m
Filesystem     1M-blocks  Used Available Use% Mounted on
tmpfs               1601     1      1600   1% /run
/dev/sda          320944  9395    308262   3% /
tmpfs               8001     0      8001   0% /dev/shm
tmpfs                  5     0         5   0% /run/lock
/dev/sdc          100221     1     95085   1% /var/lib/elasticsearch
tmpfs               1601     1      1601   1% /run/user/1001
```

OS再起動後もマウントされることを確認します。
```
# reboot
# df -m
Filesystem     1M-blocks  Used Available Use% Mounted on
tmpfs               1601     1      1600   1% /run
/dev/sda          320944  9395    308262   3% /
tmpfs               8001     0      8001   0% /dev/shm
tmpfs                  5     0         5   0% /run/lock
/dev/sdc          100221     1     95085   1% /var/lib/elasticsearch
tmpfs               1601     1      1601   1% /run/user/1001
```



## Elasticsearchのインストール続き

elasticsearch.ymlを修正します。
```
$ sudo vi /etc/elasticsearch/elasticsearch.yml
```

```bash:elasticsearch.yml
network.host: 0.0.0.0
http.port: 9200 
```

Elasticsearchを開始します。
```bash
$ sudo systemctl start elasticsearch
$ sudo systemctl status elasticsearch
$ sudo systemctl enable elasticsearch
```



簡易動作確認を行います。以下のような出力が行われ、Errorとならなければ成功です。
先ほどのElasticsearchインストール時に出力された「Security autoconfiguration information」に記載の、elasticユーザーのパスワードを用います。
```
$ sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic https://localhost:9200
Enter host password for user 'elastic': ここでパスワードを入力します
{
  "name" : "el-stack",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "agQ2REIjSuWzWCXydpOoyg",
  "version" : {
    "number" : "8.6.2",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "2d58d0f136141f03239816a4e360a8d17b6d8f29",
    "build_date" : "2023-02-13T09:35:20.314882762Z",
    "build_snapshot" : false,
    "lucene_version" : "9.4.2",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}
```




## Kibanaのインストール

引き続き、Kibanaをインストールします。
```
$ sudo apt install kibana -y
```

kibana.ymlを修正します。
```
$ sudo vi /etc/kibana/kibana.yml
```
```bash:kibana.yml
server.host: "0.0.0.0"
server.port : 5601
```

Kibanaを開始します。
```
$ sudo systemctl start kibana
$ sudo systemctl status kibana
● kibana.service - Kibana
     Loaded: loaded (/lib/systemd/system/kibana.service; disabled; vendor preset: enabled)
     Active: active (running) since Sun 2022-10-09 12:40:24 JST; 12s ago
       Docs: https://www.elastic.co
   Main PID: 6445 (node)
      Tasks: 11 (limit: 9406)
     Memory: 316.3M
        CPU: 13.321s
     CGroup: /system.slice/kibana.service
             mq6445 /usr/share/kibana/bin/../node/bin/node /usr/share/kibana/bin/../src/cli/dist


$ sudo systemctl enable kibana
```



## KibanaのHTTPS化

Kibanaに対してはブラウザを用いて接続しますが、HTTPSにてアクセスできるように設定を行います。Kibana用のサーバー証明書を準備します。
```
$ sudo apt install unzip
$ cd /usr/share/kibana/

$ sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca -pem
This tool assists you in the generation of X.509 certificates and certificate
signing requests for use with SSL/TLS in the Elastic stack.

The 'ca' mode generates a new 'certificate authority'
This will create a new X.509 certificate and private key that can be used
to sign certificate when running in 'cert' mode.

Use the 'ca-dn' option if you wish to configure the 'distinguished name'
of the certificate authority

By default the 'ca' mode produces a single PKCS#12 output file which holds:
    * The CA certificate
    * The CA's private key

If you elect to generate PEM format certificates (the -pem option), then the output will
be a zip file containing individual files for the CA certificate and private key

Please enter the desired output file [elastic-stack-ca.zip]:  ENTERを押下
```

証明書を/usr/share/kibana/に展開します。
```
$ sudo ls /usr/share/elasticsearch/
bin  elastic-stack-ca.zip  jdk  lib  modules  NOTICE.txt  plugins  README.asciidoc

$ sudo mv /usr/share/elasticsearch/elastic-stack-ca.zip ./
$ sudo unzip elastic-stack-ca.zip
Archive:  elastic-stack-ca.zip
   creating: ca/
  inflating: ca/ca.crt
  inflating: ca/ca.key

```

kibana.ymlを修正します。
[LinodeインスタンスのグローバルIP]はLinodeに割り当てられたグローバルIPを入力します。
```
$ sudo vi /etc/kibana/kibana.yml
```
```bash:kibana.yml
server.ssl.enabled: true
server.ssl.certificate: /usr/share/kibana/ca/ca.crt
server.ssl.key: /usr/share/kibana/ca/ca.key

server.publicBaseUrl: "https://[LinodeインスタンスのグローバルIP]:5601/"
```

Kibanaを再起動します。
```
$ sudo systemctl restart kibana
```


## Kibanaの初期設定
Kibanaに初めてログインする際に、Tokenとverification codeが必要となるため、コマンドにて取得しメモしておきます。
```
$ sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token --scope kibana
eyJ2ZXIiOiI4LjYuMiIsImFk--略--jYjY2MmI2YzBmNWU2MGU3Iiwia2V5IjoiSC1EMV9JWUI2V1ZYeE9OWTg1a3Y6Mkh3YXc3TGtRRi1fblRlcWtvdFRDQSJ9

$ sudo /usr/share/kibana/bin/kibana-verification-code
Your verification code is:  671 897
```

パソコンのブラウザを用いて、Kibanaに接続します。
https://[LinodeインスタンスのグローバルIP]:5601/


先ほどのelasticsearch-create-enrollment-tokenで取得したトークンを貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/2525c52c-910e-249d-d144-77e8364288fa.png)

同じくkibana-verification-codeで取得した、verification codeを貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/946ef184-7608-5b7c-94b5-0551acddfa5b.png)


初期設定が開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/678f10b7-3f3f-81ca-9c17-42757ab07e24.png)


Elasticsearchインストール時の「Security autoconfiguration information」に記載されたelasticユーザーのパスワードを用いて、elasticユーザーにてログインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/c8892948-b505-7b51-6873-8748b1913d36.png)


Kibanaへログインができました。ここではExplore on my ownを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/0c1433b8-d2da-ed97-8559-835fd9cf623a.png)


無事ポータル画面が表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/e80b91b8-9cdf-db11-49ce-2a0b9fa11aa7.png)


elasticユーザーに任意のパスワードを設定します。その後、改めて変更したユーザーでKibanaへログインしてください。ここでは省略しますが必要に応じて別のユーザーも作成してください。
```
$ sudo  /usr/share/elasticsearch/bin/elasticsearch-reset-password -i -u elastic
This tool will reset the password of the [elastic] user.
You will be prompted to enter the password.
Please confirm that you would like to continue [y/N]y

Enter password for [elastic]:
Re-enter password for [elastic]:
Password for the [elastic] user successfully reset.
```






https://[LinodeインスタンスのグローバルIP]:5601/status にアクセスし、ステータスがGreenであることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/81e52f84-e8db-3900-e411-90000572147d.png)



## Kibanaの日本語化
必要に応じてKibanaを日本語対応にします。

kibana.ymlを修正し、enをja-JPに変更
```bash
$ sudo vi /etc/kibana/kibana.yml
```
```bash:kibana.yml
i18n.locale: "ja-JP"
```
Kibanaを再起動します。
```
$ sudo systemctl restart kibana
```

以下のように日本語化されれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821330/e1fa6dce-a948-bd20-c83a-63bd3a053855.png)



今回は以上となります。Linode上にElastic Stackを構築することでAkamaiのSIEM Integrationなどのログを収集する準備ができました。なお、SIEMは様々なシステムで用いられているため、Linodeで構築することにより安価なSIEMプラットフォームとして構成することも可能です。ぜひLinodeを用いたElastic Stack導入を検討してみてください。

次回は、Elastic StackのAgent一元管理機能であるFleetのインストール、そしてAkamai SIEM Integrationの連携を進めていきます。

https://qiita.com/kabe-akam/items/d84f2c49eafd7915b8a8