Demystify Azure DDoS Protection Azure Policy

There are two different policies in Azure Security Center/Azure Policy scan virtual network resources and DDoS protection plan. Your virtual network resources may fall into the list of non-compliant resources in one of these policies. In this article, let’s demystify the two policies and remediate or justify them in case you are asked by a compliance guy.

Virtual networks should be protected by Azure DDoS Protection Standard

This policy is very straightforward. It simply scans all Azure virtual networks in the assignment scope and read the following fields:

  • Microsoft.Network/virtualNetworks/enableDdosProtection
  • Microsoft.Network/virtualNetworks/ddosProtectionPlan.id

There are two different actions that this built-in policy does: Audit and Modify (remediation) For the audit part, it checks the boolean value (True or False) of enableDdosProtection field. It also verifies whether the value of ddosProtectionPlan.id is empty.

"allOf": [
    {
      "field": "type",
      "equals": "Microsoft.Network/virtualNetworks"
    },
    {
      "anyOf": [
        {
          "field": "Microsoft.Network/virtualNetworks/enableDdosProtection",
          "notEquals": true
        },
        {
          "field": "Microsoft.Network/virtualNetworks/ddosProtectionPlan",
          "equals": ""
        }
      ]
    }
  ]
}

For the remediation part, it automatically sets the value of enableDdosProtection to True as well as associates scanned non-compliant virtual networks with an existing Azure DDoS protection plan.

"operations": [
    {
      "operation": "addOrReplace",
      "field": "Microsoft.Network/virtualNetworks/enableDdosProtection",
      "value": true
    },
    {
      "operation": "addOrReplace",
      "field": "Microsoft.Network/virtualNetworks/ddosProtectionPlan.id",
      "value": "[parameters('ddosPlan')]"
    }
  ]
}

Sometimes you have your own plan so you don’t want Azure Policy to automatically remediate your virtual network. In that case, if you would like to audit only, you must modify the policy to remove the remediation part. Below is the sample audit-only policy:

{
  "mode": "Indexed",
  "parameters": {
    "effect": {
      "type": "String",
      "metadata": {
        "displayName": "Effect",
        "description": "Enable or disable the execution of the policy"
      },
      "allowedValues": ["Audit", "Disabled"],
      "defaultValue": "Audit"
    }
  },
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "type",
          "equals": "Microsoft.Network/virtualNetworks"
        },
        {
          "anyOf": [
            {
              "field": "Microsoft.Network/virtualNetworks/enableDdosProtection",
              "notEquals": true
            },
            {
              "field": "Microsoft.Network/virtualNetworks/ddosProtectionPlan",
              "equals": ""
            }
          ]
        }
      ]
    },
    "then": {
      "effect": "[parameters('effect')]"
    }
  }
}

To test this Azure Policy, you can create a new dedicated resource group and assign the policy to it. To test this policy, you can use the following sample ARM template:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "baseName": {
      "type": "string",
      "defaultValue": "azsec",
      "metadata": {
        "description": "Basename of resource deployment"
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Location of the virtual network"
      }
    },
    "enableDdosProtection": {
      "type": "bool",
      "defaultValue": false,
      "metadata": {
        "description": "Indicate whether you want to enable DDos Protection"
      }
    }
  },
  "variables": {
    "vnetName": "[if(parameters('enableDdosProtection'), concat(parameters('baseName'),'-vnet-with-ddos'), concat(parameters('baseName'), '-vnet-no-ddos'))]",
    "subnetName": "[concat(variables('vnetName'), 'subnet')]",
    "vnetAddressPrefix": "172.17.0.0/16",
    "subnetAddressPrefix": "172.17.0.0/24",
    "ddosProtectionPlanName": "[concat(parameters('baseName'),'ddos-plan')]",
    "ddosProtection": {
        "id": "[resourceId('Microsoft.Network/ddosProtectionPlans', variables('ddosProtectionPlanName'))]"
    }
  },
  "resources": [
    {
      "condition": "[parameters('enableDdosProtection')]",
      "type": "Microsoft.Network/ddosProtectionPlans",
      "apiVersion": "2020-11-01",
      "name": "[variables('ddosProtectionPlanName')]",
      "location": "[parameters('location')]"
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2020-11-01",
      "name": "[variables('vnetName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Network/ddosProtectionPlans', variables('ddosProtectionPlanName'))]"
      ],
      "properties": {
        "addressSpace": {
          "addressPrefixes": ["[variables('vnetAddressPrefix')]"]
        },
        "subnets": [
          {
            "name": "[variables('subnetName')]",
            "properties": {
              "addressPrefix": "[variables('subnetAddressPrefix')]"
            }
          }
        ],
        "enableDdosProtection": "[parameters('enableDdosProtection')]",
        "ddosProtectionPlan": "[if(parameters('enableDdosProtection'), variables('ddosProtection'),json('null'))]"
      }
    }
  ],
  "outputs": {
      "resourceId": {
          "type": "string",
          "value": "[resourceId('Microsoft.Network/virtualNetworks',variables('vnetName'))]"
      }
  }
}

All you need is to modify enableDdosProtection . After you assign policy, wait 15-30 minutes and check the compliance result from Azure Portal. If you don’t want to wait, you can manually trigger policy evaluation by the following command:

Start-AzPolicyComplianceScan -ResourceGroupName 'azsec-ddos-policy-rg'

Azure DDoS Protection Standard should be enabled

The name of the policy sounds similar to the first one. Although what it does is verify Azure DDoS Protection Plan, its target resource type is different. The policy doesn’t only scan Microsoft.network/virtualNetworks¬†but also Microsoft.network/virtualNetworks/subnets,Microsoft.Network applicationGateways and microsoft.network/publicipaddresses. This statement was based on my experience and evaluation. The policy doesn’t tell you what it does:

"policyRule": {
    "if": {
      "field": "type",
      "equals": "microsoft.network/virtualNetworks"
    },
    "then": {
      "effect": "[parameters('effect')]",
      "details": {
        "type": "Microsoft.Security/assessments",
        "name": "e3de1cc0-f4dd-3b34-e496-8b5381ba2d70",
        "existenceCondition": {
          "field": "Microsoft.Security/assessments/status.code",
          "in": ["NotApplicable", "Healthy"]
        }
      }
    }
  }
}

Here is what the policy is saying – DDoS protection standard should be enabled for all virtual networks with a subnet that is part of an application gateway with a public IP. To deploy an environment for this policy, you can use this template to deploy a virtual machine with a public IP address and configure the application gateway’s frontend. Wait 15-30 minutes for Azure Security Center to perform an assessment. To see how Azure Security Center clasifiies its assesmsent for DDoS protection you can use Resource Graph Explorer to query:

securityresources
| where type == "microsoft.security/assessments"
| extend assessmentKey = tostring(name)
| extend reason = tostring(properties.status.cause)
| where assessmentKey == "e3de1cc0-f4dd-3b34-e496-8b5381ba2d70"
| where resourceGroup == "azsec-ddos-policy-rg"
| project id, reason

You can exclude resource group to check all resources. You will notice that Azure Security Center will mark VnetHasNoAppGateways for virtual network it can’t find an application gateway.

{
    "policyInitiativeName": "ASC Default",
    "policyInitiativeId": "1f3afdf9-d0c9-4c3d-847f-89da613e70a8",
    "assessmentStatus": {
        "description": "There are no Application Gateway resources attached to this Virtual Network",
        firstEvaluationDate": "2021-03-14T00:00:00.0000000Z",
        "statusChangeDate": "2021-03-14T00:00:00.0000000Z",
        "code": "NotApplicable",
        "cause": "VnetHasNoAppGateways"
    }
}

You can manually check non-applicable resources to see whether they have application gateway resource attached.

Conclusion

Understanding these policies will help you deal with compliance people who ask you to make your environment aligned with compliance. Moreover, in case you are asked for a justification you know what you are going to say, as well as how to test. Good luck!

This entry was posted in Governance & Compliance and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *