🔌

コードレス コネクタ (CCF) で BLOB ストレージのログを Sentinel に取り込む

に公開

はじめに

Sentinel には Functions や Logic apps を使用せず、カスタムのコネクタを作成できる コードレス コネクタ フレームワーク (CCF) が提供されています。こちらを利用することでコードを書くことなく、API などからログを取得し、Log Ingest API を通じて Sentinel にログを取り込むことが可能になります。

こちらについてドキュメントは更新されていないのですが、ニーズが多い BLOB ストレージから JSON ファイルを取得し、Sentinel に連携することが可能となりましたので、検証していこうと思います。

なお、Azure VM を使用して BLOB ストレージから Log Analytics ワークスペースに連携する方式は以下で解説しています。
https://zenn.dev/microsoft/articles/85d9e98bdd4a8f

参考

https://learn.microsoft.com/ja-jp/azure/sentinel/create-codeless-connector

仕様の確認

コードレス コネクタは基本的に ARM テンプレートで作成していきます。まずデプロイするコネクタは以下の機能を有しています。

  • リアルタイムログ取り込み: Event Grid を使用したブロブ作成イベントの監視
  • カスタマイズ可能なデータコネクタ: Codeless Connector Framework(CCF)ベース
  • 自動インフラストラクチャ構築: 必要なストレージキュー、イベントサブスクリプション、RBAC の自動設定
  • データ変換: Data Collection Rules(DCR)を使用したログデータの変換・ルーティング
  • エラーハンドリング: Dead Letter Queue(DLQ)を使用した失敗したメッセージの処理

全体の処理の流れは以下のイメージです。

  1. BLOB ストレージにログが保管される
  2. Event Grid にログ格納が記録される
  3. Storage Queue にイベントが保存される
  4. Sentinel Data Connector でキューからイベントを取得し、BLOB ファイルを取得する
  5. Log Ingestion API から Log Analytics ワークスペースに記録する

前提条件

Azure リソース

  • Microsoft Sentinel が有効化された Log Analytics ワークスペース
  • ログファイルを保存する ストレージ アカウントとコンテナ

権限

  • Log Analytics ワークスペース: 共同作成者以上
  • ストレージアカウント: 所有者もしくはユーザーアクセス管理者 + 作成者

ARM テンプレートのデプロイ

ARM テンプレートはこちらです。
https://github.com/katsato-ms/Microsoft/blob/main/Sentinel/CCP/LogsFromBlob/mainTemplate-CCP-LogsFromBlob.json

デプロイされるリソース

ARM テンプレートでデプロイされるリソースは以下です。

  • データコネクタ定義: Microsoft Sentinel のカスタムデータコネクタ
  • データ収集ルール(DCR): ログデータの変換とルーティング
  • Log Analytics テーブル: LogsFromBlob_CL カスタムテーブル
  • Event Grid システムトピック: BLOB 作成イベントの監視
  • ストレージキュー: 通知キューと DLQ
  • RBAC ロール付与: 必要な権限の付与

必須パラメータ

パラメータ名 説明
workspace string Microsoft Sentinel が設定されている Log Analytics ワークスペース名
workspace-location string ワークスペースのリージョン
resourceGroupName string Microsoft Sentinel が設定されているリソースグループ名
subscription string Microsoft Sentinel が設定されているサブスクリプション ID

設定手順

データコネクタの設定

  1. Microsoft Sentinel ポータルにアクセス
  2. データコネクタ > Logs From Blob Storage (CCP) を選択
  3. 必要な情報を入力:
    • Service Principal ID: データ収集用のサービスプリンシパル ID (Grant tenant-wide admin consent ボタンで同意することで選択可能)
    • Blob Container URI: ログファイルが保存されているコンテナの URI
    • Storage Account Resource Group: ストレージアカウントのリソースグループ名
    • Storage Account Location: ストレージアカウントのリージョン
    • Storage Account Subscription: ストレージアカウントのサブスクリプション ID
    • Event Grid Topic Name: ストレージ アカウントの既存の Event Grid トピック名(オプション)
  4. 接続 をクリック


ログの確認

データコネクタが正常に動作している場合、以下のクエリでログを確認できます。

LogsFromBlob_CL
| take 10
| project TimeGenerated, properties

ログスキーマ

作成されるカスタムテーブル LogsFromBlob_CL のスキーマ (各種診断ログをストレージ アカウントに保存した場合のフォーマットを想定):

列名 説明
TimeGenerated datetime ログの生成時刻
properties string ログのプロパティ(JSON 形式)
sample format
{ "time": "2025-10-21T10:35:48.7796440Z", "resourceId": "/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/providers/Microsoft.aadiam", "operationName": "Validate user authentication", "operationVersion": "1.0", "category": "AuditLogs", "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "resultSignature": "None", "resultDescription": "Token is valid", "durationMs": 0, "callerIpAddress": "xx.xx.xx.xx", "correlationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "identity": "xxxx", "Level": 4, "properties": {"tenantId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","resultType":"","resultDescription":"Token is valid","operationName":"Validate user authentication","identity":"xxxx","tenantGeo":"NA","id":"xxxx","category":"Authentication","correlationId":"f8aea473-cc18-4f57-85b8-7ee35e754e09","result":"success","resultReason":"Token is valid","activityDisplayName":"Validate user authentication","activityDateTime":"2025-10-21T10:35:48.779644+00:00","loggedByService":"B2C","operationType":"Read","userAgent":null,"initiatedBy":{"app":{"appId":"xxxx","displayName":"xxxx","servicePrincipalId":null,"servicePrincipalName":"xxxx"}},"performedBy":null,"targetResources":[{"id":null,"displayName":"00000000-0000-0000-0000-000000000000","type":"Other","modifiedProperties":[],"administrativeUnits":[]}],"additionalDetails":[{"key":"targetTenant","value":"00000000-0000-0000-0000-000000000000"},{"key":"targetEntityType","value":"None"},{"key":"actorIdentityType","value":"ApplicationID"},{"key":"RequestId","value":"xxxx"}]}}
{ "time": "2025-10-21T10:35:48.7796440Z", "resourceId": "/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/providers/Microsoft.aadiam", "operationName": "Validate user authentication", "operationVersion": "1.0", "category": "AuditLogs", "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "resultSignature": "None", "resultDescription": "Token is valid", "durationMs": 0, "callerIpAddress": "xx.xx.xx.xx", "correlationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "identity": "xxxx", "Level": 4, "properties": {"tenantId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","resultType":"","resultDescription":"Token is valid","operationName":"Validate user authentication","identity":"xxxx","tenantGeo":"NA","id":"xxxx","category":"Authentication","correlationId":"f8aea473-cc18-4f57-85b8-7ee35e754e09","result":"success","resultReason":"Token is valid","activityDisplayName":"Validate user authentication","activityDateTime":"2025-10-21T10:35:48.779644+00:00","loggedByService":"B2C","operationType":"Read","userAgent":null,"initiatedBy":{"app":{"appId":"xxxx","displayName":"xxxx","servicePrincipalId":null,"servicePrincipalName":"xxxx"}},"performedBy":null,"targetResources":[{"id":null,"displayName":"00000000-0000-0000-0000-000000000000","type":"Other","modifiedProperties":[],"administrativeUnits":[]}],"additionalDetails":[{"key":"targetTenant","value":"00000000-0000-0000-0000-000000000000"},{"key":"targetEntityType","value":"None"},{"key":"actorIdentityType","value":"ApplicationID"},{"key":"RequestId","value":"xxxx"}]}}
{ "time": "2025-10-21T10:35:48.7796440Z", "resourceId": "/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/providers/Microsoft.aadiam", "operationName": "Validate user authentication", "operationVersion": "1.0", "category": "AuditLogs", "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "resultSignature": "None", "resultDescription": "Token is valid", "durationMs": 0, "callerIpAddress": "xx.xx.xx.xx", "correlationId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "identity": "xxxx", "Level": 4, "properties": {"tenantId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","resultType":"","resultDescription":"Token is valid","operationName":"Validate user authentication","identity":"xxxx","tenantGeo":"NA","id":"xxxx","category":"Authentication","correlationId":"f8aea473-cc18-4f57-85b8-7ee35e754e09","result":"success","resultReason":"Token is valid","activityDisplayName":"Validate user authentication","activityDateTime":"2025-10-21T10:35:48.779644+00:00","loggedByService":"B2C","operationType":"Read","userAgent":null,"initiatedBy":{"app":{"appId":"xxxx","displayName":"xxxx","servicePrincipalId":null,"servicePrincipalName":"xxxx"}},"performedBy":null,"targetResources":[{"id":null,"displayName":"00000000-0000-0000-0000-000000000000","type":"Other","modifiedProperties":[],"administrativeUnits":[]}],"additionalDetails":[{"key":"targetTenant","value":"00000000-0000-0000-0000-000000000000"},{"key":"targetEntityType","value":"None"},{"key":"actorIdentityType","value":"ApplicationID"},{"key":"RequestId","value":"xxxx"}]}}

補足

  • テーブルに個別にカラムを追加したうえで、変換ルールを使用し、適切な形式に変換することも可能です。
  • 診断ログを取得する場合、随時追記されるログは取得できないため、ログがすべて追記された状態の BLOB ファイルを azcopy 等で別のコンテナに移動させ、そのコンテナからログ取得する必要があります。

GitHub リンク

https://github.com/katsato-ms/Microsoft/tree/main/Sentinel/CCP/LogsFromBlob

Microsoft (有志)

Discussion