Partager via


Démarrage rapide : Créer un Azure Web Application Firewall v2 à l’aide d’un modèle ARM

Dans ce guide de démarrage rapide, vous utilisez un modèle Azure Resource Manager (modèle ARM) pour créer un Azure Web Application Firewall (WAF) v2 sur Azure Application Gateway.

Un modèle Azure Resource Manager est un fichier JSON (JavaScript Object Notation) qui définit l’infrastructure et la configuration de votre projet. Le modèle utilise la syntaxe déclarative. Vous décrivez votre déploiement prévu sans écrire la séquence de commandes de programmation pour créer le déploiement.

Remarque

Nous vous recommandons d’utiliser le module Azure Az PowerShell pour interagir avec Azure. Pour bien démarrer, consultez Installer Azure PowerShell. Pour savoir comment migrer vers le module Az PowerShell, consultez Migrer Azure PowerShell depuis AzureRM vers Az.

Si votre environnement remplit les conditions préalables et que vous êtes habitué à utiliser les modèles ARM, vous pouvez sélectionner le bouton Déployer sur Azure pour ouvrir le modèle dans le portail Azure.

Bouton pour déployer le modèle Resource Manager sur Azure.

Prérequis

  • Compte Azure avec un abonnement actif. Si vous n’en avez pas, vous pouvez créer un compte gratuitement.

Vérifier le modèle

Ce modèle crée un pare-feu d’applications web v2 simple sur Azure Application Gateway. Ce modèle crée l’adresse IP d’un front-end d’adresses IP publiques, des paramètres HTTP, une règle avec un écouteur de base sur le port 80 et un pool back-end. Une stratégie WAF avec une règle personnalisée bloque le trafic vers le pool back-end en fonction d’un type de correspondance d’adresse IP.

Le modèle définit les ressources Azure suivantes :

Le modèle provient des modèles de démarrage rapide 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"
      ]
    }
  ]
}

Déployer le modèle

Déployez le modèle ARM sur Azure :

  1. Sélectionnez Déployer sur Azure pour vous connecter à Azure et ouvrir le modèle. Le modèle crée une passerelle d’application, l’infrastructure réseau et deux machines virtuelles dans le pool de back-ends exécutant IIS.

    Bouton pour déployer le modèle Resource Manager sur Azure.

  2. Sélectionnez ou créez un groupe de ressources.

  3. Sélectionnez Vérifier + créer, puis quand la validation réussit, sélectionnez Créer. Le déploiement peut prendre 10 minutes ou plus.

Valider le déploiement

Même si IIS n’est pas obligatoire, le modèle installe IIS sur les serveurs principaux afin de pouvoir vérifier qu’Azure a créé un WAF v2 sur la passerelle d’application.

Utilisez IIS pour tester la passerelle d’application :

  1. Copiez l’adresse IP publique de la passerelle d’application depuis sa page Vue d’ensemble.

    Capture d’écran montrant l’adresse IP publique de la passerelle d’application.

    Vous pouvez également rechercher les passerelles d’application dans la zone de recherche Azure. La liste des passerelles d’application affiche les adresses IP publiques dans la colonne Adresses IP publiques.

  2. Collez l’adresse IP dans la barre d’adresse de votre navigateur pour parcourir cette adresse.

  3. Vérifiez la réponse. Une réponse 403 Interdit vérifie que le pare-feu d’applications web (WAF) bloque bien les connexions au pool back-end.

  4. Pour modifier la règle personnalisée pour autoriser le trafic, exécutez le script Azure PowerShell suivant, en remplaçant le nom de votre groupe de ressources :

    $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
    
  5. Actualisez votre navigateur plusieurs fois. Vous devriez voir des connexions à la fois à myVM1 et à myVM2.

Nettoyer les ressources

Lorsque vous n’avez plus besoin des ressources que vous avez créées dans ce guide de démarrage rapide, supprimez le groupe de ressources pour supprimer la passerelle d’application et toutes ses ressources associées.

Pour supprimer le groupe de ressources, appelez l’applet de commande Remove-AzResourceGroup :

Remove-AzResourceGroup -Name "<your resource group name>"

Étapes suivantes