在 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 範圍:

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

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

    • 資源子網路。這個子網路包含伺服器和管理工作站。使用足以容納您打算部署的所有伺服器的子網路 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 轉送功能,允許 RDP 連線至所有 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 與網域控制器之間的安全 LDAP 連線:

    & 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:先前建立的共用虛擬私有雲網路名稱。
    • REGION:部署 Active Directory 網域控制站的區域。請注意,可用區名稱會根據您指定的區域名稱。您隨時可以擴充 VPC 和網域,涵蓋其他區域。

    範例:

    $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,讓 VM 能夠存取 DSRM 密碼。
    • 設定訪客服務代理,以停用帳戶管理員。如要進一步瞭解如何設定訪客代理程式,請參閱「啟用及停用 Windows 執行個體功能」。
    • 讓 VM 在 sysprep 專用階段安裝 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 轉送連線。

後續步驟