Azure Blob Storage の監視に関するベスト プラクティス

この記事では、一般的なストレージ監視シナリオのコレクションを取り上げ、それらを実現するためのベスト プラクティスのガイドラインを提供します。

使用率がゼロまたは低いストレージ アカウントを特定する

Storage Insights は、Azure Storage のメトリックとログの上にあるダッシュボードです。 Storage Insights を使用すると、すべてのアカウントのトランザクション ボリュームと使用済み容量を調べることができます。 その情報は、廃止するアカウントを決定するのに役立ちます。 Storage Insights を構成するには、「Azure Monitor Storage 分析情報を使用したストレージ サービスの監視」を参照してください。

トランザクション ボリュームを分析する

Azure Monitor の Storage Insights ビューから、 [トランザクション] 列を使用してアカウントを昇順に並べ替えます。 次の画像は、指定した期間にトランザクション ボリュームが少ないアカウントを示しています。

transaction volume in Storage Insights

これらのトランザクションの詳細については、アカウントのリンクをクリックしてください。 この例では、ほとんどの要求が Blob Storage サービスに対して行われています。

transaction by service type

行われている要求の種類を判別するには、API 名別トランザクション グラフの詳細を調べます。

Storage transaction APIs

この例では、要求はすべて、アカウント プロパティ情報に対するリスト操作または要求です。 読み取りおよび書き込みトランザクションはありません。 このことから、このアカウントがあまり使用されていないと想像できます。

使用済み容量を分析する

Azure Monitor の Storage Insights ビュー[容量] タブから、 [アカウントの使用済み容量] 列を使用して、アカウントを昇順に並べ替えます。 次の画像は、他のアカウントよりも容量ボリュームが少ないアカウントを示しています。

Used storage capacity

この使用済み容量に関連する BLOB を調べるには、Storage Explorer を使用します。 BLOB の数が多い場合は、BLOB インベントリ ポリシーを使用してレポートを生成することを検討してください。

コンテナーの使用を監視する

顧客のデータをコンテナーごとにパーティション分割すると、各顧客によって使用されている容量を監視できます。 Azure Storage の BLOB インベントリを使用すると、サイズ情報を含む BLOB のインベントリを取得できます。 次に、コンテナー レベルでサイズと数を集計できます。 例については、「Azure Storage インベントリを使用してコンテナーあたりの BLOB の数と合計サイズを計算する」を参照してください。

また、ログに対してクエリを実行して、コンテナー レベルでトラフィックを評価することもできます。 Log Analytic クエリの記述について詳しくは、Log Analytics に関するページを参照してください。 ストレージ ログ スキーマの詳細については、Azure Blob Storage の監視データのリファレンスに関するページを参照してください。

各コンテナーで読み取られたトランザクションの数と読み取られたバイト数を取得するクエリを次に示します。

StorageBlobLogs
| where OperationName  == "GetBlob"
| extend ContainerName = split(parse_url(Uri).Path, "/")[1]
| summarize ReadSize = sum(ResponseBodySize), ReadCount = count() by tostring(ContainerName)

次のクエリでは、同様のクエリを使用して、書き込み操作に関する情報を取得します。

StorageBlobLogs
| where OperationName == "PutBlob" or
  OperationName == "PutBlock" or
  OperationName == "PutBlockList" or
  OperationName == "AppendBlock" or
  OperationName == "SnapshotBlob" or
  OperationName == "CopyBlob" or
  OperationName == "SetBlobTier"
| extend ContainerName = split(parse_url(Uri).Path, "/")[1]
| summarize WriteSize = sum(RequestBodySize), WriteCount = count() by tostring(ContainerName)

上記のクエリでは、複数の種類の操作を書き込み操作としてカウントできるため、複数の操作の名前が参照されています。 どの操作が読み取りおよび書き込み操作と見なされるかについては、「Azure Blob Storage の価格」または「Azure Data Lake Storage の価格」を参照してください。

アカウントのアクティビティを監査する

多くの場合、セキュリティとコンプライアンスのためにストレージ アカウントのアクティビティを監査する必要があります。 ストレージ アカウントの操作は、"コントロール プレーン" と "データ プレーン" の 2 つのカテゴリに分類されます。

コントロール プレーン操作は、ストレージ アカウントを作成したり既存のストレージ アカウントのプロパティを更新したりする Azure Resource Manager 要求です。 詳細については、Azure Resource Manager に関するページを参照してください。

データ プレーン操作は、ストレージ サービス エンドポイントへの要求の結果として得られたストレージ アカウント内のデータに対する操作です。 たとえば、ストレージ アカウントに BLOB をアップロードしたり、ストレージ アカウントから BLOB をダウンロードしたりするときに、データ プレーン操作が実行されます。 詳細については、Azure Storage API に関するページを参照してください。

このセクションでは、コントロールおよびデータ プレーン操作の "いつ"、"誰が"、"何を"、"どのように" という情報を特定する方法を示します。

コントロール プレーン操作の監査

Resource Manager の操作は、Azure アクティビティ ログに取り込まれます。 アクティビティ ログを表示するには、Azure portal でストレージ アカウントを開き、 [アクティビティ ログ] を選択します。

Activity Log

任意のログ エントリを開いて、アクティビティが記述されている JSON を表示します。 次の JSON では、コントロール プレーン操作の "いつ"、"何を"、"どのように" という情報が示されています。

Activity Log JSON

"誰が" という情報の可用性は、コントロール プレーン操作の実行に使用された認証方法によって決まります。 認可が Microsoft Entra セキュリティ プリンシパルによって実行された場合は、そのセキュリティ プリンシパルのオブジェクト識別子もこの JSON 出力に表示されます (例: "http://schemas.microsoft.com/identity/claims/objectidentifier": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx")。 メール アドレスや名前など、他の ID 関連情報は必ずしも表示されるとは限らないので、セキュリティ プリンシパルを一意に識別するには、オブジェクト識別子が常に最善の方法です。

そのセキュリティ プリンシパルのフレンドリ名を見つけるには、オブジェクト識別子の値を取得し、Azure portal の Microsoft Entra ID ページでセキュリティ プリンシパルを検索します。 次のスクリーンショットは、Microsoft Entra ID での検索結果を示しています。

Search Microsoft Entra ID

データ プレーン操作の監査

データ プレーン操作は、Storage の Azure リソース ログに取り込まれます。 ネイティブ クエリ エクスペリエンスを得るために、ログを Log Analytics ワークスペースにエクスポートするように診断設定を構成できます。

ログ エントリの一覧から "いつ"、"誰が"、"何を"、"どのように" という情報を取得する Log Analytics クエリを次に示します。

StorageBlobLogs
| where TimeGenerated > ago(3d)
| project TimeGenerated, AuthenticationType, RequesterObjectId, OperationName, Uri

監査の "いつ" 部分については、TimeGenerated フィールドに、ログ エントリがいつ記録されたかが表示されます。

監査の "何を" 部分については、Uri フィールドに、項目が変更または読み取られたことが表示されます。

監査の "どのように" 部分については、OperationName フィールドに、実行された操作が表示されます。

ヒント

たとえば、BLOB またはコンテナーが誤って削除された疑いがある場合は、OperationNameDelete blob または Delete Container に設定したログ エントリのみを返す where 句を追加します。 監査の "誰が" 部分については、AuthenticationType に、要求を行うために使用された認証の種類が表示されます。 このフィールドには、アカウント キー、SAS トークン、または Azure Microsoft Entra 認証の使用など、Azure Storage でサポートされているすべての種類の認証を表示できます。

要求の承認に Microsoft Entra ID を使用している場合は、"誰が" の特定に RequestObjectId フィールドを使用できます。 共有キーと SAS 認証では、個々の ID を監査する手段は提供されません。 その場合、操作のソースを特定するのに callerIPAddress フィールドと userAgentHeader フィールドが役立つことがあります。 操作の承認に SAS トークンを使用している場合は、そのトークンを特定できます。また、トークンとトークン受信者とのマッピングをユーザー側で指定している場合は、操作を実行したユーザー、組織、またはアプリケーションを特定できます。 「要求の承認に使用される SAS トークンの特定」を参照してください。

要求の承認に使用されるセキュリティ プリンシパルの特定

要求が Microsoft Entra ID を使用して認証された場合、RequesterObjectId フィールドには、セキュリティ プリンシパルを識別する最も信頼性の高い方法が示されます。 そのセキュリティ プリンシパルのフレンドリ名を見つけるには、RequesterObjectId フィールドの値を取得し、Azure portal の Microsoft Entra ID ページでセキュリティ プリンシパルを検索します。 次のスクリーンショットは、Microsoft Entra ID での検索結果を示しています。

Search Microsoft Entra ID

場合によっては、ユーザー プリンシパル名 (UPN) がログに表示されることがあります。 たとえば、セキュリティ プリンシパルが Microsoft Entra ユーザーの場合は、UPN が表示される可能性が高くなります。 ユーザー割り当てマネージド ID などの他の種類のセキュリティ プリンシパルの場合や、Microsoft Entra テナント間認証などの特定のシナリオでは、UPN はログに表示されません。

このクエリでは、OAuth セキュリティ プリンシパルによって実行されたすべての読み取り操作が表示されます。

StorageBlobLogs
| where TimeGenerated > ago(3d)
  and OperationName == "GetBlob"
  and AuthenticationType == "OAuth"
| project TimeGenerated, AuthenticationType, RequesterObjectId, OperationName, Uri

共有キーと SAS 認証では、個々の ID を監査する手段は提供されません。 したがって、ID に基づく監査能力を向上させたい場合は、Microsoft Entra ID に移行し、共有キーと SAS の認証を禁止することをお勧めします。 共有キーと SAS 認証を禁止する方法については、「Azure Storage アカウントの共有キーによる承認を禁止する」を参照してください。 Microsoft Entra ID の使用を開始するには、「Microsoft Entra ID を使用して BLOB へのアクセスを認可する」を参照してください。

要求の承認に使用される SAS トークンの特定

SAS トークンを使用して承認された操作を照会できます。 たとえば、次のクエリは、SAS トークンを使用して承認されたすべての書き込み操作を返します。

StorageBlobLogs
| where TimeGenerated > ago(3d)
  and OperationName == "PutBlob"
  and AuthenticationType == "SAS"
| project TimeGenerated, AuthenticationType, AuthenticationHash, OperationName, Uri

セキュリティ上の理由から、SAS トークンはログには表示されません。 ただし、SAS トークンの SHA-256 ハッシュは、このクエリによって返される AuthenticationHash フィールドに表示されます。

複数の SAS トークンを分散していて、どの SAS トークンが使用されているかを知る必要がある場合は、各 SAS トークンを SHA-256 ハッシュに変換し、ログに表示されるハッシュ値とそのハッシュを比較する必要があります。

最初に各 SAS トークン文字列をデコードします。 次の例では、PowerShell を使用して SAS トークン文字列をデコードします。

[uri]::UnescapeDataString("<SAS token goes here>")

その後、その文字列を Get-FileHash PowerShell コマンドレットに渡すことができます。 サンプルについては、「例 4: 文字列のハッシュを計算する」を参照してください。

または、デコードされた文字列を Azure Data Explorer を使用するクエリの一部として hash_sha256() 関数に渡すこともできます。

SAS トークンには ID 情報は含まれません。 ユーザーまたは組織のアクティビティを追跡する 1 つの方法は、ユーザーまたは組織のさまざまな SAS トークン ハッシュへのマッ​​ピングを維持することです。

頻度の低いクエリのコストを最適化する

Log Analytics にログをエクスポートすることで、豊富なネイティブ クエリ機能を利用できます。 ストレージ アカウントに大量のトランザクションがある場合、Log Analytics でログを使用するコストが高くなる可能性があります。 詳細については、Azure Log Analytics の価格に関するページを参照してください。 ログに対してたまにしかクエリを実行しない場合 (コンプライアンス監査のためにログに対してクエリを実行するなど)、ログをストレージ アカウントにエクスポートしてから、ログ データに対してサーバーレス クエリ ソリューション (Azure Synapse など) を使用することによって、合計コストの削減を検討することができます。

Azure Synapse を使用すると、サーバーレス SQL プールを作成して、必要に応じてログ データに対してクエリを実行できます。 これによってコストを大幅に削減できる可能性があります。

  1. ログをストレージ アカウントにエクスポートします。 詳細については、「診断設定の作成」を参照してください。

  2. Synapse ワークスペースを作成して構成します。 詳細については、「クイックスタート: Synapse ワークスペースを作成する」を参照してください。

  3. ログに対してクエリを実行します。 詳細については、「Azure Synapse Analytics でサーバーレス SQL プールを使用して JSON ファイルのクエリを実行する」を参照してください。

    次に例を示します。

     select
         JSON_VALUE(doc, '$.time') AS time,
         JSON_VALUE(doc, '$.properties.accountName') AS accountName,
         JSON_VALUE(doc, '$.identity.type') AS identityType,
         JSON_VALUE(doc, '$.identity.requester.objectId') AS requesterObjectId,
         JSON_VALUE(doc, '$.operationName') AS operationName,
         JSON_VALUE(doc, '$.callerIpAddress') AS callerIpAddress,
         JSON_VALUE(doc, '$.uri') AS uri
         doc
     from openrowset(
             bulk 'https://demo2uswest4log.blob.core.windows.net/insights-logs-storageread/resourceId=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/mytestrp/providers/Microsoft.Storage/storageAccounts/demo2uswest/blobServices/default/y=2021/m=03/d=19/h=*/m=*/PT1H.json',
             format = 'csv', fieldterminator ='0x0b', fieldquote = '0x0b'
         ) with (doc nvarchar(max)) as rows
     order by JSON_VALUE(doc, '$.time') desc
    
    

関連項目