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
| Onderdeel | Waarde |
|---|---|
| Proxmox-host | macpro2013.local |
| Proxmox-console | https://macpro2013.local:8006 |
| Beheerstation | Mac Mini M1 |
| VM 1 - AD + DNS | WS2022-AD-DNS - 192.168.178.210 |
| VM 2 - CA | WS2022-CA01 - 192.168.178.211 |
| Standaard gateway | 192.168.178.1 |
| Subnetprefix | /24 |
| Domein | LAB01.local |
| Resources (beide VMs) | 2 vCPU / 4 GB RAM |
| Template | WS2022-TEMPLATE-BASE |
Bouwvolgorde
De CA heeft een harde afhankelijkheid van een werkende AD en DNS. Bouw alles daarom in deze volgorde:
- Kloon
WS2022-TEMPLATE-BASEnaarWS2022-AD-DNSen stel hostnaam en vast IP in - Installeer AD DS + DNS en promoveer naar Domain Controller
- Configureer DNS-zones, de SYSVOL-scriptmap en Group Policy
- Kloon
WS2022-TEMPLATE-BASEnaarWS2022-CA01en voeg toe aan het domein - Installeer ADCS (Enterprise Root CA), Web Enrollment en IIS
- Configureer certificaatsjablonen en CRL-distributiepunten
- Deploy
Set-RDPCert.ps1via SYSVOL en een Scheduled Task op beide servers - 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-DNS192.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: