From 6135b230a81f8fde33fe299cf8d9fc06e1516ea0 Mon Sep 17 00:00:00 2001 From: Gordon Byers Date: Mon, 20 Sep 2021 12:21:10 +0100 Subject: [PATCH] Adding OWASP firewall configuration (#55) * Added appGW firewall param * Adding auto compiled bicep json * coped with standardv2 and waf combo * Adding auto compiled bicep json Co-authored-by: Gordon Byers Co-authored-by: Gordonby --- bicep/compiled/main.json | 26 +++++++++++++++++++++++--- bicep/main.bicep | 19 ++++++++++++++++++- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/bicep/compiled/main.json b/bicep/compiled/main.json index eb4d79148..6cbbfa305 100644 --- a/bicep/compiled/main.json +++ b/bicep/compiled/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.4.613.9944", - "templateHash": "15689473077999260665" + "templateHash": "17287026184570139123" } }, "parameters": { @@ -103,7 +103,18 @@ }, "appGWsku": { "type": "string", - "defaultValue": "WAF_v2" + "defaultValue": "WAF_v2", + "metadata": { + "description": "The SKU for AppGw" + }, + "allowedValues": [ + "Standard_v2", + "WAF_v2" + ] + }, + "appGWenableFirewall": { + "type": "bool", + "defaultValue": true }, "dnsPrefix": { "type": "string", @@ -239,6 +250,7 @@ "acrName": "[format('cr{0}{1}', replace(parameters('resourceName'), '-', ''), uniqueString(resourceGroup().id, parameters('resourceName')))]", "AcrPullRole": "[resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')]", "deployAppGw": "[and(parameters('ingressApplicationGateway'), or(parameters('custom_vnet'), not(empty(parameters('byoAGWSubnetId')))))]", + "appGWenableWafFirewall": "[if(equals(parameters('appGWsku'), 'Standard_v2'), false(), parameters('appGWenableFirewall'))]", "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', variables('aks_law_name'))]", "appgwName": "[format('agw-{0}', parameters('resourceName'))]", "appgwResourceId": "[if(variables('deployAppGw'), resourceId('Microsoft.Network/applicationGateways', variables('appgwName')), '')]", @@ -250,6 +262,14 @@ }, "name": "appGatewayFrontendIP" }, + "appGwFirewallConfigOwasp": { + "enabled": "[variables('appGWenableWafFirewall')]", + "firewallMode": "Prevention", + "ruleSetType": "OWASP", + "ruleSetVersion": "3.2", + "requestBodyCheck": true, + "maxRequestBodySizeInKb": 128 + }, "appGWskuObj": "[union(createObject('name', parameters('appGWsku'), 'tier', parameters('appGWsku')), if(equals(parameters('appGWmaxCount'), 0), createObject('capacity', parameters('appGWcount')), createObject()))]", "DEPLOY_APPGW_ADDON": "[and(parameters('ingressApplicationGateway'), empty(parameters('byoAGWSubnetId')))]", "contributor": "[resourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]", @@ -385,7 +405,7 @@ "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('id-appgw-{0}', parameters('resourceName')))]": {} } }, - "properties": "[union(createObject('sku', variables('appGWskuObj'), 'sslPolicy', createObject('policyType', 'Predefined', 'policyName', 'AppGwSslPolicy20170401S'), 'gatewayIPConfigurations', createArray(createObject('name', 'besubnet', 'properties', createObject('subnet', createObject('id', if(parameters('ingressApplicationGateway'), if(parameters('custom_vnet'), reference(resourceId('Microsoft.Resources/deployments', 'network'), '2019-10-01').outputs.appGwSubnetId.value, parameters('byoAGWSubnetId')), ''))))), 'frontendIPConfigurations', if(empty(parameters('privateIpApplicationGateway')), array(variables('frontendPublicIpConfig')), concat(array(variables('frontendPublicIpConfig')), array(createObject('properties', createObject('privateIPAllocationMethod', 'Static', 'privateIPAddress', parameters('privateIpApplicationGateway'), 'subnet', createObject('id', if(parameters('ingressApplicationGateway'), if(parameters('custom_vnet'), reference(resourceId('Microsoft.Resources/deployments', 'network'), '2019-10-01').outputs.appGwSubnetId.value, parameters('byoAGWSubnetId')), ''))), 'name', 'appGatewayPrivateIP')))), 'frontendPorts', createArray(createObject('name', 'appGatewayFrontendPort', 'properties', createObject('port', 80))), 'backendAddressPools', createArray(createObject('name', 'defaultaddresspool')), 'backendHttpSettingsCollection', createArray(createObject('name', 'defaulthttpsetting', 'properties', createObject('port', 80, 'protocol', 'Http', 'cookieBasedAffinity', 'Disabled', 'requestTimeout', 30, 'pickHostNameFromBackendAddress', true()))), 'httpListeners', createArray(createObject('name', 'hlisten', 'properties', createObject('frontendIPConfiguration', createObject('id', if(empty(parameters('privateIpApplicationGateway')), format('{0}/frontendIPConfigurations/appGatewayFrontendIP', variables('appgwResourceId')), format('{0}/frontendIPConfigurations/appGatewayPrivateIP', variables('appgwResourceId')))), 'frontendPort', createObject('id', format('{0}/frontendPorts/appGatewayFrontendPort', variables('appgwResourceId'))), 'protocol', 'Http'))), 'requestRoutingRules', createArray(createObject('name', 'appGwRoutingRuleName', 'properties', createObject('ruleType', 'Basic', 'httpListener', createObject('id', format('{0}/httpListeners/hlisten', variables('appgwResourceId'))), 'backendAddressPool', createObject('id', format('{0}/backendAddressPools/defaultaddresspool', variables('appgwResourceId'))), 'backendHttpSettings', createObject('id', format('{0}/backendHttpSettingsCollection/defaulthttpsetting', variables('appgwResourceId'))))))), if(greater(parameters('appGWmaxCount'), 0), createObject('autoscaleConfiguration', createObject('minCapacity', parameters('appGWcount'), 'maxCapacity', parameters('appGWmaxCount'))), createObject()))]", + "properties": "[union(createObject('sku', variables('appGWskuObj'), 'sslPolicy', createObject('policyType', 'Predefined', 'policyName', 'AppGwSslPolicy20170401S'), 'webApplicationFirewallConfiguration', if(variables('appGWenableWafFirewall'), variables('appGwFirewallConfigOwasp'), json('null')), 'gatewayIPConfigurations', createArray(createObject('name', 'besubnet', 'properties', createObject('subnet', createObject('id', if(parameters('ingressApplicationGateway'), if(parameters('custom_vnet'), reference(resourceId('Microsoft.Resources/deployments', 'network'), '2019-10-01').outputs.appGwSubnetId.value, parameters('byoAGWSubnetId')), ''))))), 'frontendIPConfigurations', if(empty(parameters('privateIpApplicationGateway')), array(variables('frontendPublicIpConfig')), concat(array(variables('frontendPublicIpConfig')), array(createObject('properties', createObject('privateIPAllocationMethod', 'Static', 'privateIPAddress', parameters('privateIpApplicationGateway'), 'subnet', createObject('id', if(parameters('ingressApplicationGateway'), if(parameters('custom_vnet'), reference(resourceId('Microsoft.Resources/deployments', 'network'), '2019-10-01').outputs.appGwSubnetId.value, parameters('byoAGWSubnetId')), ''))), 'name', 'appGatewayPrivateIP')))), 'frontendPorts', createArray(createObject('name', 'appGatewayFrontendPort', 'properties', createObject('port', 80))), 'backendAddressPools', createArray(createObject('name', 'defaultaddresspool')), 'backendHttpSettingsCollection', createArray(createObject('name', 'defaulthttpsetting', 'properties', createObject('port', 80, 'protocol', 'Http', 'cookieBasedAffinity', 'Disabled', 'requestTimeout', 30, 'pickHostNameFromBackendAddress', true()))), 'httpListeners', createArray(createObject('name', 'hlisten', 'properties', createObject('frontendIPConfiguration', createObject('id', if(empty(parameters('privateIpApplicationGateway')), format('{0}/frontendIPConfigurations/appGatewayFrontendIP', variables('appgwResourceId')), format('{0}/frontendIPConfigurations/appGatewayPrivateIP', variables('appgwResourceId')))), 'frontendPort', createObject('id', format('{0}/frontendPorts/appGatewayFrontendPort', variables('appgwResourceId'))), 'protocol', 'Http'))), 'requestRoutingRules', createArray(createObject('name', 'appGwRoutingRuleName', 'properties', createObject('ruleType', 'Basic', 'httpListener', createObject('id', format('{0}/httpListeners/hlisten', variables('appgwResourceId'))), 'backendAddressPool', createObject('id', format('{0}/backendAddressPools/defaultaddresspool', variables('appgwResourceId'))), 'backendHttpSettings', createObject('id', format('{0}/backendHttpSettingsCollection/defaulthttpsetting', variables('appgwResourceId'))))))), if(greater(parameters('appGWmaxCount'), 0), createObject('autoscaleConfiguration', createObject('minCapacity', parameters('appGWcount'), 'maxCapacity', parameters('appGWmaxCount'))), createObject()))]", "dependsOn": [ "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', format('id-appgw-{0}', parameters('resourceName')))]", "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-agw-{0}', parameters('resourceName')))]", diff --git a/bicep/main.bicep b/bicep/main.bicep index bd24076d2..5437c5736 100644 --- a/bicep/main.bicep +++ b/bicep/main.bicep @@ -237,10 +237,17 @@ param appGWcount int = 2 param appGWmaxCount int = 0 param privateIpApplicationGateway string = '' param appgwKVIntegration bool = false -param appGWsku string = 'WAF_v2' +@allowed([ + 'Standard_v2' + 'WAF_v2' +]) +@description('The SKU for AppGw') +param appGWsku string = 'WAF_v2' +param appGWenableFirewall bool = true var deployAppGw = ingressApplicationGateway && (custom_vnet || !empty(byoAGWSubnetId)) +var appGWenableWafFirewall = appGWsku=='Standard_v2' ? false : appGWenableFirewall // If integrating App Gateway with KeyVault, create a Identity App Gateway will use to access keyvault // 'identity' is always created (adding: "|| deployAppGw") until this is fixed: @@ -286,6 +293,15 @@ var frontendPrivateIpConfig = { name: 'appGatewayPrivateIP' } +var appGwFirewallConfigOwasp = { + enabled: appGWenableWafFirewall + firewallMode: 'Prevention' + ruleSetType: 'OWASP' + ruleSetVersion: '3.2' + requestBodyCheck: true + maxRequestBodySizeInKb: 128 +} + var appGWskuObj = union({ name: appGWsku tier: appGWsku @@ -300,6 +316,7 @@ var appgwProperties = union({ policyType: 'Predefined' policyName: 'AppGwSslPolicy20170401S' } + webApplicationFirewallConfiguration: appGWenableWafFirewall ? appGwFirewallConfigOwasp : json('null') gatewayIPConfigurations: [ { name: 'besubnet'