CRS または DRS ルールセットのバージョンをアップグレードする

適用対象: ✔️ Application Gateway V2

Azure Application Gateway Web Application Firewall (WAF) の Azure で管理 される既定の規則セット (DRS) は、OWASP の上位 10 種類の攻撃など、一般的な脆弱性や悪用から Web アプリケーションを保護します。 また、既定のルール セットには、Microsoft 脅威インテリジェンス コレクションのルールも組み込まれています。 最新のセキュリティ更新プログラム、ルールの機能強化、修正プログラムを含む最新のルール セット バージョンを常に実行します。

Azure で管理される既定の規則セット (DRS) は、以前のすべてのコア ルール セット (CRS) バージョンを置き換える、Azure WAF の最新世代のルールセットです。 DRS のリリースの中では、常に利用可能な最新バージョン(DRS 2.2)を使用して、最新の保護を確実に利用できるようにしてください。

この記事では、Azure WAF ポリシーを CRS 3.0、CRS 3.1、CRS 3.2、または DRS 2.1 から DRS 2.2 にアップグレードする PowerShell の例を示します。

PowerShell スニペットは例にすぎません。 すべてのプレースホルダーを環境の値に置き換えます。

[前提条件]

アップグレード時の主な考慮事項

Azure WAF ルールセットのバージョンをアップグレードするときは、次のことを確認してください。

  • 既存のカスタマイズを保持する: ルール アクションのオーバーライド、ルールの状態 (有効または無効) のオーバーライド、除外を引き継ぐ。

  • 削除されたルールのカスタマイズを削除する: DRS 2.2 に存在しなくなったルールのオーバーライドや除外は引き継がないでください。 DRS 2.2 に含まれていないルールのオーバーライドを引き継ぐと、ポリシーの更新が失敗し、 The override Rule '<id>' is unknown for RuleGroup '<group>'などのエラーが発生します。

  • パラノイア レベル ベースラインのアカウント: DRS 2.2 は、既定で Paranoia レベル 1 (PL1) で動作し、すべての PL2 ルールが既定で無効になっています。 CRS 3.2 および DRS 2.1 では、PL2 ルールがアクティブでした。 以前にカスタマイズした PL2 ルールは、明示的に再度有効にするまで、DRS 2.2 では既定で無効になります。

  • 新しいルールを安全に検証します。既定で有効になっている新しく追加されたルール (PL1) は、最初は ログ モードに設定されるため、ブロックを有効にする前に影響を監視して微調整できます。

環境と変数を準備する

  1. 選択したサブスクリプション、リソース グループ、およびAZURE WAF ポリシーのコンテキストを設定します。

    Import-Module Az.Network
    Set-AzContext -SubscriptionId "<subscription_id>"
    $resourceGroupName = "<resource_group>"
    $wafPolicyName = "<policy_name>"
    
  2. WAF ポリシー オブジェクトを取得し、その定義を取得します。 現在のマネージド ルール セットには、CRS (OWASP) 型または DRS (Microsoft_DefaultRuleSet) 型を指定できます。

    $wafPolicy = Get-AzApplicationGatewayFirewallPolicy `
        -Name $wafPolicyName `
        -ResourceGroupName $resourceGroupName
    
    $currentExclusions = $wafPolicy.ManagedRules.Exclusions
    $currentManagedRuleset = $wafPolicy.ManagedRules.ManagedRuleSets |
        Where-Object { $_.RuleSetType -eq "OWASP" -or $_.RuleSetType -eq "Microsoft_DefaultRuleSet" }
    $currentVersion = $currentManagedRuleset.RuleSetVersion
    

既存のカスタマイズを保持する

  1. ルールがまだ DRS 2.2 に存在する場合にのみ、オーバーライドまたは除外を引き継ぐ。 次の関数は、DRS 2.2 ルールの完全なセットに対してルール ID を検証し、削除されたすべてのルールの $true を返します ( 920460942130920250などの従来のルールと非アクティブなルールを含む)。 有効なルール ID の許可リストを使用すると、ルールごとのメンテナンスが回避され、不明なルールでポリシーの更新が失敗するのを防ぐことができます。

    function Test-RuleIsRemovedFromDRS22 {
        param (
            [string]$RuleId,
            [string]$CurrentRulesetVersion  # Retained for compatibility; not used
        )
    
        # Complete set of rule IDs that exist in DRS 2.2.
        # Any override or exclusion for a rule NOT in this set is dropped during migration.
        $drs22RuleIds = @(
            "200002","200003",
            "911100",
            "920100","920120","920121","920160","920170","920171","920180","920181","920190","920200","920201","920210","920220","920230","920240","920260","920270","920271","920280","920290","920300","920310","920311","920320","920330","920340","920341","920350","920420","920430","920440","920450","920470","920480","920500","920530","920620",
            "921110","921120","921130","921140","921150","921151","921160","921190","921200","921422",
            "930100","930110","930120","930130",
            "931100","931110","931120","931130",
            "932100","932105","932110","932115","932120","932130","932140","932150","932160","932170","932171","932180",
            "933100","933110","933120","933130","933140","933150","933151","933160","933170","933180","933200","933210",
            "934100",
            "941100","941101","941110","941120","941130","941140","941150","941160","941170","941180","941190","941200","941210","941220","941230","941240","941250","941260","941270","941280","941290","941300","941310","941320","941330","941340","941350","941360","941370","941380",
            "942100","942110","942120","942140","942150","942160","942170","942180","942190","942200","942210","942220","942230","942240","942250","942260","942270","942280","942290","942300","942310","942320","942330","942340","942350","942360","942361","942370","942380","942390","942400","942410","942430","942440","942450","942470","942480","942500","942510",
            "943100","943110","943120",
            "944100","944110","944120","944130","944200","944210","944240","944250",
            "99005002","99005003","99005004","99005005","99005006",
            "99030001","99030002","99030003","99030004","99030005","99030006",
            "99031001","99031002","99031003","99031004","99031005","99031006",
            "99001001","99001002","99001003","99001004","99001005","99001006","99001007","99001008","99001009","99001010","99001011","99001012","99001013","99001014","99001015","99001016","99001017","99001018",
            "99032001","99032002"
        )
    
        return -not ($drs22RuleIds -contains $RuleId)
    }
    
  2. 新しいオーバーライド オブジェクトを作成するときは、 DRS 2.2 グループ名を使用します。 次の関数は、従来の CRS グループ名を DRS グループにマップします。 マップ内にない DRS ソース グループ名 (DRS 2.1 からアップグレードする場合など) は変更されずに返されます。

    function Get-DrsRuleGroupName {
        param (
            [Parameter(Mandatory = $true)]
            [string]$SourceGroupName
        )
        $groupMap = @{
            "REQUEST-930-APPLICATION-ATTACK-LFI"             = "LFI"
            "REQUEST-931-APPLICATION-ATTACK-RFI"             = "RFI"
            "REQUEST-932-APPLICATION-ATTACK-RCE"             = "RCE"
            "REQUEST-933-APPLICATION-ATTACK-PHP"             = "PHP"
            "REQUEST-941-APPLICATION-ATTACK-XSS"             = "XSS"
            "REQUEST-942-APPLICATION-ATTACK-SQLI"            = "SQLI"
            "REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" = "FIX"
            "REQUEST-944-APPLICATION-ATTACK-JAVA"            = "JAVA"
            "REQUEST-921-PROTOCOL-ATTACK"                    = "PROTOCOL-ATTACK"
            "REQUEST-911-METHOD-ENFORCEMENT"                 = "METHOD-ENFORCEMENT"
            "REQUEST-920-PROTOCOL-ENFORCEMENT"               = "PROTOCOL-ENFORCEMENT"
            "REQUEST-913-SCANNER-DETECTION"                  = $null  # No direct mapping
            "Known-CVEs"                                     = "MS-ThreatIntel-CVEs"
            "General"                                        = "General"
        }
        if ($groupMap.ContainsKey($SourceGroupName)) {
            return $groupMap[$SourceGroupName]
        } else {
            return $SourceGroupName  # No known mapping; pass through (DRS source group names)
        }
    }
    
  3. 次の PowerShell コードを使用して、ルールのオーバーライドを定義し、既存のルール セット バージョンからのオーバーライドを複製します。

    $groupOverrides = @()
    foreach ($group in $currentManagedRuleset.RuleGroupOverrides) {
        $mappedGroupName = Get-DrsRuleGroupName $group.RuleGroupName
        if (-not $mappedGroupName) { continue }  # Skip groups with no DRS equivalent
        foreach ($existingRule in $group.Rules) {
            if (-not (Test-RuleIsRemovedFromDRS22 $existingRule.RuleId $currentVersion)) {
                $existingGroup = $groupOverrides | Where-Object { $_.RuleGroupName -eq $mappedGroupName }
                if ($existingGroup) {
                    if (-not ($existingGroup.Rules | Where-Object { $_.RuleId -eq $existingRule.RuleId })) {
                        $existingGroup.Rules.Add($existingRule)
                    }
                } else {
                    $newGroup = New-AzApplicationGatewayFirewallPolicyManagedRuleGroupOverride `
                        -RuleGroupName $mappedGroupName `
                        -Rule @($existingRule)
                    $groupOverrides += $newGroup
                }
            }
        }
    }
    
  4. 次の PowerShell コードを使用して既存の除外を複製し、DRS 2.2 に適用します。

    # Create new exclusion objects
    $newRuleSetExclusions = @()
    
    if ($currentExclusions -ne $null -and $currentExclusions.Count -gt 0) {
        foreach ($exclusion in $currentExclusions) {
            $newExclusion = New-AzApplicationGatewayFirewallPolicyExclusion `
                -MatchVariable $exclusion.MatchVariable `
                -SelectorMatchOperator $exclusion.SelectorMatchOperator `
                -Selector $exclusion.Selector
    
            # Migrate scopes: RuleSet, RuleGroup, or individual Rules
            if ($exclusion.ExclusionManagedRuleSets) {
                foreach ($scope in $exclusion.ExclusionManagedRuleSets) {
                    # Create RuleGroup objects from existing RuleGroups
                    $ruleGroups = @()
                    foreach ($group in $scope.RuleGroups) {
                        $drsGroupName = Get-DrsRuleGroupName $group.RuleGroupName
                        if ($drsGroupName) {
                            $exclusionRules = @()
                            foreach ($rule in $group.Rules) {
                                if (-not (Test-RuleIsRemovedFromDRS22 $rule.RuleId $currentVersion)) {
                                    $exclusionRules += New-AzApplicationGatewayFirewallPolicyExclusionManagedRule `
                                        -RuleId $rule.RuleId
                                }
                            }
                            if ($exclusionRules -ne $null -and $exclusionRules.Count -gt 0) {
                                $ruleGroups += New-AzApplicationGatewayFirewallPolicyExclusionManagedRuleGroup `
                                    -Name $drsGroupName `
                                    -Rule $exclusionRules
                            } else {
                                $ruleGroups += New-AzApplicationGatewayFirewallPolicyExclusionManagedRuleGroup `
                                    -Name $drsGroupName
                            }
                        }
                    }
    
                    # Create the ManagedRuleSet scope object with the updated RuleGroups
                    if ($ruleGroups.Count -gt 0) {
                        $newRuleSetScope = New-AzApplicationGatewayFirewallPolicyExclusionManagedRuleSet `
                            -Type "Microsoft_DefaultRuleSet" `
                            -Version "2.2" `
                            -RuleGroup $ruleGroups
    
                        # Add to the new exclusion object
                        $newExclusion.ExclusionManagedRuleSets += $newRuleSetScope
                    }
                }
            }
    
            if (-not $newExclusion.ExclusionManagedRuleSets) {
                $newExclusion.ExclusionManagedRuleSets = @()
            }
    
            $newRuleSetExclusions += $newExclusion
        }
    }
    

新しいルールを安全に検証する

アップグレードすると、Paranoia レベル 1 に属する新しい DRS 2.2 ルールが既定で有効になります。 WAF が 防止 モードの場合は、これらの新しいルールを最初に ログ モードに設定して、ブロックを有効にする前にログを確認できるようにします。

Paranoia レベル 2 に属するルールは、DRS 2.2 では既定で無効になっており、トラフィックをブロックしないため、この手順は必要ありません。 Paranoia レベル 2 で操作する場合は、関連する PL2 規則を明示的に有効にし、同じログ内検証アプローチに従います。

  1. アップグレードするバージョンと一致する 定義を使用します。 各定義には、DRS 2.2 で導入され、そのバージョンと比較して既定で有効になっている規則が一覧表示されます。

    # Added and enabled by default in DRS 2.2 compared to CRS 3.0
    $rulesAddedInThisVersionByGroup = @{
        "General"              = @("200002", "200003")
        "PROTOCOL-ENFORCEMENT" = @("920171", "920181", "920470", "920480", "920500", "920530", "920620")
        "PROTOCOL-ATTACK"      = @("921190", "921200")
        "RCE"                  = @("932180")
        "PHP"                  = @("933200", "933210")
        "NODEJS"               = @("934100")
        "XSS"                  = @("941360", "941370")
        "SQLI"                 = @("942500")
        "JAVA"                 = @("944100", "944110", "944120", "944130")
        "MS-ThreatIntel-CVEs"  = @("99001018")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
    # Added and enabled by default in DRS 2.2 compared to CRS 3.1
    $rulesAddedInThisVersionByGroup = @{
        "General"              = @("200002", "200003")
        "PROTOCOL-ENFORCEMENT" = @("920181", "920500", "920530", "920620")
        "PROTOCOL-ATTACK"      = @("921190", "921200")
        "PHP"                  = @("933200", "933210")
        "NODEJS"               = @("934100")
        "XSS"                  = @("941360", "941370")
        "SQLI"                 = @("942500")
        "MS-ThreatIntel-CVEs"  = @("99001018")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
    # Added and enabled by default in DRS 2.2 compared to CRS 3.2
    $rulesAddedInThisVersionByGroup = @{
        "PROTOCOL-ENFORCEMENT" = @("920181", "920500", "920530", "920620")
        "PROTOCOL-ATTACK"      = @("921190", "921200")
        "NODEJS"               = @("934100")
        "XSS"                  = @("941370")
        "MS-ThreatIntel-CVEs"  = @("99001018")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
    # Added and enabled by default in DRS 2.2 compared to DRS 2.1
    $rulesAddedInThisVersionByGroup = @{
        "PROTOCOL-ENFORCEMENT" = @("920530", "920620")
        "MS-ThreatIntel-XSS"   = @("99032001")
    }
    
  2. 次の PowerShell コードを使用して、前に定義した既存の $groupOverrides オブジェクトに新しい規則のオーバーライドを追加します。

    foreach ($groupName in $rulesAddedInThisVersionByGroup.Keys) {
        $ruleOverrides = @()
        foreach ($ruleId in $rulesAddedInThisVersionByGroup[$groupName]) {
            $existingGroup = $groupOverrides | Where-Object { $_.RuleGroupName -eq $groupName }
            $alreadyExists = $false
            if ($existingGroup) {
                $alreadyExists = $existingGroup.Rules | Where-Object { $_.RuleId -eq $ruleId }
            }
            if (-not $alreadyExists) {
                $ruleOverrides += New-AzApplicationGatewayFirewallPolicyManagedRuleOverride `
                    -RuleId $ruleId `
                    -Action "Log" `
                    -State "Enabled"
            }
        }
        # Only create or update the group override if we added rules to it
        if ($ruleOverrides.Count -gt 0) {
            $existingGroup = $groupOverrides | Where-Object { $_.RuleGroupName -eq $groupName }
            if ($existingGroup) {
                foreach ($ruleOverride in $ruleOverrides) {
                    $existingGroup.Rules.Add($ruleOverride)
                }
            } else {
                $groupOverrides += New-AzApplicationGatewayFirewallPolicyManagedRuleGroupOverride `
                    -RuleGroupName $groupName `
                    -Rule $ruleOverrides
            }
        }
    }
    

カスタマイズとアップグレードを適用する

重複した規則と更新された規則のオーバーライドと除外を組み込んで、更新された Azure WAF ポリシー オブジェクトを定義します。

$managedRuleSet = New-AzApplicationGatewayFirewallPolicyManagedRuleSet `
    -RuleSetType "Microsoft_DefaultRuleSet" `
    -RuleSetVersion "2.2" `
    -RuleGroupOverride $groupOverrides

# Replace the existing CRS (OWASP) or DRS (Microsoft_DefaultRuleSet) managed rule set
for ($i = 0; $i -lt $wafPolicy.ManagedRules.ManagedRuleSets.Count; $i++) {
    if ($wafPolicy.ManagedRules.ManagedRuleSets[$i].RuleSetType -eq "OWASP" -or
        $wafPolicy.ManagedRules.ManagedRuleSets[$i].RuleSetType -eq "Microsoft_DefaultRuleSet") {
        $wafPolicy.ManagedRules.ManagedRuleSets[$i] = $managedRuleSet
        break
    }
}

# Assign the migrated exclusions to the policy
$wafPolicy.ManagedRules.Exclusions = $newRuleSetExclusions

# Apply the updated WAF policy
Set-AzApplicationGatewayFirewallPolicy -InputObject $wafPolicy