Compartir a través de


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

En este inicio rápido se muestra cómo implementar una instancia de Azure Application Gateway con un acceso directo de TLS (mTLS) mutuo mediante una plantilla de ARM y una versión 2025-03-01de API. En el modo de paso a través, la puerta de enlace solicita un certificado de cliente, pero no la 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 de CA de cliente en la puerta de enlace.
  • verifyClientAuthMode admite Strict y Passthrough.

Nota:

Actualmente, la compatibilidad con el portal, PowerShell y la CLI para la configuración de paso a través no está disponible. Para este propósito, use plantillas de ARM.

Prerrequisitos

  • Suscripción de Azure y grupo de recursos.
  • La CLI de Azure instalada.
  • Certificado SSL (PFX codificado en Base64) y contraseña.
  • Clave SSH para el administrador de máquinas virtuales Linux (si procede).
  • Versión de API 2025-03-01 para la propiedad de paso directo.

Despliegue de Application Gateway con listener de paso directo de mTLS

Esta plantilla crea:

  • Una red virtual con dos subredes (una delegada en Application Gateway).
  • Una dirección IP pública para el interfaz del gateway.
  • Una pasarela de aplicación (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

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

  • En Azure Portal, compruebe el archivo JSON del recurso de Application Gateway.
  • Seleccione la versión de API 2025-03-01 y compruebe sslprofile.
  • Compruebe que verifyClientAuthMode está configurado como "passthrough".
"sslProfiles": [
         {
             "name": "sslnotrustedcert",
             "id": "samplesubscriptionid",
             "etag": "W/\"851e4e20-d2b1-4338-9135-e0beac11aa0e\"",
             "properties": {
                 "provisioningState": "Succeeded",
                 "clientAuthConfiguration": {
                     "verifyClientCertIssuerDN": false,
                     "verifyClientRevocation": "None",
                     "verifyClientAuthMode": "Passthrough"
                 },
                 "httpListeners": [
                     {
                         "id": "samplesubscriptionid"
                     }
                 ]

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 como se describe en mutual-authentication-server-variables.

  • Si el cliente ha enviado un certificado, esta reescritura garantiza que el certificado de cliente se incluya en los encabezados de solicitud para el procesamiento de back-end.

Prueba de conectividad

  • Las conexiones deben establecerse incluso si no se proporciona un certificado de cliente.

Parámetros de paso a través de mTLS

Nombre Tipo Description
verifyClientCertIssuerDN boolean Comprobación del nombre del emisor del certificado de cliente en la puerta de enlace
verifyClientRevocation options Comprobación de la revocación de certificados de cliente
VerifyClientAuthMode options Establecer el modo de certificado de cliente (Strict o Passthrough)

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

Aviso de seguridad

Esta solución se clasifica como Confidencial de Microsoft. Asegúrese de seguir los procedimientos recomendados de seguridad y control de datos de su organización al implementar y administrar esta solución.