|
| 1 | +--- |
| 2 | +title: Restrict web traffic with a web application firewall - Azure PowerShell |
| 3 | +description: Learn how to restrict web traffic with a web application firewall on an application gateway using Azure PowerShell. |
| 4 | +services: application-gateway |
| 5 | +author: vhorne |
| 6 | +manager: jpconnock |
| 7 | +tags: azure-resource-manager |
| 8 | + |
| 9 | +ms.service: application-gateway |
| 10 | +ms.topic: tutorial |
| 11 | +ms.workload: infrastructure-services |
| 12 | +ms.date: 3/22/2018 |
| 13 | +ms.author: victorh |
| 14 | +ms.custom: mvc |
| 15 | +--- |
| 16 | +# Tutorial: Restrict web traffic with a web application firewall using Azure PowerShell |
| 17 | + |
| 18 | +You can restrict traffic on an [application gateway](overview.md) with a [web application firewall](waf-overview.md) (WAF). The WAF uses [OWASP](https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project) rules to protect your application. These rules include protection against attacks such as SQL injection, cross-site scripting attacks, and session hijacks. |
| 19 | + |
| 20 | +In this tutorial, you learn how to: |
| 21 | + |
| 22 | +> [!div class="checklist"] |
| 23 | +> * Set up the network |
| 24 | +> * Create an application gateway with WAF enabled |
| 25 | +> * Create a virtual machine scale set |
| 26 | +> * Create a storage account and configure diagnostics |
| 27 | +
|
| 28 | + |
| 29 | + |
| 30 | +If you don't have an Azure subscription, create a [free account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F) before you begin. |
| 31 | + |
| 32 | +[!INCLUDE [cloud-shell-powershell.md](../../includes/cloud-shell-powershell.md)] |
| 33 | + |
| 34 | +If you choose to install and use the PowerShell locally, this tutorial requires the Azure PowerShell module version 3.6 or later. Run ` Get-Module -ListAvailable AzureRM` to find the version. If you need to upgrade, see [Install Azure PowerShell module](/powershell/azure/install-azurerm-ps). If you are running PowerShell locally, you also need to run `Login-AzureRmAccount` to create a connection with Azure. |
| 35 | + |
| 36 | +## Create a resource group |
| 37 | + |
| 38 | +A resource group is a logical container into which Azure resources are deployed and managed. Create an Azure resource group using [New-AzureRmResourceGroup](/powershell/module/azurerm.resources/new-azurermresourcegroup). |
| 39 | + |
| 40 | +```azurepowershell-interactive |
| 41 | +New-AzureRmResourceGroup -Name myResourceGroupAG -Location eastus |
| 42 | +``` |
| 43 | + |
| 44 | +## Create network resources |
| 45 | + |
| 46 | +Create the subnet configurations named *myBackendSubnet* and *myAGSubnet* using [New-AzureRmVirtualNetworkSubnetConfig](/powershell/module/azurerm.network/new-azurermvirtualnetworksubnetconfig). Create the virtual network named *myVNet* using [New-AzureRmVirtualNetwork](/powershell/module/azurerm.network/new-azurermvirtualnetwork) with the subnet configurations. And finally, create the public IP address named *myAGPublicIPAddress* using [New-AzureRmPublicIpAddress](/powershell/module/azurerm.network/new-azurermpublicipaddress). These resources are used to provide network connectivity to the application gateway and its associated resources. |
| 47 | + |
| 48 | +```azurepowershell-interactive |
| 49 | +$backendSubnetConfig = New-AzureRmVirtualNetworkSubnetConfig ` |
| 50 | + -Name myBackendSubnet ` |
| 51 | + -AddressPrefix 10.0.1.0/24 |
| 52 | +
|
| 53 | +$agSubnetConfig = New-AzureRmVirtualNetworkSubnetConfig ` |
| 54 | + -Name myAGSubnet ` |
| 55 | + -AddressPrefix 10.0.2.0/24 |
| 56 | +
|
| 57 | +$vnet = New-AzureRmVirtualNetwork ` |
| 58 | + -ResourceGroupName myResourceGroupAG ` |
| 59 | + -Location eastus ` |
| 60 | + -Name myVNet ` |
| 61 | + -AddressPrefix 10.0.0.0/16 ` |
| 62 | + -Subnet $backendSubnetConfig, $agSubnetConfig |
| 63 | +
|
| 64 | +$pip = New-AzureRmPublicIpAddress ` |
| 65 | + -ResourceGroupName myResourceGroupAG ` |
| 66 | + -Location eastus ` |
| 67 | + -Name myAGPublicIPAddress ` |
| 68 | + -AllocationMethod Dynamic |
| 69 | +``` |
| 70 | + |
| 71 | +## Create an application gateway |
| 72 | + |
| 73 | +In this section you create resources that support the application gateway, and then finally create it and a WAF. The resources that you create include: |
| 74 | + |
| 75 | +- *IP configurations and frontend port* - Associates the subnet that you previously created to the application gateway and assigns a port to use to access it. |
| 76 | +- *Default pool* - All application gateways must have at least one backend pool of servers. |
| 77 | +- *Default listener and rule* - The default listener listens for traffic on the port that was assigned and the default rule sends traffic to the default pool. |
| 78 | + |
| 79 | +### Create the IP configurations and frontend port |
| 80 | + |
| 81 | +Associate *myAGSubnet* that you previously created to the application gateway using [New-AzureRmApplicationGatewayIPConfiguration](/powershell/module/azurerm.network/new-azurermapplicationgatewayipconfiguration). Assign *myAGPublicIPAddress* to the application gateway using [New-AzureRmApplicationGatewayFrontendIPConfig](/powershell/module/azurerm.network/new-azurermapplicationgatewayfrontendipconfig). |
| 82 | + |
| 83 | +```azurepowershell-interactive |
| 84 | +$vnet = Get-AzureRmVirtualNetwork ` |
| 85 | + -ResourceGroupName myResourceGroupAG ` |
| 86 | + -Name myVNet |
| 87 | +
|
| 88 | +$subnet=$vnet.Subnets[0] |
| 89 | +
|
| 90 | +$gipconfig = New-AzureRmApplicationGatewayIPConfiguration ` |
| 91 | + -Name myAGIPConfig ` |
| 92 | + -Subnet $subnet |
| 93 | +
|
| 94 | +$fipconfig = New-AzureRmApplicationGatewayFrontendIPConfig ` |
| 95 | + -Name myAGFrontendIPConfig ` |
| 96 | + -PublicIPAddress $pip |
| 97 | +
|
| 98 | +$frontendport = New-AzureRmApplicationGatewayFrontendPort ` |
| 99 | + -Name myFrontendPort ` |
| 100 | + -Port 80 |
| 101 | +``` |
| 102 | + |
| 103 | +### Create the backend pool and settings |
| 104 | + |
| 105 | +Create the backend pool named *appGatewayBackendPool* for the application gateway using [New-AzureRmApplicationGatewayBackendAddressPool](/powershell/module/azurerm.network/new-azurermapplicationgatewaybackendaddresspool). Configure the settings for the backend address pools using [New-AzureRmApplicationGatewayBackendHttpSettings](/powershell/module/azurerm.network/new-azurermapplicationgatewaybackendhttpsettings). |
| 106 | + |
| 107 | +```azurepowershell-interactive |
| 108 | +$defaultPool = New-AzureRmApplicationGatewayBackendAddressPool ` |
| 109 | + -Name appGatewayBackendPool |
| 110 | +
|
| 111 | +$poolSettings = New-AzureRmApplicationGatewayBackendHttpSettings ` |
| 112 | + -Name myPoolSettings ` |
| 113 | + -Port 80 ` |
| 114 | + -Protocol Http ` |
| 115 | + -CookieBasedAffinity Enabled ` |
| 116 | + -RequestTimeout 120 |
| 117 | +``` |
| 118 | + |
| 119 | +### Create the default listener and rule |
| 120 | + |
| 121 | +A listener is required to enable the application gateway to route traffic appropriately to the backend address pools. In this example, you create a basic listener that listens for traffic at the root URL. |
| 122 | + |
| 123 | +Create a listener named *mydefaultListener* using [New-AzureRmApplicationGatewayHttpListener](/powershell/module/azurerm.network/new-azurermapplicationgatewayhttplistener) with the frontend configuration and frontend port that you previously created. A rule is required for the listener to know which backend pool to use for incoming traffic. Create a basic rule named *rule1* using [New-AzureRmApplicationGatewayRequestRoutingRule](/powershell/module/azurerm.network/new-azurermapplicationgatewayrequestroutingrule). |
| 124 | + |
| 125 | +```azurepowershell-interactive |
| 126 | +$defaultlistener = New-AzureRmApplicationGatewayHttpListener ` |
| 127 | + -Name mydefaultListener ` |
| 128 | + -Protocol Http ` |
| 129 | + -FrontendIPConfiguration $fipconfig ` |
| 130 | + -FrontendPort $frontendport |
| 131 | +
|
| 132 | +$frontendRule = New-AzureRmApplicationGatewayRequestRoutingRule ` |
| 133 | + -Name rule1 ` |
| 134 | + -RuleType Basic ` |
| 135 | + -HttpListener $defaultlistener ` |
| 136 | + -BackendAddressPool $defaultPool ` |
| 137 | + -BackendHttpSettings $poolSettings |
| 138 | +``` |
| 139 | + |
| 140 | +### Create the application gateway with the WAF |
| 141 | + |
| 142 | +Now that you created the necessary supporting resources, specify parameters for the application gateway using [New-AzureRmApplicationGatewaySku](/powershell/module/azurerm.network/new-azurermapplicationgatewaysku). Specify the WAF configuration using [New-AzureRmApplicationGatewayWebApplicationFirewallConfiguration](/powershell/module/azurerm.network/new-azurermapplicationgatewaywebapplicationfirewallconfiguration). And then create the application gateway named *myAppGateway* using [New-AzureRmApplicationGateway](/powershell/module/azurerm.network/new-azurermapplicationgateway). |
| 143 | + |
| 144 | +```azurepowershell-interactive |
| 145 | +$sku = New-AzureRmApplicationGatewaySku ` |
| 146 | + -Name WAF_Medium ` |
| 147 | + -Tier WAF ` |
| 148 | + -Capacity 2 |
| 149 | +
|
| 150 | +$wafConfig = New-AzureRmApplicationGatewayWebApplicationFirewallConfiguration ` |
| 151 | + -Enabled $true ` |
| 152 | + -FirewallMode "Detection" |
| 153 | +
|
| 154 | +$appgw = New-AzureRmApplicationGateway ` |
| 155 | + -Name myAppGateway ` |
| 156 | + -ResourceGroupName myResourceGroupAG ` |
| 157 | + -Location eastus ` |
| 158 | + -BackendAddressPools $defaultPool ` |
| 159 | + -BackendHttpSettingsCollection $poolSettings ` |
| 160 | + -FrontendIpConfigurations $fipconfig ` |
| 161 | + -GatewayIpConfigurations $gipconfig ` |
| 162 | + -FrontendPorts $frontendport ` |
| 163 | + -HttpListeners $defaultlistener ` |
| 164 | + -RequestRoutingRules $frontendRule ` |
| 165 | + -Sku $sku ` |
| 166 | + -WebApplicationFirewallConfig $wafConfig |
| 167 | +``` |
| 168 | + |
| 169 | +## Create a virtual machine scale set |
| 170 | + |
| 171 | +In this example, you create a virtual machine scale set to provide servers for the backend pool in the application gateway. You assign the scale set to the backend pool when you configure the IP settings. |
| 172 | + |
| 173 | +```azurepowershell-interactive |
| 174 | +$vnet = Get-AzureRmVirtualNetwork ` |
| 175 | + -ResourceGroupName myResourceGroupAG ` |
| 176 | + -Name myVNet |
| 177 | +
|
| 178 | +$appgw = Get-AzureRmApplicationGateway ` |
| 179 | + -ResourceGroupName myResourceGroupAG ` |
| 180 | + -Name myAppGateway |
| 181 | +
|
| 182 | +$backendPool = Get-AzureRmApplicationGatewayBackendAddressPool ` |
| 183 | + -Name appGatewayBackendPool ` |
| 184 | + -ApplicationGateway $appgw |
| 185 | +
|
| 186 | +$ipConfig = New-AzureRmVmssIpConfig ` |
| 187 | + -Name myVmssIPConfig ` |
| 188 | + -SubnetId $vnet.Subnets[1].Id ` |
| 189 | + -ApplicationGatewayBackendAddressPoolsId $backendPool.Id |
| 190 | +
|
| 191 | +$vmssConfig = New-AzureRmVmssConfig ` |
| 192 | + -Location eastus ` |
| 193 | + -SkuCapacity 2 ` |
| 194 | + -SkuName Standard_DS2 ` |
| 195 | + -UpgradePolicyMode Automatic |
| 196 | +
|
| 197 | +Set-AzureRmVmssStorageProfile $vmssConfig ` |
| 198 | + -ImageReferencePublisher MicrosoftWindowsServer ` |
| 199 | + -ImageReferenceOffer WindowsServer ` |
| 200 | + -ImageReferenceSku 2016-Datacenter ` |
| 201 | + -ImageReferenceVersion latest |
| 202 | +
|
| 203 | +Set-AzureRmVmssOsProfile $vmssConfig ` |
| 204 | + -AdminUsername azureuser ` |
| 205 | + -AdminPassword "Azure123456!" ` |
| 206 | + -ComputerNamePrefix myvmss |
| 207 | +
|
| 208 | +Add-AzureRmVmssNetworkInterfaceConfiguration ` |
| 209 | + -VirtualMachineScaleSet $vmssConfig ` |
| 210 | + -Name myVmssNetConfig ` |
| 211 | + -Primary $true ` |
| 212 | + -IPConfiguration $ipConfig |
| 213 | +
|
| 214 | +New-AzureRmVmss ` |
| 215 | + -ResourceGroupName myResourceGroupAG ` |
| 216 | + -Name myvmss ` |
| 217 | + -VirtualMachineScaleSet $vmssConfig |
| 218 | +``` |
| 219 | + |
| 220 | +### Install IIS |
| 221 | + |
| 222 | +```azurepowershell-interactive |
| 223 | +$publicSettings = @{ "fileUris" = (,"https://raw.githubusercontent.com/davidmu1/samplescripts/master/appgatewayurl.ps1"); |
| 224 | + "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File appgatewayurl.ps1" } |
| 225 | +
|
| 226 | +$vmss = Get-AzureRmVmss -ResourceGroupName myResourceGroupAG -VMScaleSetName myvmss |
| 227 | +
|
| 228 | +Add-AzureRmVmssExtension -VirtualMachineScaleSet $vmss ` |
| 229 | + -Name "customScript" ` |
| 230 | + -Publisher "Microsoft.Compute" ` |
| 231 | + -Type "CustomScriptExtension" ` |
| 232 | + -TypeHandlerVersion 1.8 ` |
| 233 | + -Setting $publicSettings |
| 234 | +
|
| 235 | +Update-AzureRmVmss ` |
| 236 | + -ResourceGroupName myResourceGroupAG ` |
| 237 | + -Name myvmss ` |
| 238 | + -VirtualMachineScaleSet $vmss |
| 239 | +``` |
| 240 | + |
| 241 | +## Create a storage account and configure diagnostics |
| 242 | + |
| 243 | +In this tutorial, the application gateway uses a storage account to store data for detection and prevention purposes. You could also use Log Analytics or Event Hub to record data. |
| 244 | + |
| 245 | +### Create the storage account |
| 246 | + |
| 247 | +Create a storage account named *myagstore1* using [New-AzureRmStorageAccount](/powershell/module/azurerm.storage/new-azurermstorageaccount). |
| 248 | + |
| 249 | +```azurepowershell-interactive |
| 250 | +$storageAccount = New-AzureRmStorageAccount ` |
| 251 | + -ResourceGroupName myResourceGroupAG ` |
| 252 | + -Name myagstore1 ` |
| 253 | + -Location eastus ` |
| 254 | + -SkuName "Standard_LRS" |
| 255 | +``` |
| 256 | + |
| 257 | +### Configure diagnostics |
| 258 | + |
| 259 | +Configure diagnostics to record data into the ApplicationGatewayAccessLog, ApplicationGatewayPerformanceLog, and ApplicationGatewayFirewallLog logs using [Set-AzureRmDiagnosticSetting](/powershell/module/azurerm.insights/set-azurermdiagnosticsetting). |
| 260 | + |
| 261 | +```azurepowershell-interactive |
| 262 | +$appgw = Get-AzureRmApplicationGateway ` |
| 263 | + -ResourceGroupName myResourceGroupAG ` |
| 264 | + -Name myAppGateway |
| 265 | +
|
| 266 | +$store = Get-AzureRmStorageAccount ` |
| 267 | + -ResourceGroupName myResourceGroupAG ` |
| 268 | + -Name myagstore1 |
| 269 | +
|
| 270 | +Set-AzureRmDiagnosticSetting ` |
| 271 | + -ResourceId $appgw.Id ` |
| 272 | + -StorageAccountId $store.Id ` |
| 273 | + -Categories ApplicationGatewayAccessLog, ApplicationGatewayPerformanceLog, ApplicationGatewayFirewallLog ` |
| 274 | + -Enabled $true ` |
| 275 | + -RetentionEnabled $true ` |
| 276 | + -RetentionInDays 30 |
| 277 | +``` |
| 278 | + |
| 279 | +## Test the application gateway |
| 280 | + |
| 281 | +You can use [Get-AzureRmPublicIPAddress](/powershell/module/azurerm.network/get-azurermpublicipaddress) to get the public IP address of the application gateway. Copy the public IP address, and then paste it into the address bar of your browser. |
| 282 | + |
| 283 | +```azurepowershell-interactive |
| 284 | +Get-AzureRmPublicIPAddress -ResourceGroupName myResourceGroupAG -Name myAGPublicIPAddress |
| 285 | +``` |
| 286 | + |
| 287 | + |
| 288 | + |
| 289 | +## Clean up resources |
| 290 | + |
| 291 | +When no longer needed, remove the resource group, application gateway, and all related resources using [Remove-AzureRmResourceGroup](/powershell/module/azurerm.resources/remove-azurermresourcegroup). |
| 292 | + |
| 293 | +```azurepowershell-interactive |
| 294 | +Remove-AzureRmResourceGroup -Name myResourceGroupAG |
| 295 | +``` |
| 296 | + |
| 297 | +## Next steps |
| 298 | + |
| 299 | +In this tutorial, you learned how to: |
| 300 | + |
| 301 | +> [!div class="checklist"] |
| 302 | +> * Set up the network |
| 303 | +> * Create an application gateway with WAF enabled |
| 304 | +> * Create a virtual machine scale set |
| 305 | +> * Create a storage account and configure diagnostics |
| 306 | +
|
| 307 | +> [!div class="nextstepaction"] |
| 308 | +> [Create an application gateway with SSL termination](./tutorial-ssl-powershell.md) |
0 commit comments