升级 CRS 或 DRS 规则集版本

适用于: ✔️应用程序网关 V2

Azure 应用程序网关 Web 应用程序防火墙(WAF)中的 Azure 托管 的默认规则集(DRS) 可保护 Web 应用程序免受常见漏洞和攻击,包括 OWASP 前 10 种攻击类型。 默认规则集还包含 Microsoft 威胁情报收集规则。 始终运行 最新的规则集版本,其中包括最新的安全更新、规则增强和修补程序。

Azure 托管的默认规则集(DRS)是 Azure WAF 中最新一代的规则集,取代了以前的所有核心规则集(CRS)版本。 在各个 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 默认在偏执级别 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