🛡️

Defender for Cloud のカスタム推奨事項・標準作成~割り当てまでを API/CLI で設定

2025/01/30に公開

はじめに

Defender for Cloud で複数のスコープに対してカスタムの推奨事項や標準を作成する場合、Azure ポータルだと時間がかかります。特に管理アカウントで束ねられていない AWS アカウントや管理グループでまとめられない Lighthouse で委任されたサブスクリプションなどに適用するケースです。
上記に対処するため、API 経由で設定するためのスクリプトを整理しました。

作成の前に

カスタム標準とカスタム推奨事項の作成にはそれぞれスコープを定義する必要があり、そのスコープ内でのみ利用可能です。Azure であれば管理グループが選択でき複数のサブスクリプションにまとめて作成・適用できるのですが、AWS と GCP の場合はスコープがコネクタになります。そのため 2025 年 1 月時点ではカスタム推奨事項・標準を 1 つ作成して複数のコネクタに適用するという運用ができず、コネクタごとに同じカスタム推奨事項・標準を作成する必要があります。

カスタム推奨事項の作成

まずカスタム推奨事項を作成していきます。複数作成する必要がある場合は繰り返してください。AWS 前提で書いていますが、一部コメントアウトしている Azure 用のサブスクリプション指定でも動きます。Azure の場合は $payload を Azure の内容に書き直してください。
使用する API はこちらです。
https://learn.microsoft.com/en-us/rest/api/defenderforcloud/custom-recommendations/create-or-update?view=rest-defenderforcloud-2024-08-01&tabs=HTTP

# Azure PowerShell に接続
$subscriptionId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Connect-AzAccount -SubscriptionId $subscriptionId

# Scope の指定
# $scope = "subscriptions/$subscriptionId"  # Azure の場合
$scope = "subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourcegroups/myrg/providers/microsoft.security/securityconnectors/awsconnector" # AWS の場合はコネクタのリソース ID をベースに指定 (初めの / を削除)

# パラメーターを指定
$customRecommendationName = New-Guid
# $customRecommendationName = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 更新の場合は後述する確認方法で取得した既存の GUID を指定

# path を指定
$path = "/$scope/providers/Microsoft.Security/customRecommendations/$($customRecommendationName)?api-version=2024-08-01"

# REST API の body を作成
# "cloudProviders" ではなく、"supportedClouds" を指定する
$payload = @{
    "properties" = @{
        "query" = "let PublicSnapshots = RawEntityMetadata | where Environment == 'AWS' and Identifiers.Type == 'ec2.createvolumepermission' | where Record.Group.Value == 'all' | extend SnapshotId = tostring(Record.SnapshotId) | project SnapshotId, IsPublic = true; RawEntityMetadata | where Environment == 'AWS' and Identifiers.Type == 'ec2.snapshot' | extend SnapshotId = tostring(Record.SnapshotId) | join kind=leftouter PublicSnapshots on SnapshotId | project-away SnapshotId1 | extend HealthStatus = iff(IsPublic, 'UNHEALTHY', 'HEALTHY')"
        "supportedClouds" = @(
            "AWS"
        )
        "severity" = "Medium"
        "displayName" = "Amazon EBS snapshots should not be publicly restorable"
        "description" = "Amazon EBS snapshots should not be publicly restorable"
        "remediationDescription" = "Amazon EBS snapshots should not be publicly restorable"
        "securityIssue" = "Vulnerability"
    }
} | ConvertTo-Json

# REST API を実行
$response = Invoke-AzRestMethod -Path $path -Method Put -Payload $payload

# 実行結果の確認
$response

# 後続で使用するカスタム推奨事項の GUID と assessmentKey を取得
$customRecommendationName = ($response.Content | ConvertFrom-Json).name
$assessmentKey = ($response.Content | ConvertFrom-Json).properties.assessmentKey

カスタム推奨事項の確認

作成後や更新時、assessmentKey を取得したい場合などにカスタム推奨事項を確認する方法です。それぞれ一覧から名前でピックアップする場合と GUID が分かっている場合の方法です。

# カスタム推奨事項一覧の取得し、目的のカスタム推奨事項をピックアップ
$path = "/$scope/providers/Microsoft.Security/customRecommendations?api-version=2024-08-01"
$response = Invoke-AzRestMethod -Path $path -Method Get
$customRecommendation = ($response.Content | ConvertFrom-Json).value | Where-Object { $_.properties.displayName -eq "Amazon EBS snapshots should not be publicly restorable" } 
$customRecommendationName = $customRecommendation.name
$assessmentKey = $customRecommendation.properties.assessmentKey

# GUID が分かる場合は個別にカスタム推奨事項の取得し、assessmentKey を取得
$customRecommendationName = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$path = "/$scope/providers/Microsoft.Security/customRecommendations/$($customRecommendationName)?api-version=2024-08-01"
$response = Invoke-AzRestMethod -Path $path -Method Get
$assessmentKey = ($response.Content | ConvertFrom-Json).properties.assessmentKey

カスタム標準の作成

次に先ほど作成したカスタム推奨事項を含めた形でカスタム標準を作成します。今回は 1 つのみ含めていますが、$payloadassessments の箇所で複数指定することが可能です。こちらも AWS 前提で書いていますが、Azure でも動きます。
使用する API はこちらです。
https://learn.microsoft.com/en-us/rest/api/defenderforcloud/security-standards/create-or-update?view=rest-defenderforcloud-2024-08-01&tabs=HTTP

# パラメーターを指定
$standerdId = New-Guid
# $standerdId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 更新の場合は既存の GUID を指定

# path を指定
$path = "/$scope/providers/Microsoft.Security/securityStandards/$($standerdId)?api-version=2024-08-01"

# REST API の body を作成
# AWS・GCP の場合は Azure Policy に依存しないため "policySetDefinitionId" は指定しない
$payload = @{
    "properties" = @{
        "displayName" = "AWS Test Security Standard 1"
        "description" = "description of AWS Test Security Standard 1"
        "assessments" = @(
            @{
                "assessmentKey" = $assessmentKey
            }
        )
        "cloudProviders" = @(
            "AWS"
        )
    }
} | ConvertTo-Json -depth 8

# REST API を実行
$response = Invoke-AzRestMethod -Path $path -Method Put -Payload $payload

# 実行結果の確認
$response

# 後で使用する Id と Name (GUID) を取得
$customStandardId = ($response.Content | ConvertFrom-Json).id
$customStandardName = ($response.Content | ConvertFrom-Json).name

カスタム標準の確認

作成後や更新時にカスタム標準を確認する方法です。それぞれ一覧から名前でピックアップする場合と GUID が分かっている場合の方法です。

# カスタム標準一覧の取得し、名前から該当のカスタム標準をピックアップ
$path = "/$scope/providers/Microsoft.Security/securityStandards?api-version=2024-08-01"
$response = Invoke-AzRestMethod -Path $path -Method Get
$customStandard = ($response.Content | ConvertFrom-Json).value | Where-Object { $_.properties.displayName -eq "AWS Test Security Standard 2" }

# 割り当てに必要な Id を取得
$customStandardId = $customStandard.id
$customStandardName = $customStandard.Name

# GUID が分かる場合は個別にカスタム標準を取得
$customStandardName = "3bdd23b7-cb91-409f-be7c-dc55a34d34e0"
$path = "/$scope/providers/Microsoft.Security/securityStandards/$($customStandardName)?api-version=2024-08-01"
$response = Invoke-AzRestMethod -Path $path -Method Get

# 割り当てに必要な Id を取得
$customStandardId = ($response.Content | ConvertFrom-Json).id

カスタム標準の割り当て

最後に作成したカスタム標準を割り当てていきます。こちらも AWS 前提で書いていますが、Azure でも動きます。

# パラメーターを指定
$standardAssignmentName = New-Guid
# $standardAssignmentName = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # 更新の場合は既存の GUID を指定

# path を指定
$path = "/$scope/providers/Microsoft.Security/standardAssignments/$($standardAssignmentName)?api-version=2024-08-01"

# REST API の body を作成
$payload = @{
    "properties" = @{
        "displayName" = "AWS Test Security Standard 1"
        "description" = "AWS Test Security Standard 1"
        "assignedStandard" = @{
            "id" = $customStandardId
        }
        "effect" = "Audit"
        "excludedScopes" = @()
    }
} | ConvertTo-Json

# REST API を実行
$response = Invoke-AzRestMethod -Path $path -Method Put -Payload $payload

# 実行結果の確認
$response

カスタム標準の割り当ての確認

作成後や更新時などにカスタム標準の割り当てを確認する方法です。それぞれ一覧から名前でピックアップする場合と GUID が分かっている場合の方法です。

# 割り当て一覧を取得し、名前から該当のカスタム標準をピックアップ
$path = "/$scope/providers/Microsoft.Security/standardAssignments?api-version=2024-08-01"
$response = Invoke-AzRestMethod -Path $path -Method Get
$standardAssignment = ($response.Content | ConvertFrom-Json).value | Where-Object { $_.properties.displayName -eq "AWS Test Security Standard 1" }

# 必要な項目を取得
$standardAssignmentId = $standardAssignment.id
$standardAssignmentName = $standardAssignment.name


# GUID が分かる場合は個別にカスタム標準割り当てを取得
$standardAssignmentName = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$path = "/$scope/providers/Microsoft.Security/standardAssignments/$($standardAssignmentName)?api-version=2024-08-01"
$response = Invoke-AzRestMethod -Path $path -Method Get

# 必要な項目を取得
$standardAssignmentId = ($response.Content | ConvertFrom-Json).id
$standardAssignmentName = ($response.Content | ConvertFrom-Json).name

最後に

  • 削除したい場合は各確認の項目にある、GUID を指定する方法において、-MethodGet から Delete にすれば可能です。
  • 複数環境に適用したい場合はスコープを csv などで一覧化しておき、foreach などでスコープごとに実行するように変更してご利用ください。
Microsoft (有志)

Discussion