Fluent BitでWindowsのイベントログを収集する方法

# 近況
NintendoのSwitch2を発売日からプレイしたり、AWS Summitの予約などをしています。
また、AWS SCSの受験をするのでそろそろ勉強を始めないとなあと思いつつマリオカートを起動しちゃっています。

# ざっくり説明

### 実現したいこと

##### ①Windowsクライアント端末のイベントログをS3に配信したい
→Athenaでクエリできるように保存先はS3

##### ②障害調査のために使用するため、できるだけリアルタイムでS3に保存したい
→イベントログが1日に1回まとめて送られるような形では障害調査しづらいので。

##### ③特定のWindowsイベントログのみを配信したい
→Windowsのクライアント端末数が多いため、ある程度ログの量を絞り込みたい

### ざっくりの構成図


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494465/05057918-b834-491b-b1d7-e5f579e38159.png)

##### ①Fluent Bit(Windows)をインストールしたWindowsクライアント端末からNLBにイベントログが送信される。

##### ②NLBで受けたイベントログはターゲットグループに登録されているECSコンテナに流れる。

##### ③Fluent BitのDockerイメージから作成したECSコンテナーでログを処理し、Data Firehoseに送信する。

##### ④Data Firehoseから指定のS3にイベントログを送信する。

##### ⑤ログ確認者がコンソールログインし、Athenaでクエリ実行する。


# ちょっと詳細な設定

### Windowsクライアント端末
##### ①Windows11にFluent Bitをインストールし、設定ファイルであるfluent-bit.confを設定します。

ファイルの中身は下記のように設定しました。
[こちらの記事](https://qiita.com/mmm-kato/items/06ef6c989423f680d597)がわかりやすかったので、参考に設定をしました。


https://qiita.com/mmm-kato/items/06ef6c989423f680d597


```
[SERVICE]
    Flush        1
    Log_Level    info
    Daemon       Off

[INPUT]
    Name         winevtlog
    Channels     System
    Interval_Sec 1
    DB           winevtlog.sqlite
    Tag          windows
    Use_ANSI     False  
    Event_Query  Event/System[EventID=7 or EventID=11 or EventID=13 or EventID=17 or EventID=18 or EventID=41 or EventID=51 or EventID=55 or EventID=104 or EventID=105 or EventID=202 or EventID=1201 or EventID=4199 or EventID=6008]

[INPUT]
    Name         winevtlog
    Channels     Application
    Interval_Sec 1
    DB           winevtlog.sqlite
    Tag          windows
    Use_ANSI     False  
    Event_Query  Event/System[EventID=33 or EventID=528 or EventID=1000 or EventID=1001 or EventID=1002 or EventID=7031 or EventID=7034 or EventID=10016]

[INPUT]
    Name         winevtlog
    Channels     Security
    Interval_Sec 1
    DB           winevtlog.sqlite
    Tag          windows
    Use_ANSI     False  
    Event_Query  Event/System[EventID=1102 or EventID=4618 or EventID=4625 or EventID=4649 or EventID=4663 or EventID=4698 or EventID=4719 or EventID=4728 or EventID=4732 or EventID=4740 or EventID=4756 or EventID=4794]


[INPUT]
    Name         winevtlog
    Channels     Microsoft-Windows-Windows Defender/Operational,Security
    Interval_Sec 1
    DB           winevtlog.sqlite
    Tag          windows
    Use_ANSI     False
    Event_Query  Event/System[EventID=101 or EventID=104 or EventID=105 or EventID=1116 or EventID=1150 or EventID=1201 or EventID=2001 or EventID=2003 or EventID=202 or EventID=5007 or EventID=5010]

[FILTER]
    Name      modify
    Match     windows
    Remove    ProviderName
    Remove    ProviderGuid
    Remove    Qualifiers
    Remove    Opcode
    Remove    Keywords
    Remove    ActivityID
    Remove    RelatedActivityID
    Remove    StringInserts
    Remove    Task
    Remove    Version
    Remove    Level
    Remove    EventRecordID
    Remove    ProcessID
    Remove    ThreadID
    Remove    Channel
    Remove    UserID
    Add category eventlog

[OUTPUT]
    Name         forward
    Match        *
    Host         (NLBのDNS名を入力)
    Port         24224
```

参考にさせていただいた記事に記載がある通り、Fluent-BitではWindowsイベントログの収集プラグインが2つあるんですが、いろいろ比較して「winlog」ではなく「winevtlog」を採用しています。

###### [INPUT] セクション

[INPUT]セクションを複数にしているんですが、なぜかEvent_Queryフィールドが一定の文字数を超えた際にFluent Bitの起動に失敗してしまう事象があったため、イベントログのChannelごとに分けました。

###### [FILTER] セクション

ログの可読性を重視し、必要な情報のみ出力されるようにしました。
ここは実際にS3にたまっていくログを確認しつつ調整していくのがいいと思います。

###### [OUTPUT] セクション
NameはECSのFluent Bitでログを処理するため、Forwardにしています。
※ForwardはFluentd、Fluent Bit間のみ利用できるプラグイン...だったはずです...多分。。。
向き先は**NLBのDNS**を設定してください。

### NLB

今回、Windowsクライアント端末はAWS環境にVPNで繋がっているためInternalで作成しました。
検証時にInternet-facingでも作成して問題なかったので、環境次第と思います。


### ECS
ここは検証するのにすごい時間がかかりました。
わからないことだらけだったので、ちょくちょくCopilotさんに聞きながら進めていきました。
詳細に記載すると別の記事1本分くらいになるので、後日書こうと思います。

##### ①ECSでカスタムのfluent-bit.confを指定してFluent Bitを起動する必要があるため、いろいろあって最初にEC2上でカスタムのDockerイメージを作成し、ECRにプッシュする。

##### ②Fargate型でECSコンテナーを作成する。この時環境変数はS3にenvファイルを事前に作成し、参照するようにする。(.envファイル内でFirehoseにログが流れるようFirehose名を記載する)

##### ③作成したイメージからECSコンテナを起動するタスク定義を作成する。

##### ④作成したNLBを指定し、ECSサービスを作成、ECS上でFluent Bitを起動する。

ざっくりこのような流れです。
文字で書くとそんなに大変そうではないですが、実際は日々相談しながら徐々に進めていきました。

### Data Firehose

ECS関連のリソースを作成する前に作成する。
（特に変わった設定は入れていないです。）
可能であればS3への配信テストを実施する。

### S3

ECS関連のリソースを作成する前に作成する。
（特に変わった設定は入れていないです。）

# 実際にS3へ吐かれたログ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3494465/79b9bcee-6295-4f6f-8db7-ddff3b451c0e.png)

コマンドで該当のイベントIDを登録しました。
FILTERをかける前はもっと雑多なイベントログが出ていたので[FILTER]セクションもうまく機能しているみたいでした。
ヨカッタヨカッタ。

# さいごに
結構苦労して無事にWindowsのイベントログをクライアント端末からS3に集約することができました。
コンテナに関しては全く触ったことがなかったため、とてもいい学習の機会になりました。
DBやコンテナもこれから頑張ります！