Compute Engine에 Active Directory 포레스트 배포

Last reviewed 2023-05-10 UTC

이 문서에서는 Google Cloud에서 Active Directory를 실행하기 위한 권장사항에 설명된 권장사항을 준수하는 방식으로 Compute Engine에 Active Directory 포레스트를 배포하는 방법을 설명합니다.

이 가이드는 관리자 및 DevOps 엔지니어를 대상으로 합니다. 사용자가 Active Directory을 확실히 이해하며 Google Cloud 네트워킹 및 보안에 대한 기본 지식이 있다고 가정합니다.

아키텍처

배포는 두 프로젝트로 구성됩니다.

이 아키텍처를 통해 다음을 수행할 수 있습니다.

  • 별도의 프로젝트에 추가 Windows 워크로드를 배포하고 공유 VPC 네트워크 및 Active Directory 포레스트를 사용할 수 있도록 합니다.
  • Active Directory 포레스트를 기존 온프레미스 포레스트와 통합하여 리소스 포레스트 패턴을 구현합니다.

시작하기 전에

이 가이드의 안내를 따르려면 다음이 필요합니다.

  • 두 서브넷의 서브넷 CIDR 범위:

    • 도메인 컨트롤러 서브넷. 이 서브넷에는 도메인 컨트롤러가 포함됩니다. 도메인 컨트롤러용 전용 서브넷을 사용하면 방화벽 규칙을 관리하거나 네트워크 로그를 분석할 때 도메인 컨트롤러 트래픽을 다른 서버 트래픽과 구분할 수 있습니다.

      크기가 /28 또는 /29인 서브넷 CIDR 범위를 사용하는 것이 좋습니다.

    • 리소스 서브넷. 이 서브넷에는 서버 및 관리 워크스테이션이 포함됩니다. 배포할 모든 서버를 수용할 수 있을 정도로 큰 서브넷 CIDR 범위를 사용합니다.

    서브넷이 온프레미스 서브넷과 겹치지 않도록 하고 충분한 공간을 확보하세요.

  • Active Directory 포레스트 루트 도메인의 DNS 도메인 이름과 NetBIOS 도메인 이름. 이름 선택에 대한 자세한 내용은 Microsoft 이름 지정 규칙을 참조하세요.

공유 네트워크 배포

이 섹션에서는 새 프로젝트를 만들고 이를 사용하여 공유 VPC 네트워크를 배포합니다. 나중에 이 네트워크를 사용하여 Active Directory 도메인 컨트롤러를 배포합니다.

프로젝트 만들기

이제 새 프로젝트를 만들고 이를 사용해서 공유 VPC 네트워크를 배포할 수 있습니다.

  1. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  2. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  3. API Compute Engine and Cloud DNS 사용 설정

    API 사용 설정

공유 네트워크를 배포하는 데 필요한 권한을 얻으려면 관리자에게 문의해서 프로젝트 또는 상위 폴더에 대해 다음 IAM 역할을 부여해 달라고 요청하세요.

역할 부여에 대한 자세한 내용은 액세스 관리를 참조하세요.

커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.

기본 VPC 삭제

기본적으로 Compute Engine은 만드는 새 프로젝트마다 기본 네트워크를 만듭니다. 이 네트워크는 자동 모드로 구성됩니다. 즉, 서브넷이 각 리전에 사전 할당되며 CIDR 범위가 자동으로 할당됩니다.

이 섹션에서는 이 VPC 네트워크를 서브넷이 2개 있고 커스텀 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. 기본 VPC를 삭제하세요.

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

커스텀 모드 VPC 네트워크 만들기

이제 VPC 호스트 프로젝트에서 커스텀 모드 VPC 네트워크를 만듭니다.

  1. PowerShell에서 다음 변수를 초기화합니다.

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

    다음을 바꿉니다.

    • VPC_NAME: VPC의 이름
    • 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. VPC를 만들고 공유 VPC 네트워크로 사용하도록 구성합니다.

    $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
    

서브넷 및 방화벽 규칙 배포

이제 VPC 내에서 Active Directory 통신을 허용하는 방화벽 규칙을 만듭니다.

  1. Cloud IAP TCP 전달을 통해 모든 VM 인스턴스에 RDP 연결을 허용합니다.

    & 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에서 도메인 컨트롤러로 Active Directory 로그온을 허용합니다.

    & 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. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  2. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  3. API Compute Engine and Secret Manager 사용 설정

    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: 이전에 만든 공유 VPC 네트워크의 이름
    • 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 전달 영역 만들기

이제 도메인 컨트롤러에 대해 2개의 고정 IP 주소를 예약하고 Active Directory 도메인의 모든 DNS 쿼리를 이러한 IP 주소로 전달하는 비공개 DNS 전달 영역을 만듭니다.

  1. 프로젝트를 공유 VPC 네트워크에 연결합니다.

    $ProjectId = gcloud config get-value core/project
    & gcloud compute shared-vpc associated-projects add $ProjectId --host-project $VpcProjectId
    
  2. 도메인 컨트롤러 서브넷에서 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 비밀번호 만들기

이제 디렉터리 서비스 복원 모드(DSRM) 비밀번호를 정의하고 Secret Manager에 저장합니다. 그런 다음 Active Directory 포레스트를 배포하는 데 사용할 수 있도록 도메인 컨트롤러 VM에 이 보안 비밀에 대한 임시 액세스 권한을 부여합니다.

  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. 서비스 계정에 1시간 동안 보안 비밀을 읽을 수 있는 권한을 부여합니다.

    $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 인스턴스 2개를 배포하고 새 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 $DomainNetbiosName `
            -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을 만듭니다.
    • DSRM 비밀번호에 액세스할 수 있도록 ad-domaincontroller 서비스 계정을 VM에 할당합니다.
    • 계정 관리자를 사용 중지하도록 게스트 에이전트를 구성합니다. 게스트 에이전트 구성에 대한 자세한 내용은 Windows 인스턴스 기능 사용 설정 및 중지를 참조하세요.
    • sysprep specialize 단계에서 VM이 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]
    

    Restarting to apply all settings... 메시지가 표시될 때까지 10분 정도 기다린 후 Ctrl+C를 누릅니다.

  5. 해당 직렬 포트 출력을 확인하여 두 번째 도메인 컨트롤러의 초기화 프로세스를 모니터링합니다.

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

    Restarting to apply all settings... 메시지가 표시될 때까지 10분 정도 기다린 후 Ctrl+C를 누릅니다.

이제 Active Directory 포레스트 및 도메인을 사용할 수 있습니다.

도메인 컨트롤러에 연결

이제 도메인 컨트롤러 중 하나에 연결하여 Active Directory 포레스트를 맞춤설정할 수 있습니다.

  1. PowerShell에서 Administrator 사용자의 비밀번호에 액세스합니다.

    gcloud secrets versions access latest --secret ad-password
    
  2. RDP를 사용하여 dc-1에 연결하고 Administrator 사용자로 로그온합니다.

    VM 인스턴스에 공개 IP 주소가 없으므로 IAP(Identity-Aware Proxy) TCP 전달을 통해 연결해야 합니다.

다음 단계