Поделиться через


Развертывание шлюза приложений Azure с помощью сквозного прослушивателя MTLS

В этом кратком руководстве показано, как развернуть шлюз приложений Azure с сквозной передачей с использованием взаимной аутентификации TLS (mTLS), используя шаблон ARM и версию интерфейса программирования приложений 2025-03-01. В режиме сквозной передачи шлюз запрашивает сертификат клиента, но не проверяет его. Проверка сертификатов и принудительное применение политик выполняются в серверной части.

Ключевые особенности

  • Свяжите SSL-профиль с конфигурацией слушателя для сквозной передачи mTLS.
  • На шлюзе не требуется клиентский сертификат удостоверяющего центра.
  • verifyClientAuthMode поддерживает Strict и Passthrough.

Замечание

Поддержка портала, PowerShell и CLI для настройки сквозной конфигурации в настоящее время недоступна. В этом руководстве используйте шаблоны ARM.

Предпосылки

  • Подписка Azure и группа ресурсов.
  • Установленный Azure CLI.
  • SSL-сертификат (PFX в кодировке Base64) и пароль.
  • Ключ SSH для администратора виртуальной машины Linux (если применимо).
  • Версия 2025-03-01 API для сквозного свойства.

Развертывание шлюза приложений с помощью сквозного прослушивателя MTLS

Этот шаблон создает:

  • Виртуальная сеть с двумя подсетями (одна делегирована шлюзу приложений).
  • Общедоступный IP-адрес для внешнего интерфейса шлюза.
  • Шлюз приложений (Standard_v2) с:
    • SSL-сертификат и профиль SSL для сквозной передачи клиентского сертификата.
    • Прослушиватель HTTPS и правило маршрутизации.
    • Серверный пул, указывающий на службу приложений. Обновите шаблон с подробными сведениями о конфигурации и включите действительный SSL-сертификат.

Файл параметров: 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>"
        }
    }
}

Файл шаблона: 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'))]"
            ]
        }
    ]
}

Развертывание шаблона

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

Проверка и тестирование

Проверка развертывания

  • На портале Azure проверьте JSON-файл ресурса шлюза приложений
  • Выберите API версии 2025-03-01 и проверьте sslprofile
  • Проверьте, что verifyClientAuthMode установлено в значение "сквозной"
"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"
                     }
                 ]

Отправка сертификата клиента в серверную часть

  • Если необходимо переслать клиентский сертификат на бэкенд, настройте правило перезаписи, как описано в переменных сервера взаимной аутентификации.

  • Если клиент отправил сертификат, этот перезапись гарантирует, что сертификат клиента включен в заголовки запросов для внутренней обработки.

Проверка подключения

  • Необходимо установить подключения, даже в случае, если сертификат клиента не указан.

Параметры сквозной передачи mTLS

Имя Тип Description
verifyClientCertIssuerDN булевый Проверка имени издателя сертификата клиента на шлюзе
verifyClientRevocation options Проверка отзыва сертификата клиента
VerifyClientAuthMode options Настройка режима сертификата клиента (Strict или Passthrough)

Режим сквозной передачи: Шлюз запрашивает сертификат клиента, но не требует его. Серверная часть проверяет сертификат и применяет политику.

Уведомление о безопасности

Это решение классифицируется как конфиденциальное решение Майкрософт. При развертывании и управлении этим решением убедитесь, что вы следуйте рекомендациям по обеспечению безопасности и обработке данных организации.