快速入门:使用 ARM 模板创建 Azure Web 应用程序防火墙 v2
在本快速入门中,你将使用 Azure 资源管理器模板(ARM 模板)在 Azure 应用程序网关上创建 Azure Web 应用程序防火墙 (WAF) v2。
Azure 资源管理器模板是定义项目基础结构和配置的 JavaScript 对象表示法 (JSON) 文件。 模板使用声明性语法。 你可以在不编写用于创建部署的编程命令序列的情况下,描述预期部署。
注意
建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az。
如果环境满足先决条件并且你熟悉如何使用 ARM 模板,则可以选择“部署到 Azure”按钮在 Azure 门户中打开模板。
- 具有活动订阅的 Azure 帐户。 如果没有帐户,可以创建一个帐户。
此模板在 Azure 应用程序网关上创建简单的 Web 应用程序防火墙 v2。 该模板创建公共 IP 前端 IP 地址、HTTP 设置、包含端口 80 上的基本侦听器的规则,以及后端池。 包含自定义规则的 WAF 策略会基于 IP 地址匹配类型阻止发往后端池的流量。
该模板定义以下 Azure 资源:
- Microsoft.Network/applicationgateways
- Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies
- Microsoft.Network/publicIPAddresses,一个用于应用程序网关,两个用于虚拟机 (VM)
- Microsoft.Network/networkSecurityGroups
- Microsoft.Network/virtualNetworks
- Microsoft.Compute/virtualMachines,两个 VM
- Microsoft.Network/networkInterfaces,每个 VM 一个
- Microsoft.Compute/virtualMachine/extensions,用于配置 IIS 和网页
此模板来自 Azure 快速入门模板。
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.15.31.15270",
"templateHash": "7253194970749033988"
}
},
"parameters": {
"adminUsername": {
"type": "string",
"metadata": {
"description": "Admin username for the backend servers"
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Password for the admin account on the backend servers"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "Location for all resources."
}
},
"vmSize": {
"type": "string",
"defaultValue": "Standard_B2ms",
"metadata": {
"description": "Size of the virtual machine."
}
}
},
"variables": {
"virtualMachines_myVM_name": "myVM",
"virtualNetworks_myVNet_name": "myVNet",
"myNic_name": "net-int",
"ipconfig_name": "ipconfig",
"publicIPAddress_name": "public_ip",
"nsg_name": "vm-nsg",
"applicationGateways_myAppGateway_name": "myAppGateway",
"vnet_prefix": "10.0.0.0/16",
"ag_subnet_prefix": "10.0.0.0/24",
"backend_subnet_prefix": "10.0.1.0/24",
"AppGW_AppFW_Pol_name": "WafPol01"
},
"resources": [
{
"copy": {
"name": "nsg",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Network/networkSecurityGroups",
"apiVersion": "2021-08-01",
"name": "[format('{0}{1}', variables('nsg_name'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"securityRules": [
{
"name": "RDP",
"properties": {
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "3389",
"sourceAddressPrefix": "*",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 300,
"direction": "Inbound"
}
}
]
}
},
{
"copy": {
"name": "publicIPAddress",
"count": "[length(range(0, 3))]"
},
"type": "Microsoft.Network/publicIPAddresses",
"apiVersion": "2021-08-01",
"name": "[format('{0}{1}', variables('publicIPAddress_name'), range(0, 3)[copyIndex()])]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"properties": {
"publicIPAddressVersion": "IPv4",
"publicIPAllocationMethod": "Static",
"idleTimeoutInMinutes": 4
}
},
{
"type": "Microsoft.Network/virtualNetworks",
"apiVersion": "2021-08-01",
"name": "[variables('virtualNetworks_myVNet_name')]",
"location": "[parameters('location')]",
"properties": {
"addressSpace": {
"addressPrefixes": [
"[variables('vnet_prefix')]"
]
},
"subnets": [
{
"name": "myAGSubnet",
"properties": {
"addressPrefix": "[variables('ag_subnet_prefix')]",
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
},
{
"name": "myBackendSubnet",
"properties": {
"addressPrefix": "[variables('backend_subnet_prefix')]",
"privateEndpointNetworkPolicies": "Enabled",
"privateLinkServiceNetworkPolicies": "Enabled"
}
}
],
"enableDdosProtection": false,
"enableVmProtection": false
}
},
{
"copy": {
"name": "myVM",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2021-11-01",
"name": "[format('{0}{1}', variables('virtualMachines_myVM_name'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"storageProfile": {
"imageReference": {
"publisher": "MicrosoftWindowsServer",
"offer": "WindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
},
"osDisk": {
"osType": "Windows",
"createOption": "FromImage",
"caching": "ReadWrite",
"managedDisk": {
"storageAccountType": "StandardSSD_LRS"
},
"diskSizeGB": 127
}
},
"osProfile": {
"computerName": "[format('{0}{1}', variables('virtualMachines_myVM_name'), add(range(0, 2)[copyIndex()], 1))]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]",
"windowsConfiguration": {
"provisionVMAgent": true,
"enableAutomaticUpdates": true
},
"allowExtensionOperations": true
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}{1}', variables('myNic_name'), add(range(0, 2)[copyIndex()], 1)))]"
}
]
}
},
"dependsOn": [
"myNic"
]
},
{
"copy": {
"name": "myVM_IIS",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Compute/virtualMachines/extensions",
"apiVersion": "2021-11-01",
"name": "[format('{0}{1}/IIS', variables('virtualMachines_myVM_name'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"autoUpgradeMinorVersion": true,
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.4",
"settings": {
"commandToExecute": "powershell Add-WindowsFeature Web-Server; powershell Add-Content -Path \"C:\\inetpub\\wwwroot\\Default.htm\" -Value $($env:computername)"
}
},
"dependsOn": [
"myVM"
]
},
{
"type": "Microsoft.Network/applicationGateways",
"apiVersion": "2021-08-01",
"name": "[variables('applicationGateways_myAppGateway_name')]",
"location": "[parameters('location')]",
"properties": {
"sku": {
"name": "WAF_v2",
"tier": "WAF_v2",
"capacity": 2
},
"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig",
"properties": {
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworks_myVNet_name'), 'myAGSubnet')]"
}
}
}
],
"frontendIPConfigurations": [
{
"name": "appGwPublicFrontendIp",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}0', variables('publicIPAddress_name')))]"
}
}
}
],
"frontendPorts": [
{
"name": "port_80",
"properties": {
"port": 80
}
}
],
"backendAddressPools": [
{
"name": "myBackendPool",
"properties": {}
}
],
"backendHttpSettingsCollection": [
{
"name": "myHTTPSetting",
"properties": {
"port": 80,
"protocol": "Http",
"cookieBasedAffinity": "Disabled",
"pickHostNameFromBackendAddress": false,
"requestTimeout": 20
}
}
],
"httpListeners": [
{
"name": "myListener",
"properties": {
"firewallPolicy": {
"id": "[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', variables('AppGW_AppFW_Pol_name'))]"
},
"frontendIPConfiguration": {
"id": "[resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', variables('applicationGateways_myAppGateway_name'), 'appGwPublicFrontendIp')]"
},
"frontendPort": {
"id": "[resourceId('Microsoft.Network/applicationGateways/frontendPorts', variables('applicationGateways_myAppGateway_name'), 'port_80')]"
},
"protocol": "Http",
"requireServerNameIndication": false
}
}
],
"requestRoutingRules": [
{
"name": "myRoutingRule",
"properties": {
"ruleType": "Basic",
"priority": 10,
"httpListener": {
"id": "[resourceId('Microsoft.Network/applicationGateways/httpListeners', variables('applicationGateways_myAppGateway_name'), 'myListener')]"
},
"backendAddressPool": {
"id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateways_myAppGateway_name'), 'myBackendPool')]"
},
"backendHttpSettings": {
"id": "[resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', variables('applicationGateways_myAppGateway_name'), 'myHTTPSetting')]"
}
}
}
],
"enableHttp2": false,
"firewallPolicy": {
"id": "[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', variables('AppGW_AppFW_Pol_name'))]"
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies', variables('AppGW_AppFW_Pol_name'))]",
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworks_myVNet_name'))]",
"publicIPAddress"
]
},
{
"type": "Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies",
"apiVersion": "2021-08-01",
"name": "[variables('AppGW_AppFW_Pol_name')]",
"location": "[parameters('location')]",
"properties": {
"customRules": [
{
"name": "CustRule01",
"priority": 100,
"ruleType": "MatchRule",
"action": "Block",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RemoteAddr"
}
],
"operator": "IPMatch",
"negationConditon": true,
"matchValues": [
"10.10.10.0/24"
]
}
]
}
],
"policySettings": {
"requestBodyCheck": true,
"maxRequestBodySizeInKb": 128,
"fileUploadLimitInMb": 100,
"state": "Enabled",
"mode": "Prevention"
},
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.1"
}
]
}
}
},
{
"copy": {
"name": "myNic",
"count": "[length(range(0, 2))]"
},
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2021-08-01",
"name": "[format('{0}{1}', variables('myNic_name'), add(range(0, 2)[copyIndex()], 1))]",
"location": "[parameters('location')]",
"properties": {
"ipConfigurations": [
{
"name": "[format('{0}{1}', variables('ipconfig_name'), add(range(0, 2)[copyIndex()], 1))]",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}{1}', variables('publicIPAddress_name'), add(range(0, 2)[copyIndex()], 1)))]"
},
"subnet": {
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworks_myVNet_name'), 'myBackendSubnet')]"
},
"primary": true,
"privateIPAddressVersion": "IPv4",
"applicationGatewayBackendAddressPools": [
{
"id": "[resourceId('Microsoft.Network/applicationGateways/backendAddressPools', variables('applicationGateways_myAppGateway_name'), 'myBackendPool')]"
}
]
}
}
],
"enableAcceleratedNetworking": false,
"enableIPForwarding": false,
"networkSecurityGroup": {
"id": "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}{1}', variables('nsg_name'), add(range(0, 2)[copyIndex()], 1)))]"
}
},
"dependsOn": [
"[resourceId('Microsoft.Network/applicationGateways', variables('applicationGateways_myAppGateway_name'))]",
"[resourceId('Microsoft.Network/virtualNetworks', variables('virtualNetworks_myVNet_name'))]",
"nsg",
"publicIPAddress"
]
}
]
}
将 ARM 模板部署到 Azure:
选择“部署到 Azure”,登录到 Azure 并打开模板。 该模板在运行 IIS 的后端池中创建应用程序网关、网络基础结构和两个 VM。
选择或创建资源组。
选择“查看 + 创建”,然后在验证通过后选择“创建”。 部署可能需要 10 分钟或更长时间才能完成。
尽管不需要 IIS,但该模板会在后端服务器上安装 IIS,以便可以验证 Azure 是否已在应用程序网关上成功创建了 WAF v2。
使用 IIS 测试应用程序网关:
从应用程序网关的“概述”页面复制其公共 IP 地址。
还可以在 Azure 搜索框中搜索“应用程序网关”。 应用程序网关列表在“公共 IP 地址”列中显示公共 IP 地址。
将 IP 地址粘贴到浏览器的地址栏中以浏览该地址。
检查响应。 “403 禁止”响应验证 WAF 是否成功阻止与后端池的连接。
要更改自定义规则以允许流量,请运行以下 Azure PowerShell 脚本,替换资源组名称:
$rg = "<your resource group name>" $AppGW = Get-AzApplicationGateway -Name myAppGateway -ResourceGroupName $rg $pol = Get-AzApplicationGatewayFirewallPolicy -Name WafPol01 -ResourceGroupName $rg $pol[0].customrules[0].action = "allow" $rule = $pol.CustomRules Set-AzApplicationGatewayFirewallPolicy -Name WafPol01 -ResourceGroupName $rg -CustomRule $rule $AppGW.FirewallPolicy = $pol Set-AzApplicationGateway -ApplicationGateway $AppGW
多次刷新浏览器。 应会看到与 myVM1 和 myVM2 的连接。
不再需要在本快速入门中创建的资源时,请删除资源组以移除应用程序网关及其所有相关资源。
若要删除资源组,请调用 Remove-AzResourceGroup
cmdlet:
Remove-AzResourceGroup -Name "<your resource group name>"