在 Compute Engine 上部署 Active Directory 樹系

Last reviewed 2024-07-11 UTC

本文說明如何在 Compute Engine 上部署 Active Directory 樹系,並遵循「在 Google Cloud 上執行 Active Directory 的最佳做法」一文所述的最佳做法。

本指南適用於管理員和 DevOps 工程師。並假設您已充分瞭解 Active Directory,且具備Google Cloud 網路和安全性的基本知識。

架構

部署作業包含兩個專案:

這個架構可讓您執行下列操作:

  • 在獨立專案中部署其他 Windows 工作負載,並允許這些工作負載使用 Shared VPC 網路和 Active Directory 樹系。
  • 將 Active Directory 樹系與現有的地端部署樹系整合,以實作資源樹系模式

事前準備

如要按照本指南中的說明操作,請確認您具備下列條件:

  • 兩個子網路的子網路 CIDR 範圍:

    • 網域控制站子網路。這個子網路包含網域控制站。 為網域控制器使用專屬子網路,有助於管理防火牆規則或分析網路記錄時,區分網域控制器流量和其他伺服器流量。

      建議使用 /28/29 大小的子網路 CIDR 範圍。

    • 資源子網路。這個子網路包含伺服器和管理工作站。使用足夠大的子網路 CIDR 範圍,以容納您打算部署的所有伺服器。

    請確認子網路不會與任何地端部署子網路重疊,並預留足夠的成長空間。

  • Active Directory 樹系根網域的 DNS 網域名稱和 NetBIOS 網域名稱。如要進一步瞭解如何選擇名稱,請參閱「Microsoft 命名慣例」。

部署共用網路

在本節中,您將建立新專案,並使用該專案部署 Shared VPC 網路。稍後,您將使用這個網路部署 Active Directory 網域控制器。

建立專案

您現在要建立新專案,並使用該專案部署 Shared VPC 網路。

  1. 在 Google Cloud 控制台的專案選擇器頁面中,選取或建立 Google Cloud 專案。

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色

    前往專案選取器

  2. 確認專案已啟用計費功能 Google Cloud

  3. 啟用 Compute Engine 和 Cloud DNS API。

    啟用 API 時所需的角色

    如要啟用 API,您需要服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    啟用 API

如要取得部署共用網路所需的權限,請要求管理員在專案或父項資料夾中,授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

刪除預設虛擬私有雲

根據預設,Compute Engine 會在您建立的每個新專案中建立預設網路。這個網路是以自動模式設定,也就是說,系統會為每個區域預先分配子網路,並自動指派 CIDR 範圍。

在本節中,您將以自訂模式網路取代這個虛擬私有雲網路,該網路包含兩個子網路,並使用自訂 CIDR 範圍。

  1. Google Cloud 控制台中,開啟 Cloud Shell

    啟用 Cloud Shell

  2. 啟動 PowerShell:

    pwsh
    
  3. 將 gcloud CLI 設為使用新專案:

    gcloud config set project PROJECT_ID
    

    PROJECT_ID 替換為專案 ID。

  4. 刪除與預設 VPC 相關聯的所有防火牆規則:

    $ProjectId = gcloud config get-value core/project
    & gcloud compute firewall-rules list `
      --filter "network=default" `
      --format "value(name)" |
      % { gcloud compute firewall-rules delete --quiet $_ --project $ProjectId }
    
  5. 刪除預設虛擬私有雲:

    & gcloud compute networks list --format "value(name)" |
      % { gcloud compute networks delete $_ --quiet }
    

建立自訂模式虛擬私有雲網路

現在,請在虛擬私有雲主專案中建立自訂模式虛擬私有雲網路。

  1. 在 PowerShell 中,初始化下列變數:

    $VpcName = "VPC_NAME"
    $Region = "REGION"
    $SubnetRangeDomainControllers = "DC_CIDR"
    $SubnetRangeResources = "RESOURCES_CIDR"
    

    更改下列內容:

    • VPC_NAME:虛擬私有雲的名稱。
    • REGION:部署 Active Directory 網域控制站的區域。
    • DC_CIDR:網域控制站子網路使用的子網路範圍。
    • RESOURCES_CIDR:用於資源子網路的子網路範圍。

    範例:

    $VpcName = "ad"
    $Region = "us-central1"
    $SubnetRangeDomainControllers = "10.0.0.0/28"
    $SubnetRangeResources = "10.0.1.0/24"
    
  2. 建立虛擬私有雲,並設定為Shared VPC網路:

    $ProjectId = gcloud config get-value core/project
    & gcloud compute networks create $VpcName --subnet-mode custom
    & gcloud compute shared-vpc enable $ProjectId
    
  3. 建立子網路並啟用Private Google Access,讓 Windows 可以在沒有網際網路連線的情況下啟用

    & gcloud compute networks subnets create domain-controllers `
      --network $VpcName `
      --range $SubnetRangeDomainControllers `
      --region $Region `
      --enable-private-ip-google-access
    
    & gcloud compute networks subnets create resources `
      --network $VpcName `
      --range $SubnetRangeResources `
      --region $Region `
      --enable-private-ip-google-access
    

部署子網路和防火牆規則

現在請建立防火牆規則,允許虛擬私有雲內的 Active Directory 通訊。

  1. 透過 Cloud IAP TCP 轉送功能,允許連線至所有 VM 執行個體的遠端桌面協定連線:

    & gcloud compute firewall-rules create allow-rdp-ingress-from-iap `
      --direction INGRESS `
      --action allow `
      --rules tcp:3389 `
      --enable-logging `
      --source-ranges 35.235.240.0/20 `
      --network $VpcName `
      --priority 10000
    
  2. 允許從 Cloud DNS 對網域控制站進行 DNS 查詢。

    & gcloud compute firewall-rules create allow-dns-ingress-from-clouddns `
      --direction INGRESS `
      --action=allow `
      --rules udp:53,tcp:53 `
      --enable-logging `
      --source-ranges 35.199.192.0/19 `
      --target-tags ad-domaincontroller `
      --network $VpcName `
      --priority 10000
    

    私人 DNS 轉送區域必須有這項防火牆規則才能運作。

  3. 允許網域控制器之間複製 Active Directory:

    & gcloud compute firewall-rules create allow-replication-between-addc `
      --direction INGRESS `
      --action allow `
      --rules "icmp,tcp:53,udp:53,tcp:88,udp:88,udp:123,tcp:135,tcp:389,udp:389,tcp:445,udp:445,tcp:49152-65535" `
      --enable-logging `
      --source-tags ad-domaincontroller `
      --target-tags ad-domaincontroller `
      --network $VpcName `
      --priority 10000
    
  4. 允許資源子網路中的 VM 登入網域控制器:

    & gcloud compute firewall-rules create allow-logon-ingress-to-addc `
      --direction INGRESS `
      --action allow `
      --rules "icmp,tcp:53,udp:53,tcp:88,udp:88,udp:123,tcp:135,tcp:389,udp:389,tcp:445,udp:445,tcp:464,udp:464,tcp:3268,udp:3268,tcp:9389,tcp:49152-65535" `
      --enable-logging `
      --source-ranges $SubnetRangeResources `
      --target-tags ad-domaincontroller `
      --network $VpcName `
      --priority 10000
    
  5. 如果您打算設定安全 LDAP,請允許資源子網路中的 VM 連線至網域控制站:

    & gcloud compute firewall-rules create allow-ldaps-ingress-to-addc `
      --direction INGRESS `
      --action allow `
      --rules tcp:636 `
      --enable-logging `
      --source-ranges $SubnetRangeResources `
      --target-tags ad-domaincontroller `
      --network $VpcName `
      --priority 10000
    

    如果您打算設定安全 LDAP,才需要這項防火牆規則。

  6. (選用) 建立防火牆規則,記錄所有存取嘗試失敗的事件。記錄檔有助於診斷連線問題,但可能會產生大量記錄資料。

    & gcloud compute firewall-rules create deny-ingress-from-all `
      --direction INGRESS `
      --action deny `
      --rules tcp:0-65535,udp:0-65535 `
      --enable-logging `
      --source-ranges 0.0.0.0/0 `
      --network $VpcName `
      --priority 65000
    

部署 Active Directory 樹系

在本節中,您會建立新的服務專案,並將其附加至先前建立的 Shared VPC 主專案。然後,您可以使用服務專案部署新的 Active Directory 樹系,其中包含兩個網域控制器。

建立專案

現在請建立新專案,並使用該專案部署 Active Directory 網域控制器 VM。

  1. 在 Google Cloud 控制台的專案選擇器頁面中,選取或建立 Google Cloud 專案。

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色

    前往專案選取器

  2. 確認專案已啟用計費功能 Google Cloud

  3. 啟用 Compute Engine 和 Secret Manager API。

    啟用 API 時所需的角色

    如要啟用 API,您需要服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    啟用 API

如要取得部署 Active Directory 樹系所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

準備設定

下一步是準備 Active Directory 部署作業的設定。

  1. 如果您先前已關閉 PowerShell 工作階段,請開啟 Cloud Shell

    啟用 Cloud Shell

  2. 啟動 PowerShell:

    pwsh
    
  3. 將 gcloud CLI 設為使用新專案:

    gcloud config set project DC_PROJECT_ID
    

    DC_PROJECT_ID 替換為專案 ID。

  4. 使用 PowerShell 建立下列變數:

    $AdDnsDomain = "DNS_DOMAIN"
    $AdNetbiosDomain = "NETBIOS_DOMAIN"
    $VpcProjectId = "VPCHOST_PROJECT_ID"
    $VpcName = "VPC_NAME"
    $Region = "REGION"
    $Zones = "REGION-a", "REGION-b"
    

    更改下列內容:

    • DNS_DOMAIN:Active Directory 樹系的樹系根網域名稱,例如 cloud.example.com
    • NETBIOS_DOMAIN:樹系根網域的 NetBIOS 網域名稱,例如 CLOUD
    • VPCHOST_PROJECT_ID:先前建立的 VPC 主專案專案 ID。
    • VPC_NAME:先前建立的 Shared VPC 網路名稱。
    • REGION:部署 Active Directory 網域控制站的區域。請注意,可用區名稱會根據您指定的區域名稱而定。您隨時可以擴充虛擬私有雲和網域,涵蓋其他區域。

    範例:

    $AdDnsDomain = "cloud.example.com"
    $AdNetbiosDomain = "CLOUD"
    $VpcProjectId = "vpc-project-123"
    $VpcName = "ad"
    $Region = "us-west1"
    $Zones = "us-west1-a", "us-west1-b"
    

建立私人 DNS 轉送區域

現在,請為網域控制站保留兩個靜態 IP 位址,並建立私人 DNS 轉送區域,將 Active Directory 網域的所有 DNS 查詢轉送至這些 IP 位址。

  1. 將專案附加至 Shared VPC 網路:

    $ProjectId = gcloud config get-value core/project
    & gcloud compute shared-vpc associated-projects add $ProjectId --host-project $VpcProjectId
    
  2. 在網域控制站子網路中預留兩個靜態內部 IP 位址:

    $AddressOfDc1 = gcloud compute addresses create dc-1 `
      --region $Region `
      --subnet "projects/$VpcProjectId/regions/$Region/subnetworks/domain-controllers" `
      --format value`(address`)
    $AddressOfDc2 = gcloud compute addresses create dc-2 `
      --region $Region `
      --subnet "projects/$VpcProjectId/regions/$Region/subnetworks/domain-controllers" `
      --format value`(address`)
    
  3. 在 VPC 主專案中建立 Cloud DNS 私人轉送區域,並將該區域設定為將 DNS 查詢轉送至兩個保留 IP 位址:

    & gcloud dns managed-zones create $AdDnsDomain.Replace(".", "-") `
      --project $VpcProjectId `
      --dns-name $AdDnsDomain `
      --description "Active Directory forwarding zone" `
      --networks $VpcName `
      --visibility private `
      --forwarding-targets "$AddressOfDc1,$AddressOfDc2"
    

建立 DSRM 密碼

現在請定義「Directory Service Restore Mode (DSRM)」密碼,並儲存在 Secret Manager 中。然後授予網域控制器 VM 這個 Secret 的暫時存取權,讓 VM 可以使用 Secret 部署 Active Directory 樹系。

  1. 產生隨機密碼並儲存在 Secret Manager 密鑰中:

    # Generate a random password.
    $DsrmPassword = [Guid]::NewGuid().ToString()+"-"+[Guid]::NewGuid().ToString()
    
    $TempFile = New-TemporaryFile
    Set-Content $TempFile "$DsrmPassword" -NoNewLine
    & gcloud secrets create ad-password --data-file $TempFile
    Remove-Item $TempFile
    
  2. 為網域控制站 VM 執行個體建立服務帳戶:

    $DcServiceAccount = gcloud iam service-accounts create ad-domaincontroller `
      --display-name "AD Domain Controller" `
      --format "value(email)"
    
  3. 授予服務帳戶在接下來一小時內讀取密鑰的權限:

    $Expiry = [DateTime]::UtcNow.AddHours(1).ToString("o")
    & gcloud secrets add-iam-policy-binding ad-password `
      --member=serviceAccount:$($DcServiceAccount) `
      --role=roles/secretmanager.secretAccessor `
      --condition="title=Expires after 1h,expression=request.time < timestamp('$Expiry')"
    

部署網域控制站

您現在要部署兩個 VM 執行個體,並建立新的 Active Directory 樹系和網域。為盡量減少手動步驟,請使用啟動指令碼

  1. 在 PowerShell 中執行下列指令,產生開機指令碼:

    '
    $ErrorActionPreference = "Stop"
    
    #
    # Only run the script if the VM is not a domain controller already.
    #
    if ((Get-CimInstance -ClassName Win32_OperatingSystem).ProductType -eq 2) {
        exit
    }
    
    #
    # Read configuration from metadata.
    #
    Import-Module "${Env:ProgramFiles}\Google\Compute Engine\sysprep\gce_base.psm1"
    
    $ActiveDirectoryDnsDomain     = Get-MetaData -Property "attributes/ActiveDirectoryDnsDomain" -instance_only
    $ActiveDirectoryNetbiosDomain = Get-MetaData -Property "attributes/ActiveDirectoryNetbiosDomain" -instance_only
    $ActiveDirectoryFirstDc       = Get-MetaData -Property "attributes/ActiveDirectoryFirstDc" -instance_only
    $ProjectId                    = Get-MetaData -Property "project-id" -project_only
    $Hostname                     = Get-MetaData -Property "hostname" -instance_only
    $AccessToken                  = (Get-MetaData -Property "service-accounts/default/token" | ConvertFrom-Json).access_token
    
    #
    # Read the DSRM password from secret manager.
    #
    $Secret = (Invoke-RestMethod `
        -Headers @{
            "Metadata-Flavor" = "Google";
            "x-goog-user-project" = $ProjectId;
            "Authorization" = "Bearer $AccessToken"} `
        -Uri "https://secretmanager.googleapis.com/v1/projects/$ProjectId/secrets/ad-password/versions/latest:access")
    $DsrmPassword = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($Secret.payload.data))
    $DsrmPassword = ConvertTo-SecureString -AsPlainText $DsrmPassword -force
    
    #
    # Promote.
    #
    Write-Host "Setting administrator password..."
    Set-LocalUser -Name Administrator -Password $DsrmPassword
    
    if ($ActiveDirectoryFirstDc -eq $env:COMPUTERNAME) {
        Write-Host "Creating a new forest $ActiveDirectoryDnsDomain ($ActiveDirectoryNetbiosDomain)..."
        Install-ADDSForest `
            -DomainName $ActiveDirectoryDnsDomain `
            -DomainNetbiosName $ActiveDirectoryNetbiosDomain `
            -SafeModeAdministratorPassword $DsrmPassword `
            -DomainMode Win2008R2 `
            -ForestMode Win2008R2 `
            -InstallDns `
            -CreateDnsDelegation:$False `
            -NoRebootOnCompletion:$True `
            -Confirm:$false
    }
    else {
        do {
            Write-Host "Waiting for domain to become available..."
            Start-Sleep -s 60
            & ipconfig /flushdns | Out-Null
            & nltest /dsgetdc:$ActiveDirectoryDnsDomain | Out-Null
        } while ($LASTEXITCODE -ne 0)
    
        Write-Host "Adding DC to $ActiveDirectoryDnsDomain ($ActiveDirectoryNetbiosDomain)..."
        Install-ADDSDomainController `
            -DomainName $ActiveDirectoryDnsDomain `
            -SafeModeAdministratorPassword $DsrmPassword `
            -InstallDns `
            -Credential (New-Object System.Management.Automation.PSCredential ("Administrator@$ActiveDirectoryDnsDomain", $DsrmPassword)) `
            -NoRebootOnCompletion:$true  `
            -Confirm:$false
    }
    
    #
    # Configure DNS.
    #
    Write-Host "Configuring DNS settings..."
    Get-Netadapter| Disable-NetAdapterBinding -ComponentID ms_tcpip6
    Set-DnsClientServerAddress  `
        -InterfaceIndex (Get-NetAdapter -Name Ethernet).InterfaceIndex `
        -ServerAddresses 127.0.0.1
    
    #
    # Enable LSA protection.
    #
    New-ItemProperty `
        -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa" `
        -Name "RunAsPPL" `
        -Value 1 `
        -PropertyType DWord
    
    Write-Host "Restarting to apply all settings..."
    Restart-Computer
    ' | Out-File dc-startup.ps1 -Encoding ASCII
    

    指令碼會執行下列作業:

    • 從 Secret Manager 讀取 DSRM 密碼。
    • 將 VM 升級為網域控制站。
    • 設定 DNS 設定,讓每個網域控制站使用迴路位址做為 DNS 伺服器。
    • 停用 IPv6。
    • 啟用 LSA 保護措施
  2. 為第一個網域控制站建立 VM 執行個體:

    $Subnet = "projects/$VpcProjectId/regions/$Region/subnetworks/domain-controllers"
    $Metadata = `
      "ActiveDirectoryDnsDomain=$AdDnsDomain",
      "ActiveDirectoryNetbiosDomain=$AdNetbiosDomain",
      "ActiveDirectoryFirstDc=dc-1",
      "sysprep-specialize-script-ps1=Install-WindowsFeature AD-Domain-Services; Install-WindowsFeature DNS",
      "disable-account-manager=true" -join ","
    
    & gcloud compute instances create dc-1  `
      --image-family windows-2022 `
      --image-project windows-cloud `
      --machine-type n2-standard-8 `
      --tags ad-domaincontroller `
      --metadata "$Metadata" `
      --metadata-from-file windows-startup-script-ps1=dc-startup.ps1 `
      --no-address `
      --network-interface "no-address,private-network-ip=$AddressOfDc1,subnet=$Subnet" `
      --service-account $DcServiceAccount `
      --scopes cloud-platform `
      --zone $Zones[0] `
      --shielded-integrity-monitoring `
      --shielded-secure-boot `
      --shielded-vtpm `
      --deletion-protection
    

    這項指令會執行以下作業:

    • 建立受防護的 Windows Server 2022 VM。
    • ad-domaincontroller 服務帳戶指派給 VM,以便存取 DSRM 密碼。
    • 設定訪客代理程式,停用帳戶管理員。如要進一步瞭解如何設定客體代理程式,請參閱「啟用及停用 Windows 執行個體功能」。
    • 讓 VM 在 sysprep specialize 階段安裝 Windows 功能 AD-Domain-ServicesDNS
    • 讓 VM 執行先前建立的開機指令碼。
  3. 為第二個網域控制器建立另一個 VM 執行個體,並將其放在不同區域:

    & gcloud compute instances create dc-2  `
      --image-family windows-2022 `
      --image-project windows-cloud `
      --machine-type n2-standard-8 `
      --tags ad-domaincontroller `
      --metadata "$Metadata" `
      --metadata-from-file windows-startup-script-ps1=dc-startup.ps1 `
      --no-address `
      --network-interface "no-address,private-network-ip=$AddressOfDc2,subnet=$Subnet" `
      --service-account $DcServiceAccount `
      --scopes cloud-platform `
      --zone $Zones[1] `
      --shielded-integrity-monitoring `
      --shielded-secure-boot `
      --shielded-vtpm `
      --deletion-protection
    
  4. 查看第一個網域控制器的序列埠輸出內容,監控初始化程序:

    & gcloud compute instances tail-serial-port-output dc-1 --zone $Zones[0]
    

    等待約 10 分鐘,直到看到 Restarting to apply all settings... 訊息,然後按下 Ctrl+C

  5. 查看第二個網域控制站的序列埠輸出內容,監控初始化程序:

    & gcloud compute instances tail-serial-port-output dc-2 --zone $Zones[1]
    

    等待約 10 分鐘,直到看到 Restarting to apply all settings... 訊息,然後按下 Ctrl+C

Active Directory 樹系和網域現在已可使用。

連線至網域控制站

現在只要連線至其中一個網域控制器,即可自訂 Active Directory 樹系。

  1. 在 PowerShell 中,存取 Administrator 使用者的密碼:

    gcloud secrets versions access latest --secret ad-password
    
  2. 使用遠端桌面協定連線至 dc-1,並以 Administrator 使用者身分登入。

    由於 VM 執行個體沒有公開 IP 位址,因此您必須透過 Identity-Aware Proxy TCP 轉送連線。

後續步驟