在 Compute Engine 上部署 Active Directory 樹系

Last reviewed 2024-07-11 UTC

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

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

架構

部署作業包含兩個專案:

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

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

事前準備

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

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

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

      建議子網路 CIDR 範圍大小為 /28/29

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

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

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

部署共用網路

在本節中,您會建立新專案,並使用該專案部署共用虛擬私有雲網路。稍後,您將使用這個網路部署 Active Directory 網域控制器。

建立專案

您現在要建立新專案,並使用該專案部署共用虛擬私有雲網路。

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the Compute Engine and Cloud DNS APIs.

    Enable the APIs

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

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

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

刪除預設虛擬私有雲

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

在本節中,您將以自訂模式網路取代這個 VPC 網路,該網路包含兩個子網路,並使用自訂 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 }
    

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

您現在要在 VPC 主專案中建立自訂模式的 VPC 網路。

  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. 建立虛擬私有雲,並設定為共用虛擬私有雲網路:

    $ProjectId = gcloud config get-value core/project
    & gcloud compute networks create $VpcName --subnet-mode custom
    & gcloud compute shared-vpc enable $ProjectId
    
  3. 建立子網路並啟用私人 Google 存取權,這樣 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 樹系

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

建立專案

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

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the Compute Engine and Secret Manager APIs.

    Enable the APIs

如要取得部署 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:先前建立的虛擬私有雲主專案 ID。
    • VPC_NAME:您先前建立的共用 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. 將專案附加至共用虛擬私有雲網路:

    $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 對這個密碼的暫時存取權,讓 VM 可以使用密碼部署 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 轉送連線。

後續步驟