在本快速入门中,你将使用 Azure 资源管理器模板(ARM 模板)在 Azure 应用程序网关上创建 Azure Web 应用程序防火墙 (WAF) v2。
Azure 资源管理器模板是定义项目基础结构和配置的 JavaScript 对象表示法 (JSON) 文件。 模板使用声明性语法。 你可以在不编写用于创建部署的编程命令序列的情况下,描述预期部署。
如果环境满足先决条件并且你熟悉如何使用 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>"