다음을 통해 공유


mTLS 통과 수신기를 사용하여 Azure Application Gateway 배포

이 빠른 시작에서는 ARM 템플릿 및 API 버전을 사용하여 2025-03-01를 사용하여 Azure Application Gateway를 배포하는 방법을 보여 줍니다. 통과 모드에서 게이트웨이는 클라이언트 인증서를 요청하지만 유효성을 검사하지는 않습니다. 인증서 유효성 검사 및 정책 적용은 백 엔드에서 발생합니다.

주요 기능

  • mTLS 통과에 대한 수신기와 SSL 프로필을 연결합니다.
  • 게이트웨이에 클라이언트 CA 인증서가 필요하지 않습니다.
  • verifyClientAuthModeStrictPassthrough를 지원합니다.

비고

통과 구성에 대한 포털, PowerShell 및 CLI 지원은 현재 사용할 수 없습니다. 이 가이드의 목적을 위해 ARM 템플릿을 사용합니다.

필수 조건

  • Azure 구독 및 리소스 그룹.
  • Azure CLI 설치
  • SSL 인증서(Base64로 인코딩된 PFX) 및 암호입니다.
  • Linux VM 관리자용 SSH 키(해당하는 경우).
  • 통과 속성의 API 버전 2025-03-01 입니다.

mTLS 통과 수신기를 사용하여 Application Gateway 배포

이 템플릿은 다음을 만듭니다.

  • 두 개의 서브넷이 있는 Virtual Network (하나는 Application Gateway에 위임됨)입니다.
  • 게이트웨이 프런트 엔드의 공용 IP 주소 입니다.
  • Application Gateway(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 Portal에서 Application Gateway 리소스 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)

통과 모드: 게이트웨이는 클라이언트 인증서를 요청하지만 적용하지는 않습니다. 백 엔드는 인증서의 유효성을 검사하고 정책을 적용합니다.

보안 알림

이 솔루션은 Microsoft 기밀로 분류됩니다. 이 솔루션을 배포하고 관리할 때 조직의 보안 및 데이터 처리 모범 사례를 따르도록 하세요.