Déployer une passerelle d'application Azure avec écouteur de transfert mTLS

Ce guide de démarrage rapide vous montre comment déployer un Azure Application Gateway avec mutual TLS (mTLS) passthrough à l’aide d’un modèle Azure Resource Manager (modèle ARM) et d’une version d’API 2025-03-01. En mode passthrough, la passerelle demande un certificat client, mais ne la valide pas. La validation des certificats et l’application des stratégies se produisent sur le serveur principal.

Fonctionnalités clés

  • Associez un profil SSL au listener pour la transmission mTLS.
  • Aucun certificat d’autorité de certification client n’est requis sur la passerelle.
  • La propriété verifyClientAuthMode prend en charge les valeurs Strict et Passthrough.
  • Support du portail : vous pouvez configurer la transmission mTLS directement dans le portail Azure.

Note

La prise en charge de PowerShell et de l’interface CLI pour la configuration directe n’est actuellement pas disponible. Vous pouvez configurer la passthrough mTLS à l’aide du portail Azure ou des modèles ARM.

Configurer la passe directe mTLS à l’aide du portail Azure

Vous pouvez configurer le passage mTLS directement dans le portail Azure en créant un profil SSL avec la méthode d’authentification client Passthrough :

  1. Accédez à votre ressource Application Gateway dans le portail Azure.

  2. Sous Paramètres, sélectionnez profils SSL.

  3. Sélectionnez + Ajouter pour créer un profil SSL.

  4. Entrez un nom pour votre profil SSL.

  5. Sous l’onglet Authentification du client , sélectionnez Passthrough.

    En mode passthrough, le certificat client est facultatif et le serveur principal est responsable de l’authentification du client.

Screenshot montrant la boîte de dialogue Créer un profil SSL dans Azure portail avec passthrough sélectionné pour la méthode d’authentification client.

  1. Configurez les paramètres de stratégie SSL en fonction des besoins.
  2. Sélectionnez Ajouter pour créer le profil SSL.
  3. Associez le profil SSL à votre écouteur HTTPS.

Prerequisites

  • Un abonnement Azure et un groupe de ressources.
  • Azure CLI installé localement.
  • Un certificat SSL (PFX codé en base64) et un mot de passe.
  • Clé SSH pour l’administrateur de machine virtuelle Linux (le cas échéant).
  • Version 2025-03-01 de l’API ou ultérieure pour la propriété de transmission.

Déploiement d'une passerelle d'application avec écouteur de transfert mTLS

Ce modèle crée les ressources suivantes :

  • Un réseau virtuel avec deux sous-réseaux (un délégué à Application Gateway).
  • Adresse IP publique pour le serveur frontal de passerelle.
  • Passerelle d'application (Standard_v2) avec :
    • Certificat SSL et profil SSL pour le transfert du certificat client.
    • Règle d’écouteur et de routage HTTPS.
    • Pool principal pointant vers un service d’application.

Mettez à jour le modèle avec les détails de votre configuration et incluez un certificat SSL valide.

Fichier de paramètres : deploymentParameters.json

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "addressPrefix": {
            "value": "10.0.0.0/16"
        },
        "subnetPrefix": {
            "value": "10.0.0.0/24"
        },
        "skuName": {
            "value": "Standard_v2"
        },
        "capacity": {
            "value": 2
        },
        "adminUsername": {
            "value": "ubuntu"
        },
        "adminSSHKey": {
            "value": "<your-ssh-public-key>"
        },
        "certData": {
            "value": "<Base64-encoded-PFX-data>"
        },
        "certPassword": {
            "value": "<certificate-password>"
        }
    }
}

Fichier de modèle : deploymentTemplate.json

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "addressPrefix": {
            "defaultValue": "10.0.0.0/16",
            "type": "String",
            "metadata": {
                "description": "Address prefix for the Virtual Network"
            }
        },
        "subnetPrefix": {
            "defaultValue": "10.0.0.0/24",
            "type": "String",
            "metadata": {
                "description": "Subnet prefix"
            }
        },
        "skuName": {
            "defaultValue": "Standard_Medium",
            "type": "String",
            "metadata": {
                "description": "Sku Name"
            }
        },
        "capacity": {
            "defaultValue": 2,
            "type": "Int",
            "metadata": {
                "description": "Number of instances"
            }
        },
        "adminUsername": {
            "type": "String"
        },
		"adminSSHKey": {
            "type": "securestring"
        },
        "certData": {
            "type": "String",
            "metadata": {
                "description": "ssl cert data"
            }
        },
        "certPassword": {
            "type": "SecureString",
            "metadata": {
                "description": "ssl cert password"
            }
        }
    },
    "variables": {
        "applicationGatewayName": "mtlsAppGw",
        "idName": "identity",
        "publicIPAddressName": "mtlsPip",
        "virtualNetworkName": "mtlsVnet",
        "subnetName": "appgwsubnet",
        "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]",
        "subnetRef": "[concat(variables('vnetID'),'/subnets/',variables('subnetName'))]",
        "publicIPRef": "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]",
        "applicationGatewayID": "[resourceId('Microsoft.Network/applicationGateways',variables('applicationGatewayName'))]",
        "apiVersion": "2025-03-01",
        "identityID": "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',variables('idName'))]",
        "backendSubnetId": "[concat(variables('vnetID'),'/subnets/backendsubnet')]"
    },
    "resources": [
        {
            "type": "Microsoft.Network/virtualNetworks",
            "name": "[variables('virtualNetworkName')]",
            "apiVersion": "2024-07-01",
            "location": "[resourceGroup().location]",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "[parameters('addressPrefix')]"
                    ]
                },
                "subnets": [
                    {
                        "name": "[variables('subnetName')]",
                        "properties": {
                            "addressPrefix": "[parameters('subnetPrefix')]",
                             "delegations": [
                                {
                                    "name": "Microsoft.Network/applicationGateways",
                                    "properties": {
                                        "serviceName": "Microsoft.Network/applicationGateways"
                                    }
                                }
                            ]
                        }
                    },
                    {
                        "name": "backendSubnet",
                        "properties": {
                            "addressPrefix": "10.0.2.0/24"
                        }
                    }
                ]
            }
        },
        {
            "type": "Microsoft.Network/publicIPAddresses",
            "sku": {
                "name": "Standard"
            },
            "name": "[variables('publicIPAddressName')]",
            "apiVersion": "2024-07-01",
            "location": "[resourceGroup().location]",
            "properties": {
                "publicIPAllocationMethod": "Static"
            }
        },
        {
            "type": "Microsoft.Network/applicationGateways",
            "name": "[variables('applicationGatewayName')]",
            "apiVersion": "[variables('apiVersion')]",
            "location": "[resourceGroup().location]",
            "properties": {
                "sku": {
                    "name": "Standard_v2",
                    "tier": "Standard_v2",
                    "capacity": 3
                },
                "sslCertificates": [
                    {
                        "name": "sslCert",
                        "properties": {
                            "data": "[parameters('certData')]",
                            "password": "[parameters('certPassword')]"
                        }
                    }
                ],
                "sslPolicy": {
                    "policyType": "Predefined",
                    "policyName": "AppGwSslPolicy20220101"
                },
                "sslProfiles": [
                    {
                        "name": "sslnotrustedcert",
                        "id": "[concat(resourceId('Microsoft.Network/applicationGateways',  variables('applicationGatewayName')), '/sslProfiles/sslnotrustedcert')]",
                        "properties": {
                            "clientAuthConfiguration": {
                                "VerifyClientCertIssuerDN": false,
                                "VerifyClientRevocation": "None",
                                "VerifyClientAuthMode": "Passthrough"
                            }
                        }
                    }                   
                ],
                "gatewayIPConfigurations": [
                    {
                        "name": "appGatewayIpConfig",
                        "properties": {
                            "subnet": {
                                "id": "[variables('subnetRef')]"
                            }
                        }
                    }
                ],
                "frontendIPConfigurations": [
                    {
                        "name": "appGatewayFrontendIP",
                        "properties": {
                            "PublicIPAddress": {
                                "id": "[variables('publicIPRef')]"
                            }
                        }
                    }
                ],
                "frontendPorts": [
                    {
                        "name": "port2",
                        "properties": {
                            "Port": 444
                        }
                    }
                ],
                "backendAddressPools": [
                    {
                        "name": "pool2",
                        "properties": {
                            "BackendAddresses": [
							  {
                                "fqdn": "headerappgw-hsa5gjh8fpfebcfd.westus-01.azurewebsites.net"
                              }
							]
                        }
                    }
                ],
                "backendHttpSettingsCollection": [
                    {
                        "name": "settings2",
                        "properties": {
                            "Port": 80,
                            "Protocol": "Http"
                        }
                    }
                ],
                "httpListeners": [
                    {
                        "name": "listener2",
                        "properties": {
                            "FrontendIPConfiguration": {
                                "Id": "[concat(variables('applicationGatewayID'), '/frontendIPConfigurations/appGatewayFrontendIP')]"
                            },
                            "FrontendPort": {
                                "Id": "[concat(variables('applicationGatewayID'), '/frontendPorts/port2')]"
                            },
                            "Protocol": "Https",
                            "SslCertificate": {
                                "Id": "[concat(variables('applicationGatewayID'), '/sslCertificates/sslCert')]"
                            },
                            "sslProfile": {
                                "id": "[concat(variables('applicationGatewayID'), '/sslProfiles/sslnotrustedcert')]"
                            }
                        }
                    }
                ],
                "requestRoutingRules": [
                    {
                        "Name": "rule2",
                        "properties": {
                            "RuleType": "Basic",
                            "priority": 2000,
                            "httpListener": {
                                "id": "[concat(variables('applicationGatewayID'), '/httpListeners/listener2')]"
                            },
                            "backendAddressPool": {
                                "id": "[concat(variables('applicationGatewayID'), '/backendAddressPools/pool2')]"
                            },
                            "backendHttpSettings": {
                                "id": "[concat(variables('applicationGatewayID'), '/backendHttpSettingsCollection/settings2')]"
                            }
                        }
                    }
                ]
            },
            "dependsOn": [
                "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]",
                "[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]"
            ]
        }
    ]
}

Déployer le modèle

Exécutez la commande Azure CLI suivante pour déployer le modèle :

az deployment group create \
  --resource-group <your-resource-group> \
  --template-file deploymentTemplate.json \
  --parameters @deploymentParameters.json

Valider et tester

Valider le déploiement

  1. Dans le Portail Azure accédez à votre ressource Application Gateway.

  2. Sélectionnez l’affichage JSON et sélectionnez la version 2025-03-01de l’API.

  3. Vérifiez que verifyClientAuthMode est réglé sur Passthrough dans le profil SSL :

    "sslProfiles": [
        {
            "name": "sslnotrustedcert",
            "id": "<sample-subscription-id>",
            "etag": "W/\"851e4e20-d2b1-4338-9135-e0beac11aa0e\"",
            "properties": {
                "provisioningState": "Succeeded",
                "clientAuthConfiguration": {
                    "verifyClientCertIssuerDN": false,
                    "verifyClientRevocation": "None",
                    "verifyClientAuthMode": "Passthrough"
                },
                "httpListeners": [
                    {
                        "id": "<sample-subscription-id>"
                    }
                ]
            }
        }
    ]
    

Envoyer un certificat client au back-end

Si vous devez transférer le certificat client au serveur principal, configurez une règle de réécriture. Pour plus d’informations, consultez Réécrire les en-têtes HTTP et l’URL avec Application Gateway.

Lorsque le client envoie un certificat, cette réécriture garantit que le certificat client est inclus dans les en-têtes de requête pour le traitement back-end.

Tester la connectivité

Vérifiez que les connexions sont établies même lorsqu’un certificat client n’est pas fourni.

Paramètres de transmission mTLS

Le tableau suivant décrit les paramètres de configuration de passage mTLS :

Nom Type Descriptif
verifyClientCertIssuerDN Booléen Spécifie s’il faut vérifier le nom de l’émetteur du certificat client sur la passerelle.
verifyClientRevocation Chaîne Spécifie le mode de vérification de révocation de certificat client.
verifyClientAuthMode Chaîne Spécifie le mode de certificat client. Les valeurs valides sont Strict et Passthrough.

Mode passthrough : La passerelle demande un certificat client, mais ne l’applique pas. Le serveur principal valide le certificat et applique la stratégie.

Considérations relatives à la sécurité

Suivez les meilleures pratiques en matière de sécurité et de gestion des données de votre organisation lorsque vous déployez et gérez cette solution.