이 문서에서는 Google Cloud에서 Active Directory를 실행하기 위한 권장사항에 설명된 권장사항을 준수하는 방식으로 Compute Engine에 Active Directory 포리스트를 배포하는 방법을 설명합니다.
이 가이드는 관리자 및 DevOps 엔지니어를 대상으로 합니다. 사용자가 Active Directory을 확실히 이해하며 Google Cloud 네트워킹 및 보안에 대한 기본 지식이 있다고 가정합니다.
아키텍처
배포는 두 프로젝트로 구성됩니다.
- 공유 VPC 네트워크, 비공개 DNS 전달 영역, Active Directory용 방화벽 규칙이 포함된 호스트 프로젝트
- 두 영역에 배포된 도메인 컨트롤러가 두 개 포함된 서비스 프로젝트
이 아키텍처를 통해 다음을 수행할 수 있습니다.
- 별도의 프로젝트에 Windows 워크로드를 추가로 배포하고 공유 VPC 네트워크와 Active Directory 포리스트가 이를 사용하도록 허용합니다.
- Active Directory 포레스트를 기존 온프레미스 포레스트와 통합하여 리소스 포레스트 패턴을 구현합니다.
시작하기 전에
이 가이드의 안내를 따르려면 다음이 있어야 합니다.
두 서브넷의 서브넷 CIDR 범위:
도메인 컨트롤러 서브넷 이 서브넷에는 도메인 컨트롤러가 포함됩니다. 도메인 컨트롤러에 전용 서브넷을 사용하면 방화벽 규칙을 관리하거나 네트워크 로그를 분석할 때 도메인 컨트롤러 트래픽을 다른 서버 트래픽과 구분하는 데 도움이 됩니다.
크기가
/28
또는/29
인 서브넷 CIDR 범위를 사용하는 것이 좋습니다.리소스 서브넷. 이 서브넷에는 서버 및 관리 워크스테이션이 포함됩니다. 배포하려는 모든 서버를 수용하기에 충분히 큰 서브넷 CIDR 범위를 사용합니다.
서브넷이 온프레미스 서브넷과 겹치지 않도록 하고 충분한 공간을 확보하세요.
Active Directory 포레스트 루트 도메인의 DNS 도메인 이름과 NetBIOS 도메인 이름. 이름 선택에 대한 자세한 내용은 Microsoft 이름 지정 규칙을 참조하세요.
공유 네트워크 배포
이 섹션에서는 새 프로젝트를 만들고 이를 사용하여 공유 VPC 네트워크를 배포합니다. 나중에 이 네트워크를 사용하여 Active Directory 도메인 컨트롤러를 배포합니다.
프로젝트 만들기
이제 새 프로젝트를 만들고 이를 사용해서 공유 VPC 네트워크를 배포할 수 있습니다.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Cloud DNS APIs.
공유 네트워크를 배포하는 데 필요한 권한을 얻으려면 관리자에게 문의해서 프로젝트 또는 상위 폴더에 대해 다음 IAM 역할을 부여해 달라고 요청하세요.
-
Compute 네트워크 관리자(
roles/compute.networkAdmin
) -
Compute 보안 관리자(
roles/compute.securityAdmin
) -
Compute 공유 VPC 관리자(
roles/compute.xpnAdmin
) -
DNS 관리자(
roles/dns.admin
)
역할 부여에 대한 자세한 내용은 액세스 관리를 참조하세요.
커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.
기본 VPC 삭제
기본적으로 Compute Engine은 사용자가 만드는 각 새 프로젝트에 기본 네트워크를 만듭니다. 이 네트워크는 자동 모드로 구성됩니다. 즉, 서브넷이 각 리전에 사전 할당되며 CIDR 범위가 자동으로 할당됩니다.
이 섹션에서는 이 VPC 네트워크를 2개의 서브넷이 포함되어 있고 커스텀 CIDR 범위를 사용하는 커스텀 모드 네트워크로 대체합니다.
Google Cloud 콘솔에서 Cloud Shell을 엽니다.
PowerShell을 시작합니다.
pwsh
새 프로젝트를 사용하도록 gcloud CLI를 구성합니다.
gcloud config set project PROJECT_ID
PROJECT_ID를 프로젝트의 ID로 바꿉니다.
기본 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 }
기본 VPC를 삭제하세요.
& gcloud compute networks list --format "value(name)" | % { gcloud compute networks delete $_ --quiet }
커스텀 모드 VPC 네트워크 만들기
이제 VPC 호스트 프로젝트에서 커스텀 모드 VPC 네트워크를 만듭니다.
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"
VPC를 만들고 공유 VPC 네트워크로 사용하도록 구성합니다.
$ProjectId = gcloud config get-value core/project & gcloud compute networks create $VpcName --subnet-mode custom & gcloud compute shared-vpc enable $ProjectId
Windows가 인터넷 액세스 없이 활성화할 수 있도록 서브넷을 만들고 비공개 Google 액세스를 사용 설정합니다.
& 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 통신을 허용하는 방화벽 규칙을 만듭니다.
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
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 전달 영역이 작동하는 데 필요합니다.
도메인 컨트롤러 간의 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
리소스 서브넷에 있는 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
보안 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를 구성하려는 경우에만 필요합니다.
(선택사항) 모든 실패한 액세스 시도를 로깅하는 방화벽 규칙을 만듭니다. 이 로그는 연결 문제를 진단하는 데 유용하지만 상당한 양의 로그 데이터를 생성할 수 있습니다.
& 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을 배포합니다.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Secret Manager APIs.
Active Directory 포레스트를 배포하는 데 필요한 권한을 얻으려면 관리자에게 프로젝트에 대한 다음 IAM 역할을 부여해 달라고 요청하세요.
-
Compute 인스턴스 관리자(v1)(
roles/compute.instanceAdmin.v1
) -
서비스 계정 관리자(
roles/iam.serviceAccountAdmin
) -
서비스 계정 사용자(
roles/iam.serviceAccountUser
) -
Secret Manager 관리자(
roles/secretmanager.admin
) -
IAP 보안 터널 사용자(
roles/iap.tunnelResourceAccessor
)
역할 부여에 대한 자세한 내용은 액세스 관리를 참조하세요.
커스텀 역할이나 다른 사전 정의된 역할을 통해 필요한 권한을 얻을 수도 있습니다.
구성 준비
다음 단계는 Active Directory 배포를 위한 구성을 준비하는 것입니다.
이전에 PowerShell 세션을 닫은 경우 Cloud Shell을 엽니다.
PowerShell을 시작합니다.
pwsh
새 프로젝트를 사용하도록 gcloud CLI를 구성합니다.
gcloud config set project DC_PROJECT_ID
DC_PROJECT_ID를 프로젝트의 ID로 바꿉니다.
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 호스트 프로젝트의 프로젝트 IDVPC_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 전달 영역 만들기
이제 도메인 컨트롤러에 대해 두 개의 고정 IP 주소를 예약하고 Active Directory 도메인에 대한 모든 DNS 쿼리를 이러한 IP 주소로 전달하는 비공개 DNS 전달 영역을 만듭니다.
프로젝트를 공유 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`)
VPC 호스트 프로젝트에서 Cloud DNS 비공개 전달 영역을 만들고 DNS 쿼리를 2개의 예약된 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에 이 보안 비밀에 대한 임시 액세스 권한을 부여합니다.
임의의 비밀번호를 생성하고 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
도메인 컨트롤러 VM 인스턴스의 서비스 계정을 만듭니다.
$DcServiceAccount = gcloud iam service-accounts create ad-domaincontroller ` --display-name "AD Domain Controller" ` --format "value(email)"
서비스 계정에 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 인스턴스 두 개를 배포하고 새 Active Directory 포리스트 및 도메인을 만듭니다. 수동 단계 수를 최소화하려면 시작 스크립트를 사용합니다.
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 보호를 사용 설정합니다.
첫 번째 도메인 컨트롤러의 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 비밀번호에 액세스할 수 있도록 VM에
ad-domaincontroller
서비스 계정을 할당합니다. - 계정 관리자를 사용 중지하도록 게스트 에이전트를 구성합니다. 게스트 에이전트 구성에 대한 자세한 내용은 Windows 인스턴스 기능 사용 설정 및 중지를 참조하세요.
- sysprep specialize 단계에서 VM이 Windows 기능
AD-Domain-Services
및DNS
를 설치하도록 합니다. - VM이 이전에 만든 시작 스크립트를 실행하도록 합니다.
두 번째 도메인 컨트롤러의 다른 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
직렬 포트 출력을 확인하여 첫 번째 도메인 컨트롤러의 초기화 프로세스를 모니터링합니다.
& gcloud compute instances tail-serial-port-output dc-1 --zone $Zones[0]
Restarting to apply all settings...
메시지가 표시될 때까지 10분 정도 기다린 후Ctrl+C
를 누릅니다.직렬 포트 출력을 확인하여 두 번째 도메인 컨트롤러의 초기화 프로세스를 모니터링합니다.
& gcloud compute instances tail-serial-port-output dc-2 --zone $Zones[1]
Restarting to apply all settings...
메시지가 표시될 때까지 10분 정도 기다린 후Ctrl+C
를 누릅니다.
이제 Active Directory 포레스트 및 도메인을 사용할 수 있습니다.
도메인 컨트롤러에 연결
이제 도메인 컨트롤러 중 하나에 연결하여 Active Directory 포리스트를 맞춤설정할 수 있습니다.
PowerShell에서
Administrator
사용자의 비밀번호에 액세스합니다.gcloud secrets versions access latest --secret ad-password
RDP를 사용하여
dc-1
에 연결하고Administrator
사용자로 로그인합니다.VM 인스턴스에 공개 IP 주소가 없으므로 IAP(Identity-Aware Proxy) TCP 전달을 통해 연결해야 합니다.
다음 단계
- 하이브리드 환경에서 Active Directory 사용 패턴에 대해 자세히 알아보기
- VM이 도메인에 자동 조인되도록 Active Directory 구성
- 방화벽에서 Active Directory 사용에 대해 자세히 알아보기