YAMAHA RTXルータのsyslogをDockerで構築したEFK(Elasticsearch+Fluentd+Kibana)で可視化

# 注意
この2019年に投稿した内容では古くてそのままでは動作しなくなっているので別に投稿しました。

https://qiita.com/ohhara_shiojiri/items/62f061e1038fc4ce2c9e

# 更新内容
2022/06/07 新しい内容で投稿した記事について注意追加
2019/06/11 GitHubに設定ファイルのリポジトリを掲載
2019/05/24 Fluentdの設定説明に加筆とGeoIP設定を追加

# 背景
ルータ機器のファイアウォールのフィルターログをsyslogで収集する事で簡易的なハニーポットとして監視ができます。
ただ膨大なテキストのsyslogのログに溺れてしまうので、EFK(Elasticsearch+Fluentd+Kibana)で可視化してみます。
![rtx-syslog.jpg](https://qiita-image-store.s3.amazonaws.com/0/35898/3244592b-ba4b-8c69-b73f-ee619903d448.jpeg)

#ルータ機器
YAMAHA RTXシリーズ
どこのご家庭でもよく使われているYAMAHA のRTXシリーズのsyslogを前提条件とします。
また１台だけでなく複数台の利用も想定して、ファシリティ番号にタグ付けも行います。
なお、RTXシリーズのファイアウォール設定については割愛します。
syslog設定は以下の様になります。

```:
syslog host [syslogサーバー指定]
syslog facility [ファシリティ番号]
syslog notice on
```

syslogはUDP/514番を使用しますので、ファイアウォール設定を忘れずに。

# Docker環境
ホストOSには、ubuntu server 18.04 LTS を使用、Docker CEとDocker-composeでコンテナを作成します。
インストール方法は公式ガイドを参照下さい。一例も記録しておきます。

Docker CE インストール
https://docs.docker.com/install/linux/docker-ce/ubuntu/

````
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce
$ apt-cache madison docker-ce
$ sudo docker run hello-world
````

Docker Compose インストール
https://docs.docker.com/compose/install/

````
$ sudo -i
# curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# exit
$ docker-compose --version
````

# EFK(Elasticsearch+Fluentd+Kibana)の構築
本来なら複雑なEFKの構築はdocker-composeで簡単に出来ます。

## Elasticsearch設定
事前にElasticsearchはVMの仮想メモリ設定が必要

```
$ sudo sysctl -w vm.max_map_count=262144
```

自動設定

```:/etc/sysctl.conf
vm.max_map_count=262144
```

## 作業用ディレクトリの作成
EFKの作業用ディレクトリを作成します。

```
$ mkdir -p efk
$ cd efk
```

## GitHubからリポジトリを取得
必要な設定ファイルをGitHubにアップしてありますのでリポジトリから取得します。
https://github.com/ohhara-shiojiri/syslog-efk

```
$ git clone https://github.com/ohhara-shiojiri/syslog-efk.git
```

### fluentd syslog設定
syslogのログをElasticsearchに蓄積してkibanaでグラフなどで可視化する訳ですが、ある程度分類してからどの様なフォーマットでElasticsearchへ転送するかで可視化のし易さに影響します。
ここでは一例の設定を紹介します。

ログディレクトリの作成

```
$ mkdir -p log
```
Elasticsearchとは別にsyslogの生データをテキストファイルで保存します。
バックアップの他に正規表現のパターン解析などに利用できます。

### syslog受信設定

```:efk/fluentd/fluent.conf
<source>
  @type syslog
  port 5140
  bind 0.0.0.0
  format none
  tag raw.syslog
</source>
```
fluentdでsyslogを受ける部分。別途syslogサーバーを用意しなくてもfluentdが受信します。
docker-composeのポートフォワードでUDP/514をUDP/5140に転送しているのでこの様になります。

### ファイル保存と正規表現によるパターン抽出

```:efk/fluentd/fluent.conf
<match raw.syslog.**>
  @type copy
  <store>
    @type file
    path /home/fluent/log/syslog/syslog
    time_slice_format %Y%m%d
    <buffer time>
      @type file
      path /home/fluent/log/syslog/buffer
    </buffer>
  </store>
  <store>
    @type parser
    format multi_format
    key_name message
    remove_prefix raw
    add_prefix facility
    <pattern>
      format with_extra_fields
      base_format /^(?<target>.+)\s+Rejected\s+at\s+(?<direction>.+)\((?<filter_num>.+)\)\s+filter:\s+(?<proto>.+)\s+(?<src_ip>.+):(?<src_port>.+)\s+>\s+(?<dest_ip>.+):(?<dest_port>.+)$/
      extra_fields { "log_type": "reject" }
    </pattern>
    <pattern>
      format with_extra_fields
      base_format /^(?<msg>.+)$/
      extra_fields { "log_type": "other" }
    </pattern>
  </store>
</match>
```
syslogのログはlog/syslog/syslogにファイル保存する設定とfluentdへ転送しています。
ログの検索パターンとして、ファイアウォールの「Rejected」ログを条件に抽出しています。
条件に該当しないログは最後に「other」として分類します。

### ファシリティ番号のタグ設定

```:efk/fluentd/fluent.conf
<match facility.syslog.**>
  @type record_reformer
  tag yamaha_rtx
  <record>
    @facility ${tag_parts[-2]}
  </record>
</match>
```
複数のRTXルータ機器からのsyslogを区別する為にファシリティ番号で分けてタグ付けします。
これでどのRTXルータ機器からのログか判別出来ます。

### GeoIPの設定
IPアドレスから国名を特定するGeoIPのFluentd Pluginを設定します。
またKibanaの地図表示をする為に緯度経度の座標の値も取得します。
FluentdのDockerfileには既に設定済みなのでインストールはこの時点で出来ています。
注意点として、「match」ではなく「filter」で設定する。
また「filter」は「match」の直前で設定する事です。
そしてElasticsearchの座標フィールドのtypeの型は「geo_point」に設定する。
ここがハマりどころなので例で説明します。

```:efk/fluentd/fluent.conf
<filter yamaha_rtx.**>
  @type geoip
  geoip_lookup_key  src_ip
  <record>
    location  '[${location.latitude["src_ip"]},${location.longitude["src_ip"]}]'
    country_name    ${country.names.en["src_ip"]}
  </record>
  skip_adding_null_record  true
</filter>
```
FulentdからElasticsearchへ転送する箇所で、
「\<match yamaha_rtx.\*\*\>」の手前に「\<filter yamaha_rtx.\*\*\>」を設定します。
「location」に緯度経度の座標が配列で設定されます。
「country_name」に国名が設定されます。
また、国名が特定できないデータではスキップして除外されます。

### fluentdからElasticsearchへ転送設定

```:efk/fluentd/fluent.conf
<match yamaha_rtx.**>
  type elasticsearch
  logstash_format true
  logstash_prefix yamaha_rtx
  include_tag_key true
  tag_key @log_name
  hosts elasticsearch:9200
  buffer_type memory
  num_threads 1
  flush_interval 60
  retry_wait 1.0
  retry_limit 17
</match>
```
最後にElasticsearchへの転送設定

# EFKコンテナ環境の起動
設定ファイルが用意出来たらdocker-composeでEFKの各コンテナ環境を起動します。

```
$ docker-compose build
$ docker-compose up -d
```
先にfluentdのコンテナをビルドしてコンテナイメージを作成してから各コンテナを起動しています。



### Elasticsearchの設定
kibanaで地図表示する際に、緯度経度の座標フィールドは「geo_point」の型である必要がありますが、自動では「float」型になってしまいます。
また、Elasticsearchへは日付毎に分けてデータ登録されるので、毎回データ型を変更するのは大変なので、テンプレート設定で自動化しておきます。

Elasticsearchが起動している状態で、以下の設定をコマンドラインで実行します。

```
$ curl -X POST -H 'Content-Type: application/json' 'localhost:9200/_template/yamaha_rtx-reject' -d '{
  "template": "yamaha_rtx-reject-*",
  "mappings": {
    "fluentd": {
      "properties": {
        "location": {
          "type": "geo_point"
        }
      }
    }
  }
}'
```

設定後に追加されたデータから変更が有効になるので、既存のデータは削除しておきます。
kibanaの設定画面から「Management」→「Elasticsearch」→「Index management」→「yamaha_rtx-reject-年月日」
→「Mapping」で「location」のtypeが「geo_point」になっていればOKです。
また、「Management」→「Kibana」→「Index Patterns」→「yamaha_rtx-reject-\*」→「Name」→「location」のtypeが「geo_point」になっていればOKです。


# KibanaのWebUI画面
無事にEFKの各コンテナ環境が起動したらWebブラウザでKibanaを表示させます。
http://127.0.0.1:5601

Kibanaの操作方法としては、「management」でElasticsearchにFulentd経由のログが来ているか確認。
「management」の「index Patterns」でログパターンを登録すれば、あとはお好みのグラフ等で可視化が出来ます。

# 参考

[Yamahaルータ(RTX810)のログをsyslogで飛ばしてdocker + EFKで見る]
(https://qiita.com/330k/items/7c266b44d4a23f017634)
[Fluentd + Elasticsearch + Kibana を使って YAMAHA RTX1100 の syslog をそれっぽく可視化する]
(https://qiita.com/hiraro/items/474879a70b7b8a715782)