Azure Resource GraphでAzure Storageの危険設定を高速監査する実務ガイド

Azure Storage のストレージアカウントが増えるほど、「どれがインターネット側に開いているのか」「SFTP や NFS などの機能がいつの間にか有効化されていないか」を手作業で追うのは難しくなります。結論から言うと、複数サブスクリプションにまたがる設定レビューは、Azure Resource Graph と KQL を使って一括抽出し、リスクの高い構成から順に確認するのが最短です。

2026年4月21日時点の更新として、Microsoft は Azure Storage の構成確認に Azure Resource Graph クエリを活用するガイダンスを公開しました。内容は、microsoft.storage/storageaccounts を対象に、SFTP、HNS、NFS 3.0、最小 TLS バージョン、匿名 Blob アクセス、パブリックネットワーク公開状態などを KQL で確認する実務寄りのものです。PowerShell、Azure CLI、REST API でも調査はできますが、監査証跡を素早く集めたいクラウドガバナンス担当、ストレージ管理者、セキュリティ監査担当にとっては、Resource Graph Explorer で横断的に見る方法が特に有効です。(TECHCOMMUNITY.MICROSOFT.COM)

目次

Azure Resource Graph / Azure Storage の最新動向で重要なポイント

Microsoft のガイダンスで注目すべき点は、Azure Storage の設定確認を「個別アカウントの画面確認」や「スクリプト保守」から、「KQL による横断レビュー」へ寄せていることです。Azure Resource Graph は、Azure リソースを大規模に検索・絞り込み・集計するためのサービスで、複数サブスクリプションを対象にリソースプロパティを問い合わせられます。クエリ言語は Kusto Query Language、いわゆる KQL に基づいています。(Microsoft Learn)

今回の Azure Storage 向けガイダンスでは、Resources テーブルから microsoft.storage/storageaccounts を抽出し、ストレージアカウントの各種プロパティを見る構成になっています。たとえば、properties.publicNetworkAccess、properties.networkAcls.defaultAction、properties.allowBlobPublicAccess、properties.minimumTlsVersion、properties.isSftpEnabled などです。これにより、「危険そうなアカウントを先に洗い出す」「監査用 CSV を作る」「是正後に同じクエリで再確認する」という流れを作りやすくなります。(TECHCOMMUNITY.MICROSOFT.COM)

ただし、Azure Resource Graph は是正ツールではありません。あくまで設定状態を見つけるためのレビュー基盤です。実際の修正は、Azure Portal、Azure Policy、IaC、PowerShell、Azure CLI、変更管理プロセスなどと組み合わせて行います。

最初に見るべきリスクは「公開範囲」と「機能の増えすぎ」

Azure Storage の監査でまず確認すべきなのは、外部から到達しやすい状態になっていないかです。Azure Storage のファイアウォールルールは、ストレージアカウントのパブリックエンドポイントに対するネットワークアクセスを制御します。既定では任意のネットワークからの接続を許可できますが、仮想ネットワーク、IP アドレス範囲、リソースインスタンス、信頼されたサービス例外などのルールで制限できます。(Microsoft Learn)

次に見るべきなのが「feature sprawl」、つまり必要性が不明な機能の増えすぎです。SFTP、NFS 3.0、階層型名前空間、既定アクセス層などは業務上必要な場合もありますが、所有者や用途が曖昧なまま有効になっていると、運用負荷、アクセス経路、コスト、監査説明の複雑さが増えます。

確認観点主なプロパティ要注意の例次のアクション
パブリックネットワーク公開publicNetworkAccess、networkAcls.defaultActionEnabled または未設定かつ Allow所有者確認、ファイアウォール制限、Private Endpoint 化を検討
匿名 Blob 読み取りallowBlobPublicAccesstrue または null匿名要求ログとアプリ影響を確認し、不要なら false
TLS ベースラインminimumTlsVersion組織基準より古い値、未設定クライアント互換性確認後に引き上げ
SFTP / NFS / HNSisSftpEnabled、isNfsV3Enabled、isHnsEnabled用途・所有者が不明業務要件、認証方式、ネットワーク制限を確認
既定アクセス層accessTierHot / Cool の使い分けが不明コストとデータ利用頻度を見直し

特に allowBlobPublicAccess は、パブリックネットワークアクセスとは別の観点です。前者は Blob データへの匿名読み取りを許可するかどうか、後者はストレージアカウントのパブリックエンドポイントへネットワーク的に到達できるかどうかを見ます。Microsoft Learn では、匿名アクセスを禁止するには AllowBlobPublicAccess を False に設定すると説明されています。また、匿名アクセスを止める前には、匿名要求を行っている可能性があるクライアントへの影響を確認する必要があります。(Microsoft Learn)

実務で使いやすい監査ワークフロー

Azure Resource Graph / Azure Storage のレビューは、単発の検索ではなく、監査ワークフローとして設計すると効果が出ます。

フェーズやること成果物
スコープ定義管理グループ、サブスクリプション、対象リージョン、除外条件を決める監査対象一覧
ベースライン抽出すべてのストレージアカウントを KQL で棚卸しする全体インベントリ
リスク抽出公開状態、匿名アクセス、TLS、SFTP/NFS/HNS を条件抽出する優先対応リスト
所有者確認タグ、リソースグループ、CMDB などで業務オーナーを特定する例外・是正判断
証跡化KQL、実行日時、スコープ、結果件数、CSV を保存する監査エビデンス
是正後確認同じ KQL を再実行して差分を確認するクローズ証跡

Azure Resource Graph を使うには、対象リソースに対する少なくとも読み取り権限が必要です。権限がないリソースは結果に返らないため、監査担当者は「結果がゼロだった」だけで安全と判断せず、クエリ実行者の RBAC スコープも記録しておくべきです。(Microsoft Learn)

また、大規模環境では出力制限にも注意が必要です。Azure Resource Graph は既定でクエリ結果の返却件数を制限し、Resource Graph Explorer の CSV エクスポートにも上限があります。全社規模の証跡を作る場合は、サブスクリプション単位や管理グループ単位に分ける、集計クエリと詳細クエリを分ける、といった運用が現実的です。(Microsoft Learn)

Resource Graph Explorer で確認を始める手順

Resource Graph Explorer は Azure Portal から利用できます。最初のレビューでは、以下の流れで十分です。

手順操作
1Azure Portal にサインインする
2検索バーで「Resource Graph Explorer」を検索して開く
3必要に応じて Directory から対象ディレクトリ、管理グループ、サブスクリプションを選ぶ
4KQL クエリを貼り付ける
5Run query を実行し、Results と Messages を確認する
6必要に応じて CSV として保存する

Microsoft のクイックスタートでも、Resource Graph Explorer では Azure Portal 上でクエリ実行、結果確認、スコープ変更、CSV ダウンロード、ダッシュボードへのピン留めができると説明されています。(Microsoft Learn)

まず使うべきベースライン KQL

最初は、リスク判定に必要なプロパティを一括で出すベースラインクエリを作ります。タグ名は組織によって違うため、Owner や Environment は自社のタグキーに合わせて変更してください。

Resources
| where type =~ "microsoft.storage/storageaccounts"
| extend
    skuName = tostring(sku.name),
    publicNetworkAccess = tostring(properties.publicNetworkAccess),
    defaultAction = tostring(properties.networkAcls.defaultAction),
    allowBlobPublicAccess = properties.allowBlobPublicAccess,
    minimumTlsVersion = tostring(properties.minimumTlsVersion),
    isSftpEnabled = tobool(properties.isSftpEnabled),
    isNfsV3Enabled = tobool(properties.isNfsV3Enabled),
    isHnsEnabled = tobool(properties.isHnsEnabled),
    defaultAccessTier = tostring(properties.accessTier),
    owner = tostring(tags["Owner"]),
    environment = tostring(tags["Environment"])
| project
    subscriptionId,
    resourceGroup,
    name,
    location,
    kind,
    skuName,
    publicNetworkAccess,
    defaultAction,
    allowBlobPublicAccess,
    minimumTlsVersion,
    isSftpEnabled,
    isNfsV3Enabled,
    isHnsEnabled,
    defaultAccessTier,
    owner,
    environment
| order by subscriptionId asc, resourceGroup asc, name asc

このクエリは、監査の起点として便利です。いきなり「危険」と決めつけるのではなく、まず全体像を出し、公開状態、匿名アクセス、TLS、追加機能、所有者タグの有無を同じ表で確認します。

パブリックネットワークに広く開いているストレージアカウントを探す

最も優先度が高いのは、パブリックネットワークアクセスが有効または未設定で、ネットワーク ACL の既定アクションが Allow になっているアカウントです。Microsoft のガイダンスでも、この組み合わせを「任意のネットワークからアクセスでき、ファイアウォールやネットワーク制限がない可能性がある構成」として抽出しています。(TECHCOMMUNITY.MICROSOFT.COM)

Resources
| where type =~ "microsoft.storage/storageaccounts"
| where
    (properties.publicNetworkAccess == "Enabled" or isnull(properties.publicNetworkAccess))
    and properties.networkAcls.defaultAction == "Allow"
| project
    subscriptionId,
    resourceGroup,
    name,
    location,
    publicNetworkAccess = tostring(properties.publicNetworkAccess),
    defaultAction = tostring(properties.networkAcls.defaultAction)
| order by subscriptionId asc, resourceGroup asc, name asc

この結果に出たからといって、すべてが即インシデントとは限りません。静的 Web サイト、公開ダウンロード、外部サービス連携など、業務上必要な公開もあります。ただし、監査では「なぜ公開が必要か」「どのデータが置かれているか」「IP 制限や Private Endpoint を使えない理由は何か」を説明できる状態にする必要があります。

匿名 Blob 読み取りが許可されている可能性を確認する

匿名 Blob アクセスは、ストレージアカウント単位の設定とコンテナー単位の設定が関係します。ストレージアカウント側で allowBlobPublicAccess を false にすると、コンテナー側の匿名アクセス設定を上書きして匿名要求を失敗させられます。(Microsoft Learn)

Resources
| where type =~ "microsoft.storage/storageaccounts"
| extend allowBlobPublicAccess = properties.allowBlobPublicAccess
| where allowBlobPublicAccess == true or isnull(allowBlobPublicAccess)
| project
    subscriptionId,
    resourceGroup,
    name,
    location,
    allowBlobPublicAccess
| order by subscriptionId asc, resourceGroup asc, name asc

null は「明示的に false ではない」調査対象として扱うのが安全です。Microsoft Learn のサンプルでも、AllowBlobPublicAccess が True または null のアカウントを一括修復スクリプトの対象として扱っています。(Microsoft Learn)

本番環境で無効化する前には、Log Analytics で匿名要求の有無を確認します。Azure Storage のログでは AuthenticationType == "Anonymous" を条件に、匿名要求を受けている Blob アクセスを確認できます。(Microsoft Learn)

SFTP、NFS 3.0、HNS の feature sprawl を洗い出す

SFTP、NFS 3.0、HNS は、それぞれ正当な用途があります。SFTP は外部連携、NFS 3.0 は Linux クライアントや分析ワークロード、HNS は Azure Data Lake Storage Gen2 の利用で必要になることがあります。問題は、用途不明のまま有効化され続けている状態です。

Resources
| where type =~ "microsoft.storage/storageaccounts"
| extend
    isSftpEnabled = tobool(properties.isSftpEnabled),
    isNfsV3Enabled = tobool(properties.isNfsV3Enabled),
    isHnsEnabled = tobool(properties.isHnsEnabled)
| where isSftpEnabled == true
    or isNfsV3Enabled == true
    or isHnsEnabled == true
| project
    subscriptionId,
    resourceGroup,
    name,
    location,
    isSftpEnabled,
    isNfsV3Enabled,
    isHnsEnabled,
    owner = tostring(tags["Owner"]),
    environment = tostring(tags["Environment"])
| order by subscriptionId asc, resourceGroup asc, name asc

ここでの判断基準は「有効だから危険」ではなく、「用途、所有者、アクセス制御、ログ監視、変更承認が説明できるか」です。特に監査では、機能を有効化した理由よりも、不要になった機能を止めるプロセスがあるかを見られます。

最小 TLS バージョンを確認する

TLS の確認は、セキュリティ基準への適合だけでなく、古いクライアントが残っていないかを把握する目的でも重要です。Azure Storage の minimumTlsVersion は、ストレージへの要求で許可される最小 TLS バージョンを表します。Microsoft の REST API リファレンスでは、このプロパティが未設定の場合の解釈にも注意が必要であることが示されています。(Microsoft Learn)

Resources
| where type =~ "microsoft.storage/storageaccounts"
| extend minimumTlsVersion = tostring(properties.minimumTlsVersion)
| where isempty(minimumTlsVersion)
    or minimumTlsVersion in ("TLS1_0", "TLS1_1")
| project
    subscriptionId,
    resourceGroup,
    name,
    location,
    minimumTlsVersion,
    owner = tostring(tags["Owner"]),
    environment = tostring(tags["Environment"])
| order by subscriptionId asc, resourceGroup asc, name asc

TLS 設定を引き上げる場合は、いきなり全環境で変更せず、接続元アプリケーション、バッチ、古い SDK、外部連携先を確認します。監査対応としては、「対象アカウント」「現在値」「変更予定日」「影響確認の担当者」を残すと、後続レビューが楽になります。

監査向けの集計クエリを作る

詳細リストだけでは、経営層や監査担当への報告に使いにくい場合があります。その場合は、サブスクリプション単位で件数を集計します。

let StorageAccounts =
Resources
| where type =~ "microsoft.storage/storageaccounts"
| extend
    publicNetworkAccess = tostring(properties.publicNetworkAccess),
    defaultAction = tostring(properties.networkAcls.defaultAction),
    allowBlobPublicAccess = properties.allowBlobPublicAccess,
    minimumTlsVersion = tostring(properties.minimumTlsVersion),
    isSftpEnabled = tobool(properties.isSftpEnabled),
    isNfsV3Enabled = tobool(properties.isNfsV3Enabled),
    isHnsEnabled = tobool(properties.isHnsEnabled);
StorageAccounts
| summarize
    totalStorageAccounts = count(),
    publicOpen = countif((publicNetworkAccess == "Enabled" or isempty(publicNetworkAccess)) and defaultAction == "Allow"),
    blobPublicCandidate = countif(allowBlobPublicAccess == true or isnull(allowBlobPublicAccess)),
    weakOrUnsetTls = countif(isempty(minimumTlsVersion) or minimumTlsVersion in ("TLS1_0", "TLS1_1")),
    sftpEnabled = countif(isSftpEnabled == true),
    nfsV3Enabled = countif(isNfsV3Enabled == true),
    hnsEnabled = countif(isHnsEnabled == true)
  by subscriptionId
| order by publicOpen desc, blobPublicCandidate desc

この集計は、優先順位付けに向いています。たとえば publicOpen が多いサブスクリプションから先に担当者へ確認し、次に匿名 Blob アクセス候補、TLS、不要機能の順で深掘りします。

失敗しやすいポイント

publicNetworkAccess と allowBlobPublicAccess を混同する

publicNetworkAccess はネットワーク到達性、allowBlobPublicAccess は Blob の匿名読み取り許可です。片方だけ見ても公開リスクは判断できません。監査では両方を並べて確認し、必要ならコンテナー設定やログまで見る必要があります。

「KQL の結果に出ないから安全」と判断する

Azure Resource Graph は、実行者が読み取り権限を持つリソースを対象に結果を返します。権限不足やスコープ漏れがあると、危険なリソースが存在してもクエリ結果に出ません。監査証跡には、実行者、対象スコープ、実行日時を必ず残してください。(Microsoft Learn)

すべてを一度に直そうとする

パブリック公開や匿名アクセスを一括で止めると、外部連携、静的 Web 配信、データ共有、レガシーアプリが停止する可能性があります。まず読み取り専用で棚卸しし、所有者確認、ログ確認、例外承認、段階的な変更の順に進めるのが現実的です。

エビデンスがスクリーンショットだけになる

監査で本当に役立つのは、スクリーンショットよりも再実行可能な証跡です。保存すべきものは、KQL、対象スコープ、実行日時、結果 CSV、リスク分類、担当者、是正状況です。同じクエリで是正前後を比較できる状態にしておくと、内部監査や外部監査の説明が短くなります。

Azure Policy や Defender とどう使い分けるか

Azure Resource Graph は「いま何が存在するか」を高速に見つけるのに向いています。一方で、望ましくない構成を作らせない、または継続的に準拠状態を評価するには、Azure Policy などの仕組みが必要です。

ツール向いている用途
Azure Resource Graph棚卸し、横断検索、監査証跡、是正前後の確認
Azure Policy構成ルールの評価、非準拠検出、作成時の制御
Azure Monitor / Log Analytics実アクセス、匿名要求、運用ログの分析
IaC / CI/CD修正内容の標準化、再発防止、変更履歴の管理

実務では、Resource Graph で現状を洗い出し、Azure Policy で継続的な準拠を担保し、Log Analytics で実アクセスを確認し、IaC で設定を標準化する流れが扱いやすいです。

次に取るべき行動

まずは Resource Graph Explorer でベースラインクエリを実行し、すべての Azure Storage アカウントを一覧化してください。次に、パブリックネットワーク公開、匿名 Blob アクセス候補、TLS、SFTP / NFS / HNS の順で抽出します。

最初のゴールは、すべてを即修正することではありません。どのストレージアカウントが、どのサブスクリプションにあり、どの設定で、誰が所有していて、どれを優先的に確認すべきかを明確にすることです。Azure Resource Graph / Azure Storage の KQL レビューを定期実行できる形にしておけば、監査対応は「都度調査」から「証跡を更新するだけ」の運用に近づきます。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次