Samstag, 17. April 2021

Windows LDAPS mit Let's Encrypt Zertifikat

Seit Herbst 2020 erfordert Microsoft Secure Channel Binding für LDAP. Um Drittsysteme dennoch per Simple Bind mit dem Active Directory kommunizieren zu lassen, genügt es allerdings für eine verschlüsselte Kommunikation per LDAPS zu sorgen. Häufig verzichten Anbindungen auf einen Zertifikatscheck (TLS_REQCERT never).

Mit öffentlich gültigen Zertifikaten auf den Domain-Controllern ist das nicht notwendig. Dieser Beitrag zeigt, wie das unter bestimmten Voraussetzungen funktioniert.

Einer der Vorteile bei der Verwendung eines öffentlichen Domain Namens für Microsoft Active Directory ist die Möglichkeit, Let's Encrypt Zertifikate zu verwenden. Insbesondere die DNS-01 Challenge erlaubt es beliebige Zertifikate zu erstellen, für die nicht zwangsläufig ein Webserver existiert.

Außerdem kann mit DNS-01 ein Wildcard Zertifikat für die AD-Domain erstellt werden (domain.com + *.domain.com) . Was für diesen Anwendungsfall optimal ist - für kleine Netze ist der Sicherheitsverlust verschmerzbar.

Das Let's Encrypt Deployment Script wandelt das erhaltene Zertifikat in PKCS12 um es später in den Windows Zertifikatsspeicher importieren zu können und legt es in ein Intranet Verzeichnis:

openssl pkcs12 -export -in "${FULLCHAINFILE}" -inkey "${KEYFILE}" -out /var/www/intranet/${DOMAIN}.pfx -passout pass:some_very_secret_string
chown webmaster:www-data /var/www/intranet/*.pfx
chmod 640 /var/www/intranet/*.pfx

Auf einem Domain Controller wird per Geplanter Aufgabe ein Powershell Script aufgerufen, welches das Zertifikat vom Intranet lädt und in den Zertifikatsspeicher des NT-DirectoryServices (NTDS) = ActiveDirectory legt:

$cur = Get-Location

# Zertifikat herunterladen
Invoke-WebRequest "https://intranet.domain.com/domain.com.pfx" -OutFile "domain.com.pfx" -PassThru 
Start-Sleep -Milliseconds 500
$cert = "$cur\domain.com.pfx"

# Zertifikat aus Datei anlegen
$Flags = [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::MachineKeySet `
	-bor [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::PersistKeySet
$Certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($cert, "some_very_secret_string", $Flags)

# Zertifikat in den ComputerStore importieren
$Store = New-Object System.Security.Cryptography.X509Certificates.X509Store(
        [System.Security.Cryptography.X509Certificates.StoreName]::My, 
	    [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine)
$Store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$Store.Add($Certificate)
$Store.Close()

$thumbprint = $Certificate.thumbprint

# Auf den Remote Desktop Dienst kopieren
#$path = (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -Filter "TerminalName='RDP-tcp'").__path
#Set-WmiInstance -Path $path -argument @{SSLCertificateSHA1Hash=$thumbprint}

# Auf den ActiveDirectory Dienst (NTDS) kopieren (nur auf den DCs!!!)
$copyParameters = @{
    'Path' = "HKLM:\Software\Microsoft\SystemCertificates\MY\Certificates\$thumbprint"
    'Destination' = "HKLM:\SOFTWARE\Microsoft\Cryptography\Services\NTDS\SystemCertificates\My\Certificates\"
    'Recurse' = $true
}
Copy-Item @copyParameters

# Neustart des LDAP Dienstes
Start-Sleep -Milliseconds 1500
ldifde -i -f $cur\update_server_certificate_reload_ldaps.txt

Der Neustart des NTDS Dienstes funktioniert am einfachsten über das ldifde Kommando. Dazu muss die Textdatei update_server_certificate_reload_ldaps.txt im gleichen Verzeichnis folgenden Inhalt haben:

dn:
changetype: modify
add: renewServerCertificate
renewServerCertificate: 1
-

Anschließend kann die Verbindung getestet werden:

curl -v ldaps://dc01.domain.com

Keine Kommentare:

Kommentar veröffentlichen