使用 Azure 门户为 Bastion 配置 Kerberos 身份验证
本文介绍如何将 Azure Bastion 配置为使用 Kerberos 身份验证。 Kerberos 身份验证可与基本和标准 Bastion SKU 配合使用。 有关 Kerberos 身份验证的详细信息,请参阅 Kerberos 身份验证概述。 有关 Azure Bastion 的详细信息,请参阅什么是 Azure Bastion?
注意事项
- 只能在 Azure 门户中为 Azure Bastion 配置 Kerberos 设置,而不能在本机客户端中配置。
- Kerberos 目前不支持从本地迁移到 Azure 的 VM。
- Kerberos 目前不支持跨领域身份验证。
- 域控制器必须为堡垒主机部署的同一 VNET 中的 Azure 托管虚拟机。
- 对 DNS 服务器的更改不会传播到 Bastion。 需要重新部署 Bastion 才能正确传播 DNS 信息。 对 DNS 服务器进行任何更改后,需要删除再重新创建 Bastion 资源。
- 如果添加其他域控制器 (DC),Bastion 将仅识别第一个 DC。
- 如果为不同的域添加了其他 DC,则添加的域无法成功通过 Kerberos 进行身份验证。
先决条件
具有活动订阅的 Azure 帐户。 如果没有,请创建一个试用版订阅。 为了能够使用 Bastion 通过浏览器连接到 VM,必须能够登录 Azure 门户。
一个 Azure 虚拟网络。 有关创建 VNet 的步骤,请参阅快速入门:创建虚拟网络。
更新 VNet DNS 服务器
本部分中的以下步骤可帮助你更新虚拟网络以指定自定义 DNS 设置。
- 登录到 Azure 门户。
- 转到要为其部署 Bastion 资源的虚拟网络。
- 转到 VNet 的“DNS 服务器”页并选择“自定义”。 添加 Azure 托管的域控制器的 IP 地址并选择“保存”。
部署 Bastion
使用教程:使用手动配置设置部署 Bastion 中的步骤开始配置 Bastion 部署。 在“基本信息”选项卡上配置设置。然后,在页面顶部,单击“高级”转到高级选项卡。
在“高级”选项卡上,选择“Kerberos”。
在页面底部,选择“查看 + 创建”,然后选择“创建”,将 Bastion 部署到虚拟网络。
部署完成后,可以使用 Bastion 登录到任何可访问的、已加入到在前面步骤中指定的自定义 DNS 的 Windows VM。
修改现有的 Bastion 部署
本部分中的以下步骤可帮助你修改虚拟网络和现有的 Bastion 部署以进行 Kerberos 身份验证。
- 更新虚拟网络的 DNS 设置。
- 转到 Bastion 部署的门户页并选择“配置”。
- 在“配置”页上,依次选择“Kerberos 身份验证”、“应用”。
- Bastion 将使用新的配置设置进行更新。
验证 Bastion 是否使用 Kerberos
注意
必须使用用户主体名称 (UPN) 才能使用 Kerberos 登录。
在 Bastion 资源上启用 Kerberos 后,可以验证该资源是否确实在使用 Kerberos 向已加入域的目标 VM 进行身份验证。
登录到目标 VM(通过或不通过 Bastion)。 在任务栏中搜索“编辑组策略”并打开“本地组策略编辑器”。
选择“计算机配置”>“Windows 设置”>“安全设置”>“本地策略”>“安全选项”。
找到策略“网络安全: 限制 NTLM: 传入 NTLM 流量”并将其设置为“拒绝所有域帐户”。 由于在禁用 Kerberos 时 Bastion 会使用 NTLM 进行身份验证,因此,此设置可确保将来在 VM 上尝试登录时基于 NTLM 的身份验证不会成功。
结束 VM 会话。
使用 Bastion 再次连接到目标 VM。 登录应该成功,这表明 Bastion 已使用 Kerberos(而不是 NTLM)进行身份验证。
注意
若要防止故障回复到 NTLM,请确保遵循前面的步骤。 启用 Kerberos(不遵循过程)不会阻止故障回复到 NTLM。
快速入门:使用 Kerberos 设置 Bastion - 资源管理器模板
查看模板
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"defaultValue": "[resourceGroup().location]",
"type": "string"
},
"defaultNsgName": {
"type": "string",
"defaultValue": "Default-nsg"
},
"VnetName": {
"type": "string",
"defaultValue": "myVnet"
},
"ClientVMName": {
"defaultValue": "Client-vm",
"type": "string"
},
"ServerVMName": {
"defaultValue": "Server-vm",
"type": "string"
},
"vmsize": {
"defaultValue": "Standard_DS1_v2",
"type": "string",
"metadata": {
"description": "VM SKU to deploy"
}
},
"ServerVMUsername": {
"type": "string",
"defaultValue": "serveruser",
"metadata": {
"description": "Admin username on all VMs."
}
},
"ServerVMPassword": {
"type": "securestring",
"metadata": {
"description": "Admin password on all VMs."
}
},
"SafeModeAdministratorPassword": {
"type": "securestring",
"metadata": {
"description": "See https://learn.microsoft.com/powershell/module/addsdeployment/install-addsdomaincontroller?view=windowsserver2022-ps#-safemodeadministratorpassword"
}
},
"ClientVMUsername": {
"type": "string",
"defaultValue": "clientuser",
"metadata": {
"description": "username on ClientVM."
}
},
"ClientVMPassword": {
"type": "securestring",
"metadata": {
"description": "password on ClientVM."
}
},
"ServerVmImage": {
"type": "object",
"defaultValue": {
"offer": "WindowsServer",
"publisher": "MicrosoftWindowsServer",
"sku": "2019-Datacenter",
"version": "latest"
}
},
"ClientVmImage": {
"type": "object",
"defaultValue": {
"offer": "Windows",
"publisher": "microsoftvisualstudio",
"sku": "Windows-10-N-x64",
"version": "latest"
}
},
"publicIPAllocationMethod": {
"type": "string",
"defaultValue": "Static"
},
"BastionName": {
"defaultValue": "Bastion",
"type": "string"
},
"BastionPublicIPName": {
"defaultValue": "Bastion-ip",
"type": "string"
}
},
"variables": {
"DefaultSubnetId": "[concat(resourceId('Microsoft.Network/virtualNetworks', parameters('VnetName')), '/subnets/default')]",
"ClientVMSubnetId": "[concat(resourceId('Microsoft.Network/virtualNetworks', parameters('VnetName')), '/subnets/clientvm-subnet')]",
"DNSServerIpAddress": "10.16.0.4",
"ClientVMPrivateIpAddress": "10.16.1.4"
},
"resources": [
{
"apiVersion": "2020-03-01",
"name": "[parameters('VnetName')]",
"type": "Microsoft.Network/virtualNetworks",
"location": "[parameters('location')]",
"properties": {
"dhcpOptions": {
"dnsServers": [ "[variables('DNSServerIpAddress')]" ]
},
"subnets": [
{
"name": "default",
"properties": {
"addressPrefix": "10.16.0.0/24"
}
},
{
"name": "clientvm-subnet",
"properties": {
"addressPrefix": "10.16.1.0/24"
}
},
{
"name": "AzureBastionSubnet",
"properties": {
"addressPrefix": "10.16.2.0/24"
}
}
],
"addressSpace": {
"addressPrefixes": [
"10.16.0.0/16"
]
}
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2018-10-01",
"name": "[concat(parameters('ServerVMName'), 'Nic')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('VnetName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "[concat(parameters('ServerVMName'), 'NicIpConfig')]",
"properties": {
"privateIPAllocationMethod": "Static",
"privateIPAddress": "[variables('DNSServerIpAddress')]",
"subnet": {
"id": "[variables('DefaultSubnetId')]"
}
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2020-06-01",
"name": "[parameters('ServerVMName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', parameters('ServerVMName'), 'Nic')]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"osProfile": {
"AdminUsername": "[parameters('ServerVMUsername')]",
"AdminPassword": "[parameters('ServerVMPassword')]",
"computerName": "[parameters('ServerVMName')]"
},
"storageProfile": {
"imageReference": "[parameters('ServerVmImage')]",
"osDisk": {
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
}
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[ResourceId('Microsoft.Network/networkInterfaces/', concat(parameters('ServerVMName'), 'Nic'))]"
}
]
}
}
},
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"apiVersion": "2021-04-01",
"name": "[concat(parameters('ServerVMName'),'/', 'PromoteToDomainController')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/',parameters('ServerVMName'))]"
],
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.7",
"autoUpgradeMinorVersion": true,
"settings": {
"commandToExecute": "[concat('powershell.exe -Command \"Install-windowsfeature AD-domain-services; Import-Module ADDSDeployment;$Secure_String_Pwd = ConvertTo-SecureString ',parameters('SafeModeAdministratorPassword'),' -AsPlainText -Force; Install-ADDSForest -DomainName \"bastionkrb.test\" -SafeModeAdministratorPassword $Secure_String_Pwd -Force:$true')]"
}
}
},
{
"type": "Microsoft.Network/networkInterfaces",
"apiVersion": "2018-10-01",
"name": "[concat(parameters('ClientVMName'), 'Nic')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('VnetName'))]",
"[concat('Microsoft.Compute/virtualMachines/', parameters('ServerVMName'))]"
],
"properties": {
"ipConfigurations": [
{
"name": "[concat(parameters('ClientVMName'), 'NicIpConfig')]",
"properties": {
"privateIPAllocationMethod": "Static",
"privateIPAddress": "[variables('ClientVMPrivateIpAddress')]",
"subnet": {
"id": "[variables('ClientVMSubnetId')]"
}
}
}
]
}
},
{
"type": "Microsoft.Compute/virtualMachines",
"apiVersion": "2020-06-01",
"name": "[parameters('ClientVMName')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Network/networkInterfaces/', parameters('ClientVMName'), 'Nic')]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[parameters('vmSize')]"
},
"osProfile": {
"AdminUsername": "[parameters('ClientVMUsername')]",
"AdminPassword": "[parameters('ClientVMPassword')]",
"computerName": "[parameters('ClientVMName')]"
},
"storageProfile": {
"imageReference": "[parameters('ClientVmImage')]",
"osDisk": {
"createOption": "FromImage",
"managedDisk": {
"storageAccountType": "Standard_LRS"
}
}
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[ResourceId('Microsoft.Network/networkInterfaces/', concat(parameters('ClientVMName'), 'Nic'))]"
}
]
}
}
},
{
"type": "Microsoft.Compute/virtualMachines/extensions",
"apiVersion": "2021-04-01",
"name": "[concat(parameters('ClientVMName'),'/', 'DomainJoin')]",
"location": "[parameters('location')]",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/',parameters('ClientVMName'))]",
"[concat('Microsoft.Compute/virtualMachines/', parameters('ServerVMName'),'/extensions/', 'PromoteToDomainController')]",
"[concat('Microsoft.Network/bastionHosts/', parameters('BastionName'))]"
],
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.7",
"autoUpgradeMinorVersion": true,
"settings": {
"commandToExecute": "[concat('powershell.exe -Command Set-ItemProperty -Path HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\MSV1_0\\ -Name RestrictReceivingNTLMTraffic -Value 1; $Pass= ConvertTo-SecureString -String ',parameters('ServerVMPassword'),' -AsPlainText -Force; $Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList \"AD\\serveruser\", $Pass; do { try { $joined = add-computer -computername Client-vm -domainname bastionkrb.test -credential $Credential -passthru -restart -force; } catch {}} while ($joined.HasSucceeded -ne $true)')]"
}
}
},
{
"apiVersion": "2020-11-01",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[parameters('BastionPublicIPName')]",
"location": "[resourceGroup().location]",
"sku": {
"name": "Standard"
},
"properties": {
"publicIPAllocationMethod": "Static"
},
"tags": {}
},
{
"type": "Microsoft.Network/bastionHosts",
"apiVersion": "2020-11-01",
"name": "[parameters('BastionName')]",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/', parameters('VnetName'))]",
"[concat('Microsoft.Network/publicIpAddresses/', parameters('BastionPublicIPName'))]"
],
"sku": {
"name": "Standard"
},
"properties": {
"enableKerberos": "true",
"ipConfigurations": [
{
"name": "IpConf",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIpAddresses', parameters('BastionPublicIPName'))]"
},
"subnet": {
"id": "[concat(resourceId('Microsoft.Network/virtualNetworks', parameters('VnetName')), '/subnets/AzureBastionSubnet')]"
}
}
}
]
}
}
]
}
该模板中已定义了以下资源:
- 部署以下 Azure 资源:
- Microsoft.Network/virtualNetworks:创建 Azure 虚拟网络。
- Microsoft.Network/bastionHosts:创建启用了公共 IP 和 Kerberos 功能的标准 SKU Bastion。
- 创建 Windows 10 ClientVM 和 Windows Server 2019 ServerVM。
- 将 VNet 的 DNS 服务器指向 ServerVM(域控制器)的专用 IP 地址。
- 在 ServerVM 上运行自定义脚本扩展,将其提升到域名为
bastionkrb.test
的域控制器。 - 在 ClientVM 上运行自定义脚本扩展,使之执行以下操作:
- 限制 NTLM:传入 NTLM 流量 = 拒绝所有域帐户(目的是确保 Kerberos 用于身份验证)。
- 域加入
bastionkrb.test
域。
部署模板
若要设置 Kerberos,请通过运行以下 PowerShell cmd 来部署前面的 ARM 模板:
New-AzResourceGroupDeployment -ResourceGroupName <your-rg-name> -TemplateFile "<path-to-template>\KerberosDeployment.json"`
查看已部署的资源
现在,使用带有 Kerberos 身份验证的 Bastion 登录到 ClientVM:
- 凭据:用户名 =
serveruser@bastionkrb.test
,密码 =<password-entered-during-deployment>
。
后续步骤
有关 Azure Bastion 的详细信息,请参阅什么是 Azure Bastion?