Download als Word document

Dit artikel beschrijft de volledige opbouw van een twee-server Windows Server 2022 home lab in Proxmox VE. Samen leveren de twee virtuele machines Active Directory Domain Services, DNS, Group Policy en een Certificate Authority (ADCS). RDP-verbindingen worden beveiligd met PKI-certificaten, zodat de Mac Mini M1 als beheerstation zonder certificaatwaarschuwingen verbinding maakt.

Dit is deel 3 van de serie over het opbouwen van een Windows DevOps lab in Proxmox. In deel 1 beschrijf ik hoe je een VM aanmaakt en in deel 2 hoe je de template voorbereidt.

Laboratoriumomgeving

OnderdeelWaarde
Proxmox-hostmacpro2013.local
Proxmox-consolehttps://macpro2013.local:8006
BeheerstationMac Mini M1
VM 1 - AD + DNSWS2022-AD-DNS - 192.168.178.210
VM 2 - CAWS2022-CA01 - 192.168.178.211
Standaard gateway192.168.178.1
Subnetprefix/24
DomeinLAB01.local
Resources (beide VMs)2 vCPU / 4 GB RAM
TemplateWS2022-TEMPLATE-BASE

Bouwvolgorde

De CA heeft een harde afhankelijkheid van een werkende AD en DNS. Bouw alles daarom in deze volgorde:

  1. Kloon WS2022-TEMPLATE-BASE naar WS2022-AD-DNS en stel hostnaam en vast IP in
  2. Installeer AD DS + DNS en promoveer naar Domain Controller
  3. Configureer DNS-zones, de SYSVOL-scriptmap en Group Policy
  4. Kloon WS2022-TEMPLATE-BASE naar WS2022-CA01 en voeg toe aan het domein
  5. Installeer ADCS (Enterprise Root CA), Web Enrollment en IIS
  6. Configureer certificaatsjablonen en CRL-distributiepunten
  7. Deploy Set-RDPCert.ps1 via SYSVOL en een Scheduled Task op beide servers
  8. Vertrouw het Root CA-certificaat op de Mac Mini M1

Stap 1 - WS2022-AD-DNS Klonen en Voorbereiden

Kloon WS2022-TEMPLATE-BASE naar WS2022-AD-DNS via de Proxmox-console. Stel 2 vCPU en 4 GB RAM in en koppel de VM aan de lab-bridge.

Log na het opstarten in als lokale Administrator en voer het volgende uit in een verhoogde PowerShell-sessie:

 1# UITVOEREN OP: WS2022-AD-DNS (192.168.178.210) - Elevated PowerShell
 2
 3# Hernoem de computer
 4Rename-Computer -NewName "WS2022-AD-DNS" -Force
 5
 6# Identificeer de actieve netwerkadapter
 7$adapter = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object -First 1
 8
 9# Verwijder eventuele DHCP-configuratie
10Remove-NetIPAddress -InterfaceIndex $adapter.ifIndex -Confirm:$false -ErrorAction SilentlyContinue
11Remove-NetRoute     -InterfaceIndex $adapter.ifIndex -Confirm:$false -ErrorAction SilentlyContinue
12
13# Wijs een vast IP-adres toe
14New-NetIPAddress `
15    -InterfaceIndex  $adapter.ifIndex `
16    -IPAddress       192.168.178.210 `
17    -PrefixLength    24 `
18    -DefaultGateway  192.168.178.1
19
20# Wijs DNS toe aan loopback - na AD DS-installatie wijzen naar eigen IP
21Set-DnsClientServerAddress `
22    -InterfaceIndex  $adapter.ifIndex `
23    -ServerAddresses 127.0.0.1
24
25# Herstart om de hostnaam toe te passen
26Restart-Computer -Force

Stap 2 - AD DS en DNS Installeren

Log na de herstart opnieuw in als lokale Administrator en voer het volgende uit:

 1# UITVOEREN OP: WS2022-AD-DNS (192.168.178.210) - Elevated PowerShell
 2
 3# Installeer AD DS en DNS met alle beheertools
 4Install-WindowsFeature `
 5    -Name AD-Domain-Services, DNS `
 6    -IncludeManagementTools `
 7    -IncludeAllSubFeature
 8
 9# Promoveer naar Domain Controller en maak het nieuwe forest aan
10Import-Module ADDSDeployment
11
12Install-ADDSForest `
13    -DomainName                    "LAB01.local" `
14    -DomainNetBiosName             "LAB01" `
15    -ForestMode                    "WinThreshold" `
16    -DomainMode                    "WinThreshold" `
17    -InstallDns                    $true `
18    -DatabasePath                  "C:\Windows\NTDS" `
19    -LogPath                       "C:\Windows\NTDS" `
20    -SysvolPath                    "C:\Windows\SYSVOL" `
21    -SafeModeAdministratorPassword (ConvertTo-SecureString "P@ssw0rd!DSRM2026" -AsPlainText -Force) `
22    -Force

De server herstart automatisch. Log daarna in als LAB01\Administrator.

Werk vervolgens de DNS-pointer bij en maak de reverse-zoekzone aan:

 1# UITVOEREN OP: WS2022-AD-DNS (192.168.178.210) - Elevated PowerShell
 2
 3# Update DNS-pointer naar eigen IP
 4$adapter = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object -First 1
 5Set-DnsClientServerAddress `
 6    -InterfaceIndex  $adapter.ifIndex `
 7    -ServerAddresses 192.168.178.210, 8.8.8.8
 8
 9# Maak reverse-zoekzone aan
10Add-DnsServerPrimaryZone `
11    -NetworkID        "192.168.178.0/24" `
12    -ReplicationScope "Forest"
13
14# Voeg PTR-record toe voor de AD-server
15Add-DnsServerResourceRecordPtr `
16    -ZoneName      "178.168.192.in-addr.arpa" `
17    -Name          "210" `
18    -PtrDomainName "WS2022-AD-DNS.LAB01.local."
19
20# Maak de SYSVOL-scriptmap aan
21$scriptShare = "\\LAB01.local\SYSVOL\LAB01.local\scripts"
22If (-Not (Test-Path $scriptShare)) {
23    New-Item -ItemType Directory -Path $scriptShare -Force
24}

Stap 3 - Group Policy Configureren

 1# UITVOEREN OP: WS2022-AD-DNS (192.168.178.210) - Elevated PowerShell
 2
 3Import-Module GroupPolicy
 4
 5# Maak het GPO aan en koppel het aan de domeinroot
 6$gpo = New-GPO -Name "LAB01-Core-Settings"
 7New-GPLink -Name "LAB01-Core-Settings" -Target "DC=LAB01,DC=local" -LinkEnabled Yes
 8
 9# NLA verplichten voor RDP
10Set-GPRegistryValue `
11    -Name "LAB01-Core-Settings" `
12    -Key  "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
13    -ValueName "UserAuthentication" -Type DWord -Value 1
14
15# TLS-beveiligingslaag instellen
16Set-GPRegistryValue `
17    -Name "LAB01-Core-Settings" `
18    -Key  "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
19    -ValueName "SecurityLayer" -Type DWord -Value 2
20
21# Hoog versleutelingsniveau
22Set-GPRegistryValue `
23    -Name "LAB01-Core-Settings" `
24    -Key  "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" `
25    -ValueName "MinEncryptionLevel" -Type DWord -Value 3
26
27# Automatische certificaatregistratie (computers en gebruikers)
28Set-GPRegistryValue `
29    -Name "LAB01-Core-Settings" `
30    -Key  "HKLM\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment" `
31    -ValueName "AEPolicy" -Type DWord -Value 7
32
33Set-GPRegistryValue `
34    -Name "LAB01-Core-Settings" `
35    -Key  "HKCU\SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment" `
36    -ValueName "AEPolicy" -Type DWord -Value 7

Stap 4 - WS2022-CA01 Klonen en Aan Domein Toevoegen

Kloon WS2022-TEMPLATE-BASE naar WS2022-CA01 met 2 vCPU en 4 GB RAM op dezelfde lab-bridge. Stel bij de eerste opstart hostnaam en vast IP in:

 1# UITVOEREN OP: WS2022-CA01 (192.168.178.211) - Lokale VM-console / Elevated PowerShell
 2
 3Rename-Computer -NewName "WS2022-CA01" -Force
 4
 5$adapter = Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object -First 1
 6Remove-NetIPAddress -InterfaceIndex $adapter.ifIndex -Confirm:$false -ErrorAction SilentlyContinue
 7Remove-NetRoute     -InterfaceIndex $adapter.ifIndex -Confirm:$false -ErrorAction SilentlyContinue
 8
 9New-NetIPAddress `
10    -InterfaceIndex  $adapter.ifIndex `
11    -IPAddress       192.168.178.211 `
12    -PrefixLength    24 `
13    -DefaultGateway  192.168.178.1
14
15# VERPLICHT: wijs DNS naar de AD-server
16Set-DnsClientServerAddress `
17    -InterfaceIndex  $adapter.ifIndex `
18    -ServerAddresses 192.168.178.210
19
20Restart-Computer -Force

Voeg de server na de herstart toe aan het domein:

 1# UITVOEREN OP: WS2022-CA01 (192.168.178.211) - Elevated PowerShell
 2
 3# Verifieer DNS-omzetting voor de domeintoevoeging
 4Resolve-DnsName LAB01.local
 5
 6# Voeg toe aan het domein
 7Add-Computer `
 8    -DomainName "LAB01.local" `
 9    -Credential (Get-Credential -Message "Voer LAB01\Administrator-gegevens in") `
10    -Restart -Force

Stap 5 - ADCS Installeren en de Certificate Authority Configureren

Log op WS2022-CA01 in als LAB01\Administrator:

 1# UITVOEREN OP: WS2022-CA01 (192.168.178.211) - Elevated PowerShell
 2
 3# Controleer en installeer IIS
 4Get-WindowsFeature Web-Server
 5Install-WindowsFeature Web-Server -IncludeManagementTools
 6
 7# Installeer de CA-rol en Web Enrollment
 8Install-WindowsFeature `
 9    -Name ADCS-Cert-Authority `
10    -IncludeManagementTools `
11    -IncludeAllSubFeature
12
13Install-WindowsFeature ADCS-Web-Enrollment -IncludeManagementTools
14
15# Verifieer installatie
16Get-WindowsFeature ADCS-Cert-Authority, ADCS-Web-Enrollment, Web-Server | `
17    Select-Object Name, Installed, DisplayName
18
19# Configureer de Enterprise Root CA
20Install-AdcsCertificationAuthority `
21    -CAType                    EnterpriseRootCA `
22    -CACommonName              "LAB01-Root-CA" `
23    -CADistinguishedNameSuffix "DC=LAB01,DC=local" `
24    -CryptoProviderName        "RSA#Microsoft Software Key Storage Provider" `
25    -KeyLength                 4096 `
26    -HashAlgorithmName         SHA256 `
27    -ValidityPeriod            Years `
28    -ValidityPeriodUnits       10 `
29    -DatabaseDirectory         "C:\Windows\system32\CertLog" `
30    -LogDirectory              "C:\Windows\system32\CertLog" `
31    -Force
32
33# Configureer Web Enrollment
34Install-AdcsWebEnrollment -Force
35
36# Verifieer
37Get-WindowsFeature ADCS-Web-Enrollment
38Get-Service W3SVC
39netstat -an | findstr :80
40
41# Test de Web Enrollment-pagina
42Invoke-WebRequest `
43    -Uri "http://localhost/certsrv" `
44    -UseDefaultCredentials `
45    | Select-Object StatusCode, StatusDescription

De Web Enrollment-pagina is bereikbaar via http://WS2022-CA01.LAB01.local/certsrv.


Stap 6 - RDP Beveiligen met Set-RDPCert.ps1

Maak het script in SYSVOL aan op WS2022-AD-DNS:

1# UITVOEREN OP: WS2022-AD-DNS (192.168.178.210) - Elevated PowerShell
2
3notepad \\LAB01.local\SYSVOL\LAB01.local\scripts\Set-RDPCert.ps1

Plak de volgende inhoud in Notepad, sla het bestand op en sluit Notepad:

 1#Requires -RunAsAdministrator
 2<#
 3.SYNOPSIS
 4    Koppelt een door de CA uitgegeven certificaat aan de RDP-listener bij elke opstart.
 5.DESCRIPTION
 6    Zoekt het meest recente geldige certificaat in Cert:\LocalMachine\My dat is
 7    uitgegeven door LAB01-Root-CA voor de FQDN van de lokale computer. Wordt geen
 8    certificaat gevonden, dan wordt auto-enrollment geactiveerd. Het geselecteerde
 9    certificaat-thumbprint wordt weggeschreven naar de RDP-Tcp-registersleutel,
10    waarna de Remote Desktop-service wordt herstart.
11.NOTES
12    Uitrollen via SYSVOL en uitvoeren als SYSTEM via Scheduled Task bij opstart.
13    Lab: LAB01.local - WS2022-AD-DNS / WS2022-CA01
14#>
15
16Set-StrictMode -Version Latest
17$ErrorActionPreference = 'Stop'
18
19$LogFile = "C:\Scripts\Set-RDPCert.log"
20
21function Write-Log {
22    param([string]$Message)
23    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
24    "$timestamp  $Message" | Tee-Object -FilePath $LogFile -Append | Write-Host
25}
26
27Write-Log "=== Set-RDPCert.ps1 gestart ==="
28
29# 1. FQDN van de computer bepalen
30$fqdn = [System.Net.Dns]::GetHostEntry('').HostName
31Write-Log "FQDN: $fqdn"
32
33# 2. Geldig certificaat zoeken, uitgegeven door LAB01-Root-CA
34$rdpCert = Get-ChildItem Cert:\LocalMachine\My |
35    Where-Object {
36        $_.Issuer    -like "*LAB01-Root-CA*"  -and
37        $_.Subject   -like "*$fqdn*"           -and
38        $_.NotAfter  -gt (Get-Date)            -and
39        $_.HasPrivateKey
40    } |
41    Sort-Object NotAfter -Descending |
42    Select-Object -First 1
43
44# 3. Geen certificaat gevonden: auto-enrollment activeren en opnieuw zoeken
45if (-not $rdpCert) {
46    Write-Log "Geen geldig certificaat gevonden - auto-enrollment activeren..."
47    & certutil -pulse | Out-Null
48    Start-Sleep -Seconds 30
49
50    $rdpCert = Get-ChildItem Cert:\LocalMachine\My |
51        Where-Object {
52            $_.Issuer    -like "*LAB01-Root-CA*"  -and
53            $_.Subject   -like "*$fqdn*"           -and
54            $_.NotAfter  -gt (Get-Date)            -and
55            $_.HasPrivateKey
56        } |
57        Sort-Object NotAfter -Descending |
58        Select-Object -First 1
59}
60
61if (-not $rdpCert) {
62    Write-Log "FOUT: geen certificaat beschikbaar na auto-enrollment. Script afgebroken."
63    exit 1
64}
65
66Write-Log "Geselecteerd certificaat: $($rdpCert.Subject)"
67Write-Log "Thumbprint  : $($rdpCert.Thumbprint)"
68Write-Log "Geldig t/m  : $($rdpCert.NotAfter)"
69
70# 4. Network Service leesrechten geven op de private key
71$keyPath = $rdpCert.PrivateKey.CspKeyContainerInfo.UniqueKeyContainerName
72if ($keyPath) {
73    $keyFile = Get-ChildItem "$env:ProgramData\Microsoft\Crypto\RSA\MachineKeys\$keyPath" `
74               -ErrorAction SilentlyContinue
75    if ($keyFile) {
76        $acl  = Get-Acl $keyFile.FullName
77        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule(
78                    "NT AUTHORITY\NETWORK SERVICE", "Read", "Allow")
79        $acl.AddAccessRule($rule)
80        Set-Acl -Path $keyFile.FullName -AclObject $acl
81        Write-Log "ACL private key bijgewerkt voor NETWORK SERVICE."
82    }
83}
84
85# 5. Certificaat koppelen aan de RDP-listener
86$rdpReg = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
87Set-ItemProperty -Path $rdpReg -Name SSLCertificateSHA1Hash -Value $rdpCert.Thumbprint
88Write-Log "Register bijgewerkt met nieuw thumbprint."
89
90# 6. Remote Desktop Services herstarten om het nieuwe certificaat toe te passen
91Write-Log "TermService herstarten..."
92Restart-Service -Name TermService -Force
93Write-Log "TermService herstart."
94
95Write-Log "=== Set-RDPCert.ps1 succesvol afgerond ==="

Kopieer het script daarna lokaal en registreer de Scheduled Task op beide servers:

 1# UITVOEREN OP: BEIDE SERVERS - WS2022-AD-DNS + WS2022-CA01 - Elevated PowerShell
 2
 3# Lokale kopie aanmaken
 4If (-Not (Test-Path "C:\Scripts")) { New-Item -ItemType Directory -Path "C:\Scripts" -Force }
 5Copy-Item `
 6    -Path        "\\LAB01.local\SYSVOL\LAB01.local\scripts\Set-RDPCert.ps1" `
 7    -Destination "C:\Scripts\Set-RDPCert.ps1" `
 8    -Force
 9
10Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine -Force
11
12# Scheduled Task registreren
13$action    = New-ScheduledTaskAction `
14    -Execute "powershell.exe" `
15    -Argument "-NonInteractive -ExecutionPolicy Bypass -File C:\Scripts\Set-RDPCert.ps1"
16$trigger   = New-ScheduledTaskTrigger -AtStartup
17$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
18$settings  = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hours 1) `
19    -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 5) -StartWhenAvailable $true
20
21Register-ScheduledTask `
22    -TaskName "Set-RDPCertificate" -TaskPath "\LAB01\" `
23    -Action $action -Trigger $trigger -Principal $principal -Settings $settings `
24    -Description "Koppelt CA-certificaat aan RDP bij elke opstart" -Force
25
26# Direct uitvoeren voor de eerste installatie
27Start-ScheduledTask -TaskPath "\LAB01\" -TaskName "Set-RDPCertificate"

Stap 7 - Root CA-certificaat Vertrouwen op Mac Mini M1

 1# UITVOEREN OP: Mac Mini M1 - Terminal (macOS)
 2
 3# Download het Root CA-certificaat
 4curl -o ~/Downloads/LAB01-Root-CA.cer http://192.168.178.211/LAB01-Root-CA.cer
 5
 6# Installeer in de System Keychain als vertrouwde root
 7sudo security add-trusted-cert \
 8    -d \
 9    -r trustRoot \
10    -k /Library/Keychains/System.keychain \
11    ~/Downloads/LAB01-Root-CA.cer

Voeg beide VM’s toe in Microsoft Remote Desktop:

  • 192.168.178.210 - LAB01\Administrator - WS2022-AD-DNS
  • 192.168.178.211 - LAB01\Administrator - WS2022-CA01

RDP-verbindingen tonen nu geen certificaatwaarschuwingen meer.


Verificatie

 1# WS2022-AD-DNS - volledige DC-diagnose
 2dcdiag /test:Replications /test:DNS /test:KnowsOfRoleHolders /v
 3
 4# WS2022-CA01 - CA en Web Enrollment
 5Get-Service certsvc | Select-Object Name, Status
 6Get-WindowsFeature ADCS-Web-Enrollment
 7Get-Service W3SVC
 8netstat -an | findstr :80
 9certutil -CRL
10certutil -verifystore Root "LAB01-Root-CA"
11
12# Beide servers - RDP-certificaat verifiëren
13$rdpReg = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
14$thumb  = (Get-ItemProperty $rdpReg -Name SSLCertificateSHA1Hash).SSLCertificateSHA1Hash
15Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq $thumb } |
16    Select-Object Subject, Thumbprint, NotAfter, Issuer

Download

De volledige handleiding, inclusief alle commando’s, het complete Set-RDPCert.ps1-script, troubleshooting en naslag, is ook beschikbaar als Word-document:

WS2022-Lab-Handleiding-NL.docx