Desplegar un Azure Application Gateway con escucha de paso directo de mTLS

En este inicio rápido se muestra cómo implementar un Azure Application Gateway con mutual TLS (mTLS) passthrough mediante una plantilla de Azure Resource Manager (plantilla de ARM) y una versión de API 2025-03-01. En modo passthrough, la puerta de enlace solicita un certificado de cliente, pero no lo valida. La validación de certificados y la aplicación de directivas se producen en el back-end.

Características clave

  • Asocie un perfil SSL al agente de escucha para el acceso directo de mTLS.
  • No se requiere ningún certificado CA de cliente en la puerta de enlace.
  • La propiedad verifyClientAuthMode admite valores Strict y Passthrough.
  • Soporte de Portal: puede configurar el passthrough de mTLS directamente en el portal de Azure.

Nota:

La compatibilidad de PowerShell y la CLI con la configuración de paso a través no está disponible actualmente. Puede configurar el acceso directo de mTLS mediante el portal de Azure o las plantillas de ARM.

Configurar el paso directo de mTLS mediante el portal de Azure

Puede configurar el paso directo de mTLS en el portal de Azure mediante la creación de un perfil SSL con el método de autenticación de cliente Passthrough:

  1. Vaya al recurso de Application Gateway en el portal de Azure.

  2. En Configuración, seleccione Perfiles SSL.

  3. Seleccione + Agregar para crear un nuevo perfil SSL.

  4. Escriba un nombre para el perfil SSL.

  5. En la pestaña Autenticación de cliente , seleccione Paso a través.

    En el modo de paso a través, el certificado de cliente es opcional y el servidor back-end es responsable de la autenticación de cliente.

Screenshot que muestra el cuadro de diálogo Crear perfil SSL en el portal de Azure con Passthrough seleccionado para el método de autenticación de cliente.

  1. Configure las opciones de directiva SSL según sea necesario.
  2. Seleccione Agregar para crear el perfil SSL.
  3. Asocie el perfil SSL al agente de escucha HTTPS.

Prerrequisitos

  • Una suscripción y un grupo de recursos de Azure
  • CLI de Azure instalado localmente.
  • Un certificado SSL (PFX codificado en Base64) y una contraseña.
  • Una clave SSH para el administrador de máquinas virtuales Linux (si procede).
  • Versión 2025-03-01 de la API o posterior para la propiedad de paso directo.

Despliegue de Application Gateway con listener de paso directo de mTLS

Esta plantilla crea los siguientes recursos:

  • Una red virtual con dos subredes (una delegada en Application Gateway).
  • Una dirección IP pública para el front-end de puerta de enlace.
  • Una instancia de Application Gateway (Standard_v2) con:
    • Certificado SSL y perfil SSL para el paso a través del certificado de cliente.
    • Agente de escucha HTTPS y regla de enrutamiento.
    • Grupo de backend que apunta a un servicio de aplicaciones.

Actualice la plantilla con los detalles de configuración e incluya un certificado SSL válido.

Archivo de parámetros: 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>"
        }
    }
}

Archivo de plantilla: 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'))]"
            ]
        }
    ]
}

Implementación de la plantilla

Ejecute el siguiente comando CLI de Azure para implementar la plantilla:

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

Validación y prueba

Validación de la implementación

  1. En el portal de Azure, navega a tu recurso de Application Gateway.

  2. Seleccione Vista JSON y versión de API 2025-03-01.

  3. Compruebe que verifyClientAuthMode está establecido como Passthrough en el perfil 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>"
                    }
                ]
            }
        }
    ]
    

Envío de un certificado de cliente al back-end

Si necesita reenviar el certificado de cliente al back-end, configure una regla de reescritura. Para más información, consulte Reescritura de encabezados HTTP y dirección URL con Application Gateway.

Cuando el cliente envía un certificado, esta reescritura garantiza que el certificado de cliente se incluya en los encabezados de solicitud para el procesamiento de back-end.

Comprobación de la conectividad

Compruebe que las conexiones se establecen incluso cuando no se proporciona un certificado de cliente.

Parámetros de paso a través de mTLS

En la tabla siguiente se describen los parámetros para la configuración de paso a través de mTLS:

Nombre Tipo Description
verifyClientCertIssuerDN Boolean Especifica si se debe comprobar el nombre del emisor del certificado de cliente en la puerta de enlace.
verifyClientRevocation String Especifica el modo de comprobación de revocación de certificados de cliente.
verifyClientAuthMode String Especifica el modo de certificado de cliente. Los valores válidos son Strict y Passthrough.

Modo de paso a través: La puerta de enlace solicita un certificado de cliente, pero no lo aplica. El back-end valida el certificado y aplica la directiva.

Consideraciones de seguridad

Siga los procedimientos recomendados de seguridad y control de datos de su organización al implementar y administrar esta solución.