Windows テキストログを Azure Monitor Agent を用いて、カスタムログとして Microsoft Sentinel (LogAnalytics) に基本ログで取り込む！

# 1. はじめに
Microsoft Sentinel / Log Analytics ワークスペースを運用していく中で、ミドルウェアやアプリケーションのログを取り込んで分析・解析に用いたいといった要望が出てきます。Microsoft Sentinel では[データコネクタ](https://learn.microsoft.com/ja-jp/azure/sentinel/connect-data-sources)と呼ばれるモジュールで簡単に接続する仕組みが提供されているのですが、データコネクタに対応していない製品についてはカスタムログとして取り込む方法を考える必要があります。
本記事では、比較的ニーズが多い Windows サーバーのアプリケーションログとして[デジタルアーツ社 i-FILTER](https://www.daj.jp/bs/i-filter/) のアクセスログを用いて、以下を実施してみました。

- i-FILTER サーバーのアクセスログを Microsoft Sentinel (Log Analytics ワークスペース) に取り込む
- 取り込む際に、i-FILTER アクセスログから正規化を行い、必要なフィールドを抽出する
    - 送信元IP、ターゲットIP、URL、HTTP Method、iFITLERの挙動（Accept/Blockなど）
- (オプション) [Log Analytics 基本ログ](https://learn.microsoft.com/ja-jp/azure/sentinel/basic-logs-use-cases)を用いて、取り込み時のコスト削減を行う
    - Microsoft Sentinel のスケジュール分析ルールでインシデント検知を用いる場合は分析ログで行う
    - 基本ログでは、インシデント発生時の二次的な解析や、コンプライアンス要件、「何かあった場合に検索する」際のデータ保管に用いる

キーワードとして、「**カスタムログ**の取り込み」「**基本ログ**の活用」といったテーマとなります。

# 2. やりたいこと
改めて、今回やりたいこと (Before/After) は以下になります。
- Before : Windows のテキストログ（アプリケーションログなど）
- After : Microsoft Sentinel / LogAnalytics に正規化して取り込み、KQLで解析出来るようにする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/26f34452-7ade-4ddc-37f2-6d659a730aa2.png)

# 3. 実装のイメージ図
今回の実装は Azure Monitor Agent (AMA) を用いて、データ収集ルール (DCR) を用いてデータ収集エンドポイント (DCE) を経由することで、カスタムログとして取り込む方法になります。
以下イメージ図を参考としてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/d4bd9b12-b217-b023-5320-cbe4f8bbc403.png)

- AMA (Azure Monitor エージェント)
    - Windows サーバーのテキストファイルをモニターし、増分( Line 行)を Log Analytics ワークスペースに送信します。
- DCR (データ収集ルール)
    - 対象元 (AMA) から対象先 (DCE) をマッピングし、転送時にデータ変換機能を用いて必要となるデータを抽出します（不必要なフィールドの削除も OK ）
- DCE (データ収集エンドポイント)
    - DCR によって転送されたデータを処理して、Log Analytics ワークスペースに転送します。

# 4. やってみる
実際の設定の流れを以下まとめておきます。
## 4.1 データ収集エンドポイント (DCE) の作成
- カスタムログの場合、データ収集エンドポイントを経由して転送する必要があるため、事前に DCE を作成します。
- リソースグループは DCR など他のリソースと合わせてまとめて作っておくと分かりやすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/712bf8e1-d8eb-fb60-3438-651371f0d6cb.png)

https://learn.microsoft.com/ja-jp/azure/azure-monitor/essentials/data-collection-endpoint-overview?tabs=portal#create-a-data-collection-endpoint

## 4.2 カスタムテーブルの作成
対象の Log Analytics ワークスペースに取りこむ専用のテーブルを作成します。
本記事では、i-FILTER のアクセスログなので、``iFILTER_CL`` といったカスタムテーブルを作成しています。Powershell スクリプトは[公式 Docs に記載された方法](https://learn.microsoft.com/ja-jp/azure/azure-monitor/agents/data-collection-text-log?tabs=portal#create-a-custom-table)を用いています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/45221e77-babf-bd45-19de-d666cfe5b541.png)

```powershell
$tableParams = @'
{
   "properties": {
       "schema": {
              "name": "iFILTER_CL",
              "columns": [
       {
                               "name": "TimeGenerated",
                               "type": "DateTime"
                       }, 
                      {
                               "name": "RawData",
                               "type": "String"
                      }
             ]
       }
   }                                                   
}
'@

Invoke-AzRestMethod -Path "/subscriptions/(サブスクリプションID)/resourcegroups/(リソースグループ)/providers/microsoft.operationalinsights/workspaces/(Log Analytics ワークスペース名)/tables/iFILTER_CL?api-version=2021-12-01-preview" -Method PUT -payload $tableParam
```

設定後、テーブルが作成されたことを確認します。

## 4.3 一旦 データ収集ルールを作成する
一度、データ収集ルールを作成して、作成したテーブル (RawData) で取り込まれるかどうか確認します。Windows テキストログ形式では、Azure Monitor Agent (AMA) が導入された Windows サーバーと、対象のフォルダ/ファイルを指定する設定項目があるため、i-FILTER のアクセスログが出力されるファイル ``C:\Program Files\Digital Arts\i-FILTER Proxy Server Ver.10\logs\access.log0000`` を指定しています。
Digital Arts 社 i-FILTER のログフォーマットについては、標準がスペース区切りの CSV フォーマットになっています。

https://www.pa-solution.net/daj/bs/faq/detail.aspx?id=3676&isCrawler=1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/e05a388f-d739-42f5-3d19-d0a7eccf2a73.png)
>なお、ここでログフォーマットが分かっている場合は Transform の欄に専用の KQL を書くことで ETL 変換をかけることが出来ますが、この段階ではどのような KQL を書けば良いのか分からないケースがほとんどなので、後ほど設定します。

## 4.4 Log Analytics に取り込まれた生データから、抽出するフィールド情報を検討する
4.3 まで実行することで、生データ ``RawData`` が Log Analytics ワークスペースに取り込まれることが確認出来ます。このままでも良いのですが、KQL で分析し易いように正規化を行い、必要なデータのみをフィールド情報として抽出するようにします。

ここまでの設定の状態で取り込まれると ``RawData``に対象元の Text ファイルの増分が見える形になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/cd5d3bd5-0d68-1da4-2c04-5cddb0b4deb6.png)

これでは使いにくいので、KQL を駆使してテーブル用のフィールド抽出を行います！
Azure KQL の CSV の抽出方法は様々な方法があるのですが、スペース区切りの抽出方法として以下の [split 関数](https://learn.microsoft.com/ja-jp/azure/data-explorer/kusto/query/splitfunction)を用いて抽出する方法が提供されています。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/parse-text#parse-delimited-data-in-a-query

KQL で i-FILTER の標準アクセスログ CSV を抽出する例です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/6ef844b6-e06f-fc20-c3b1-4ecd9c907165.png)

例えば、宛先IP/ポート、HTTP ステータスコード、iFILTER のアクションだけ抽出するのであれば、以下のような KQL を書けば良いことになります。
```
iFILTER_CL
| extend CSVFields_CF  = split(RawData, ' ') 
| extend TargetIPPort_CF = tostring(CSVFields_CF[6]) 
| extend Status_CF       = tostring(CSVFields_CF[13])  
| extend Action_CF        = tostring(CSVFields_CF[16])
| project TimeGenerated, TargetIPPort_CF, Status_CF, Action_CF
```
>補足
コンマ区切りの CSV フォーマットの場合は、[parse_csv 関数](https://learn.microsoft.com/ja-jp/azure/data-explorer/kusto/query/parsecsvfunction)を用いる方法もあります。

## 4.5 拡張するフィールド値を追加する
抽出する CSV のカラム情報が決まったら、Azure Monitor のページより、テーブルに拡張するフィールドを追加します。カスタムログとしてフィールドを追加するお作法として、``xxxx_CF`` といった **_CF** が付与されるフィールド名で作成する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/90484add-f1b3-d7b4-1b69-593e24414f48.png)

## 4.6 (オプション) 基本ログに切り替える！
AMA を用いた DCE 経由のカスタムログは、基本ログに切り替えることが出来ます。
分析ルール等を用いず、保管用や検索用途に用いる場合は、テーブルを基本ログに切り替えましょう。
Log Analytis ワークスペースの「テーブルプラン」より「**基本**」のプランに設定変更を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/42938275-1418-39dc-f867-858cf3666d86.png)

## 4.7 DCR に戻り、Transform 変換を設定する
4.4 のフェーズで成型・抽出する KQL が決まりましたら、DCR に戻って **Transform** の部分に KQL を埋め込みます。元々あったテーブル名ではなく、Transform で流入する専用のテーブル名 ``source`` に変更する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/a8004c11-65a6-704e-9543-2ae8a1ceaa25.png)

```
source
| extend CSVFields_CF  = split(RawData, ' ') 
| extend TargetIPPort_CF = tostring(CSVFields_CF[6]) 
| extend Status_CF       = tostring(CSVFields_CF[13])  
| extend Action_CF        = tostring(CSVFields_CF[16])
| project TimeGenerated, TargetIPPort_CF, Status_CF, Action_CF
```

## 4.8 テストを行う
DCR に Transform 欄に変換・抽出する KQL を追加して保存し、サンプルログなどを流して正規化されたフィールド抽出が行われるかを確認します。過去の取り込まれたデータは対象にならず、設定後の取り込まれたデータが対象になるため、テストログなどを生成して確認しましょう。
設定が正しく反映されていれば正規化されたフィールドに反映されるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/1ee35ced-9834-1d62-8c6b-2ade521e7826.png)

# 5. (オプション) 基本ログを用いる場合の注意点
カスタムログを基本ログを用いて取り込むことにより、コスト削減が見込まれますが、基本ログは制限事項があります。

>基本ログに対するログ クエリは、次の演算子を含む KQL 言語のサブセットを使用した単純なデータ取得用に最適化されています。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/basic-logs-query?tabs=portal-1#kql-language-limits

|機能 |  分析ログ  |  基本ログ  |
| ---- | ---- | ---- |
| Sentinel でスケジュール分析ルールに用いる | 対応 | 不可 |
| 集計 (Summarize) 関数を用いて統計を作る / グラフ化する | 対応 | 不可 |
| 保存期間 | 任意 (最大2年、以後はアーカイブ層) | 固定 (8日間のみ、以後はアーカイブ層)|
| 対象のテーブル | すべて | [指定テーブルのみ](https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/basic-logs-configure?tabs=portal-1#supported-tables)|

実際に試して気づいたのですが、**summarize** 集計が基本ログでは対応していないため、統計やグラフ化が出来ません。データ量が多くなると統計分析のために集計することが多いと思いますが、基本ログの制約にひっかかるため、このような用途では分析ログを利用して下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/614cd7ed-c6c4-8dcd-01aa-c38f9b9dc401.png)


https://learn.microsoft.com/ja-jp/azure/azure-monitor/logs/basic-logs-configure?tabs=portal-1#compare-the-basic-and-analytics-log-data-plans

# 6. まとめ
本記事では Windows アプリケーションログ（テキストログ）を Microsoft Sentinel に取り込み、基本ログや正規化を行う具体的な方法をご紹介いたしました。Microsoft の公式ドキュメントでは分かり難い部分ですが、一度設定を試していただくと比較的簡単にカスタムログを取り込み、分析に必要なフィールドを自由に抽出することが出来ることがお分かりになるのではと思います。
ドキュメントだけでは分かり難い部分も多いので、ご興味ある方は本記事を参考に試していただければ幸いです。

※本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。正式な情報は、各製品の販売元にご確認ください


# 参考リンクなど
> 本記事の内容に相当する公式ドキュメントは以下をご参照下さい。

https://learn.microsoft.com/ja-jp/azure/azure-monitor/agents/data-collection-text-log?tabs=portal

https://learn.microsoft.com/ja-jp/azure/azure-monitor/agents/azure-monitor-agent-transformation