你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

在应用程序网关上创建和使用 Web 应用程序防火墙 v2 自定义规则

Azure 应用程序网关上的 Web 应用程序防火墙 (WAF) v2 可为 Web 应用程序提供保护。 该保护通过打开 Web 应用程序安全性项目 (OWASP) 核心规则集 (CRS) 来提供。 在某些情况下,可能需要根据具体需求创建自己的自定义规则。 有关 WAF 自定义规则的详细信息,请参阅自定义 Web 应用程序防火墙规则概述

本文介绍一些示例性的自定义规则,这些规则可以通过 v2 WAF 创建并使用。 若要了解如何使用 Azure PowerShell 通过自定义规则来部署 WAF,请参阅使用 Azure PowerShell 配置 Web 应用程序防火墙自定义规则

本文中所示的 JSON 代码片段来自 ApplicationGatewayWebApplicationFirewallPolicies 资源。

注意

如果应用程序网关未使用 WAF 层,会在右侧窗格中显示“将应用程序网关升级到 WAF 层”选项。

Enable WAF

示例 1

你知道有一个名为 evilbot 的机器人,你想要阻止其对你的网站进行爬网。 在这种情况下,你将在请求标头中阻止 User-Agent evilbot

逻辑:p

$variable = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RequestHeaders `
   -Selector User-Agent

$condition = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable `
   -Operator Contains `
   -MatchValue "evilbot" `
   -Transform Lowercase `
   -NegationCondition $False

$rule = New-AzApplicationGatewayFirewallCustomRule `
   -Name blockEvilBot `
   -Priority 2 `
   -RuleType MatchRule `
   -MatchCondition $condition `
   -Action Block `
   -State Enabled

下面是相应的 JSON:

{
  "customRules": [
    {
      "name": "blockEvilBot",
      "priority": 2,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RequestHeaders",
              "selector": "User-Agent"
            }
          ],
          "operator": "Contains",
          "negationCondition": false,
          "matchValues": [
            "evilbot"
          ],
          "transforms": [
            "Lowercase"
          ]
        }
      ]
    }
  ]
}

若要查看使用此自定义规则部署的 WAF,请参阅使用 Azure PowerShell 配置 Web 应用程序防火墙自定义规则

示例 1a

可以使用正则表达式完成同样的事情:

$variable = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RequestHeaders `
   -Selector User-Agent

$condition = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable `
   -Operator Regex `
   -MatchValue "evilbot" `
   -Transform Lowercase `
   -NegationCondition $False

$rule = New-AzApplicationGatewayFirewallCustomRule `
   -Name blockEvilBot `
   -Priority 2 `
   -RuleType MatchRule `
   -MatchCondition $condition `
   -Action Block `
   -State Enabled

相应的 JSON:

{
  "customRules": [
    {
      "name": "blockEvilBot",
      "priority": 2,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RequestHeaders",
              "selector": "User-Agent"
            }
          ],
          "operator": "Regex",
          "negationCondition": false,
          "matchValues": [
            "evilbot"
          ],
          "transforms": [
            "Lowercase"
          ]
        }
      ]
    }
  ]
}

示例 2

你想要使用 GeoMatch 运算符仅允许来自美国的流量,并且仍应用托管规则:

$variable = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RemoteAddr `

$condition = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable `
   -Operator GeoMatch `
   -MatchValue "US" `
   -Transform Lowercase `
   -NegationCondition $True

$rule = New-AzApplicationGatewayFirewallCustomRule `
   -Name "allowUS" `
   -Priority 2 `
   -RuleType MatchRule `
   -MatchCondition $condition `
   -Action Block `
   -State Enabled

相应的 JSON:

{
  "customRules": [
    {
      "name": "allowUS",
      "priority": 2,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RemoteAddr"
            }
          ],
          "operator": "GeoMatch",
          "negationCondition": true,
          "matchValues": [
            "US"
          ],
          "transforms": [
            "Lowercase"
          ]
        }
      ]
    }
  ]
}

示例 3

你想要阻止来自范围 198.168.5.0/24 内 IP 地址的所有请求。

在此示例中,你将阻止来自某个 IP 地址范围的所有流量。 规则名称为 myrule1,优先级设置为 10。

逻辑:p

$variable1 = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RemoteAddr

$condition1 = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable1 `
   -Operator IPMatch `
   -MatchValue "192.168.5.0/24" `
   -NegationCondition $False

$rule = New-AzApplicationGatewayFirewallCustomRule `
   -Name myrule1 `
   -Priority 10 `
   -RuleType MatchRule `
   -MatchCondition $condition1 `
   -Action Block `
   -State Enabled

下面是相应的 JSON:

{
  "customRules": [
    {
      "name": "myrule1",
      "priority": 10,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RemoteAddr"
            }
          ],
          "operator": "IPMatch",
          "negationCondition": false,
          "matchValues": [
            "192.168.5.0/24"
          ],
          "transforms": []
        }
      ]
    }
  ]
}

相应的 CRS 规则:SecRule REMOTE_ADDR "@ipMatch 192.168.5.0/24" "id:7001,deny"

示例 4

在此示例中,需阻止用户代理 evilbot 和 192.168.5.0/24 范围内的流量。 为此,可以创建两个独立的匹配条件,并将其置于同一规则中。 此配置可以确保如果 User-Agent 标头中的 evilbot 192.168.5.0/24 范围内的 IP 地址都匹配,则将阻止该请求。

逻辑:p and q

$variable1 = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RemoteAddr

 $variable2 = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RequestHeaders `
   -Selector User-Agent

$condition1 = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable1 `
   -Operator IPMatch `
   -MatchValue "192.168.5.0/24" `
   -NegationCondition $False

$condition2 = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable2 `
   -Operator Contains `
   -MatchValue "evilbot" `
   -Transform Lowercase `
   -NegationCondition $False

 $rule = New-AzApplicationGatewayFirewallCustomRule `
   -Name myrule `
   -Priority 10 `
   -RuleType MatchRule `
   -MatchCondition $condition1, $condition2 `
   -Action Block `
   -State Enabled

下面是相应的 JSON:

{
  "customRules": [
    {
      "name": "myrule",
      "priority": 10,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RemoteAddr"
            }
          ],
          "operator": "IPMatch",
          "negationCondition": false,
          "matchValues": [
            "192.168.5.0/24"
          ],
          "transforms": []
        },
        {
          "matchVariables": [
            {
              "variableName": "RequestHeaders",
              "selector": "User-Agent"
            }
          ],
          "operator": "Contains",
          "negationCondition": false,
          "matchValues": [
            "evilbot"
          ],
          "transforms": [
            "Lowercase"
          ]
        }
      ]
    }
  ]
}

示例 5

在此示例中,需阻止 IP 地址范围 192.168.5.0/24 之外的请求,或者阻止用户代理字符串不为 chrome(即用户不使用 Chrome 浏览器)的请求。 由于此逻辑使用 or,因此这两个条件位于不同的规则中,如以下示例所示。 myrule1myrule2 都需要匹配才能阻止流量。

逻辑:not (p and q) = not p or not q。

$variable1 = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RemoteAddr

$variable2 = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RequestHeaders `
   -Selector User-Agent

$condition1 = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable1 `
   -Operator IPMatch `
   -MatchValue "192.168.5.0/24" `
   -NegationCondition $True

$condition2 = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable2 `
   -Operator Contains `
   -MatchValue "chrome" `
   -Transform Lowercase `
   -NegationCondition $True

$rule1 = New-AzApplicationGatewayFirewallCustomRule `
   -Name myrule1 `
   -Priority 10 `
   -RuleType MatchRule `
   -MatchCondition $condition1 `
   -Action Block `
   -State Enabled

$rule2 = New-AzApplicationGatewayFirewallCustomRule `
   -Name myrule2 `
   -Priority 20 `
   -RuleType MatchRule `
   -MatchCondition $condition2 `
   -Action Block `
   -State Enabled

相应的 JSON:

{
  "customRules": [
    {
      "name": "myrule1",
      "priority": 10,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RemoteAddr"
            }
          ],
          "operator": "IPMatch",
          "negationCondition": true,
          "matchValues": [
            "192.168.5.0/24"
          ],
          "transforms": []
        }
      ]
    },
    {
      "name": "myrule2",
      "priority": 20,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RequestHeaders",
              "selector": "User-Agent"
            }
          ],
          "operator": "Contains",
          "negationCondition": true,
          "matchValues": [
            "chrome"
          ],
          "transforms": [
            "Lowercase"
          ]
        }
      ]
    }
  ]
}

示例 6

你想要仅允许来自特定已知用户代理的请求。

由于此处使用的逻辑为 or,且所有值都在 User-Agent 标头中,因此可以将所有 MatchValues 置于逗号分隔的列表中。

逻辑:p or q or r

$variable = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RequestHeaders `
   -Selector User-Agent
$condition = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable `
   -Operator Equal `
   -MatchValue @('user1', 'user2') `
   -NegationCondition $True

$rule = New-AzApplicationGatewayFirewallCustomRule `
   -Name BlockUnknownUserAgents `
   -Priority 2 `
   -RuleType MatchRule `
   -MatchCondition $condition `
   -Action Block `
   -State Enabled

相应的 JSON:

{
  "customRules": [
    {
      "name": "BlockUnknownUserAgents",
      "priority": 2,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RequestHeaders",
              "selector": "User-Agent"
            }
          ],
          "operator": "Equal",
          "negationCondition": true,
          "matchValues": [
            "user1",
            "user2"
          ],
          "transforms": []
        }
      ]
    }
  ]
}

示例 7

Azure Front Door 部署在应用程序网关前面的情况并不少见。 为了确保应用程序网关接收的流量来自 Front Door 部署,最佳做法是检查 X-Azure-FDID 标头是否包含预期的唯一值。 有关使用 Azure Front Door 保护对应用程序的访问的详细信息,请参阅如何将对后端的访问锁定为仅限 Azure Front Door

逻辑:非 p

$expectedFDID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$variable = New-AzApplicationGatewayFirewallMatchVariable `
   -VariableName RequestHeaders `
   -Selector X-Azure-FDID

$condition = New-AzApplicationGatewayFirewallCondition `
   -MatchVariable $variable `
   -Operator Equal `
   -MatchValue $expectedFDID `
   -Transform Lowercase `
   -NegationCondition $True

$rule = New-AzApplicationGatewayFirewallCustomRule `
   -Name blockNonAFDTraffic `
   -Priority 2 `
   -RuleType MatchRule `
   -MatchCondition $condition `
   -Action Block `
   -State Enabled

下面是相应的 JSON:

{
  "customRules": [
    {
      "name": "blockNonAFDTraffic",
      "priority": 2,
      "ruleType": "MatchRule",
      "action": "Block",
      "state": "Enabled",
      "matchConditions": [
        {
          "matchVariables": [
            {
              "variableName": "RequestHeaders",
              "selector": "X-Azure-FDID"
            }
          ],
          "operator": "Equal",
          "negationCondition": true,
          "matchValues": [
            "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          ],
          "transforms": [
            "Lowercase"
          ]
        }
      ]
    }
  ]
}

后续步骤

创建自定义规则后,可以了解如何查看 WAF 日志。 有关详细信息,请参阅应用程序网关诊断