使用 Azure 入口網站來為 Bastion 設定 Kerberos 驗證

本文說明如何設定 Azure Bastion 以便使用 Kerberos 驗證。 Kerberos 驗證可與基本和標準的 Bastion SKU 搭配使用。 如需 Kerberos 驗證的詳細資訊,請參閱 Kerberos 驗證概觀。 如需 Azure Bastion 的詳細資訊,請參閱什麼是 Azure Bastion?

考量

  • 只能在 Azure 入口網站中設定 Bastion 的 Kerberos 設定,且不得使用原生用端進行設定。
  • 目前不支援對 Kerberos 從內部部署移轉至 Azure 的 VM。 
  • 目前不支援對 Kerberos 進行跨區域驗證。
  • 網域控制站必須是部署堡壘的相同 VNET 內的 Azure 託管 VM。
  • 目前不支援對 Kerberos 進行對 DNS 伺服器所做的變更。 對 DNS 伺服器進行任何變更之後,您必須刪除並重新建立 Bastion 資源。
  • 如果新增其他 DC (網域控制站),Bastion 只會辨識第一個 DC。
  • 如果針對不同的網域新增其他 DC,則新增的網域無法成功向 Kerberos 進行驗證。

必要條件

  • 具有有效訂用帳戶的 Azure 帳戶。 如果您沒有帳戶,請免費建立一個。 若要能夠透過瀏覽器使用 Bastion 連線到 VM,您必須能夠登入 Azure 入口網站。

  • Azure 虛擬網路。 如需用來建立 VNet 的步驟,請參閱快速入門:建立虛擬網路

更新 VNet DNS 伺服器

在本節中,下列步驟可協助您更新虛擬網路,以指定自訂的 DNS 設定。

  1. 登入 Azure 入口網站
  2. 移至要部署 Bastion 資源的虛擬網路。
  3. 移至 VNet 的 [DNS 伺服器] 頁面,然後選取 [自訂]。 新增 Azure 裝載的網域控制站所具有的 IP 位址,然後 [儲存]

部署 Bastion

  1. 使用教學課程:使用手動組態設定部署 Bastion 中的步驟,開始設定 Bastion 部署。 在 [基本] 索引標籤上進行設定。然後,在頁面頂端按一下 [進階] 以前往 [進階] 索引標籤。

  2. 在 [進階] 索引標籤上,選取 [Kerberos]

    Screenshot of select bastion features.

  3. 在頁面底部,選取 [檢閱 + 建立],然後選取 [建立] 以將 Bastion 部署到您的虛擬網路。

  4. 部署完成後,便可以用它來登入任何已加入先前步驟所指定自訂 DNS 的可連線 Windows VM。

修改現有的 Bastion 部署

在本節中,下列步驟可協助您修改虛擬網路和現有 Bastion 部署,以便進行 Kerberos 驗證。

  1. 針對您的虛擬網路更新 DNS 設定
  2. 移至 Bastion 部署的入口網站頁面,然後選取 [設定]
  3. 在 [設定] 頁面上,選取 [Kerberos 驗證],然後選取 [套用]
  4. Bastion 會以新的組態設定進行更新。

確認 Bastion 是否使用 Kerberos

注意

您必須使用使用者主體名稱 (UPN) 以使用 Kerberos 登入。

在 Bastion 資源上啟用了 Kerberos 之後,便可以確認其是否真的使用 Kerberos 來向已加入目標網域的 VM 進行驗證。

  1. 登入目標 VM (要不要透過 Bastion 都可以)。 從工作列搜尋「編輯群組原則」,然後開啟 [本機群組原則編輯器]

  2. 選取 [電腦設定] > [Windows 設定] > [安全性設定] > [本機原則] > [安全性選項]

  3. 尋找 [網路安全性:限制 NTLM:傳入的 NTLM 流量] 原則,並將其設定為 [拒絕所有網域帳戶]。 由於 Bastion 會在 Kerberos 停用時使用 NTLM 進行驗證,所以此設定可確保日後在 VM 上嘗試登入時無法使用 NTLM 型驗證。

  4. 結束 VM 工作階段。

  5. 使用 Bastion 再次連線到目標 VM。 登入應該會成功,並有訊息指出 Bastion 使用 Kerberos (而不是 NTLM) 進行驗證。

    注意

    若要防止容錯回復到 NTLM,請確定您遵循上述步驟。 啟用 Kerberos (而未遵循程序) 不會防止容錯回復到 NTLM。

快速入門:使用 Kerberos 設定 Bastion - Resource Manager 範本

檢閱範本

{
  "$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/en-us/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 資源:
  • 讓 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"`

檢閱已部署的資源

現在,使用 Bastion 搭配 Kerberos 驗證登入 ClientVM:

  • 認證:使用者名稱 = serveruser@bastionkrb.test 和密碼 = <password-entered-during-deployment>

下一步

如需 Azure Bastion 的詳細資訊,請參閱什麼是 Azure Bastion?