In einem vorherigen Artikel hatte ich bereits beschrieben, wie die kostenlosen Let’s Encrypt Zertifikate mittels PowerShell angefordert und den Exchange Diensten zugewiesen werden können.
Derzeit arbeite ich daran, den kompletten Prozess vom Anfordern des Let’s Encrypt Zertifikats bis zum automatischen Erneuern mit der PowerShell zu automatisieren. Ziel ist ein Fire-and-Forget Script für die Exchange Zertifikate, mal sehen ob es klappt.
In dem Anfangs verlinkten Artikel klappte bereits das Anfordern eines Zertifikats via Let’s Encrypt. Die Zertifikate sind allerdings nur 3 Monate gültig und müssen daher regelmäßig ausgetauscht werden.
Ich habe daher jetzt einmal das Erneuern des Zertifikats getestet, dafür habe ich das folgende Script verwendet:
Import-Module ACMESharp Import-Module Webadministration Add-PSSnapin *exchange* $PFXPasswort = Get-Random -Minimum 1000000 -Maximum 9999999 $CurrentCertThumbprint = (Get-ChildItem -Path IIS:SSLBindings | where {$_.port -match "443" -and $_.IPAddress -match "0.0.0.0" } | select Thumbprint).Thumbprint $ExchangeCertificate = Get-ExchangeCertificate -Thumbprint $CurrentCertThumbprint $ExchangeSANs = ($ExchangeCertificate.CertificateDomains).Address $ExchangeSubject = $ExchangeCertificate.Subject.Replace("CN=","") if ($ExchangeSANs -notcontains $ExchangeSubject) {$ExchangeSANs += $ExchangeSubject} $ExchangeSANs $ExchangeSANID = 1 foreach ($ExchangeSAN in $ExchangeSANs) { $CurrentDate = get-date -format ddMMyyyy $ACMEAlias = "Cert" + "$CurrentDate" + "-" + "$ExchangeSANID" $ExchangeSANID++ write-host "New Identifier:" New-ACMEIdentifier -Dns $ExchangeSAN -Alias $ACMEAlias write-host "Complete Challenge:" Complete-ACMEChallenge $ACMEAlias -ChallengeType http-01 -Handler iis -HandlerParameters @{ WebSiteRef = 'Default Web Site' } [Array]$ACMEAliasArray += $ACMEAlias if ($ExchangeSAN -match $ExchangeSubject) {$ExchangeSubjectAlias = $ACMEAlias} } foreach ($ACMEAlias in $ACMEAliasArray) { write-host "Submit Challange:" Submit-ACMEChallenge $ACMEAlias -ChallengeType http-01 } sleep -seconds 30 foreach ($ACMEAlias in $ACMEAliasArray) { write-host "Update:" Update-ACMEIdentifier $ACMEAlias } $SANAlias = "SAN" + "$CurrentDate" New-ACMECertificate $ExchangeSubjectAlias -Generate -AlternativeIdentifierRefs $ACMEAliasArray -Alias $SANAlias Submit-ACMECertificate $SANAlias sleep -seconds 30 Update-ACMECertificate $SANAlias $CertPath = "$env:temp" + "\" + "$SANAlias" + ".pfx" Get-ACMECertificate $SANAlias -ExportPkcs12 $CertPath -CertificatePassword $PFXPasswort $ImportPassword = ConvertTo-SecureString -String $PFXPasswort -Force –AsPlainText Import-ExchangeCertificate -FileName $CertPath -FriendlyName $ExchangeSubject -Password $ImportPassword -PrivateKeyExportable:$true | Enable-ExchangeCertificate -Services "SMTP, IMAP, POP, IIS" –force
Dieses Script diente nur zum Testen, es enthält noch keine Fehlerbehandlung, Doku oder ähnliches. Die gute Nachricht: Der Austausch des vorhandenen Let’s Encrypt Zertifikats hat funktioniert. Hier zwei Screenshots des Scripts:
Die PowerShell habe ich dazu als Administrator ausgeführt und ich habe die Testumgebung mit dem ursprünglichen Zertifikat verwendet um den Prozess des Erneuerns zu testen.
Zwei wichtige Bausteine für das Fire-and-Forget Script funktionieren also bereits grundlegend. Bis zum fertigen Tool dauert es aber noch etwas…
Funktioniert mit Exchange 2013 wunderbar.
Hab noch folgendes hinzugefügt, was das alte Certificate löscht und das Certificate in der Site „Exchange Back End“ anpasst, sowie Neustarte der Dienste durchführt.
Einfach am Ende hinzufügen.
Ich habe Remove-Item gewählt anstatt Remove-ExchangeCertificate, weil dieser Befehl das Entfernen manchmal nicht zulässt, da dieser nicht erkennt, dass das Zertifikat schon ersetzt worden ist, wenn man den Befehl mehrfach am Tag ausführt.
$binding = Get-WebBinding -name „Exchange Back End“ -Protocol „https“
$NewCertThumbprint = (Get-ChildItem -Path IIS:SSLBindings | where {$_.port -match „443“ -and $_.IPAddress -match „0.0.0.0“ } | select Thumbprint).Thumbprint
$binding.AddSslCertificate($NewCertThumbprint,“my“)
write-host „Restarting Services“
iisreset
Restart-Service MSExchangeUMCR
Restart-Service MSExchangeUM
Restart-Service MSExchangeMailboxAssistants
Get-ChildItem Cert:\LocalMachine\My\$CurrentCertThumbprint | Remove-Item
Hi Daniel,
das Exchange Backend Zertifikat muss nicht ausgetauscht werden. Für das Backend bleibt es beim Self Signed Zertifikat.
Gruß, Frank
Hi Franky,
gibt’s schon was neues in Punkto Exchange 2013 Test ? Weißt du schon mehr ob das Script auch mit dem 2013er funktioniert ?
Vielen Dank für deine super Beiträge !
Beste Grüße
Jochen Lody kannst du das bitte weiter ausführen?
„Passen muss für Letsencrypt nur die externe IP“: ich habe es bisher so verstanden, dass das eben nicht ausreicht. Es muss auch das Verzeichnis ‚.well-known‘ verfügbar sein.
Oder hast du den gesamten Prozess der Zertifikatausstellung auf einem zweiten Webserver ausgeführt? Dann entsteht doch aber zusätzlicher Aufwand um das Zertifikat auf den ‚echten‘ Server zu bringen…
Funktioniert das nur mit EX2016… oder auch mit früheren Versionen?
Hi,
bisher habe ich es nur mit Exchange 2016 getestet. Ich werde es noch mit Exchange 2013 ausprobieren.
Gruß, Frank
Wie gewohnt grandios
Zur Anmerkung von HHenning.
Ohne jetzt inhaltlich über das Unbehagen Port 80 zu öffnen zu diskutieren. Mann muss man nicht so unbedingt den Port 80 auf dem Exchange Webserver öffnen. Passen muss für Letsencrypt nur die externe IP. Ich habe, soweit ganz erfolgreich, einen zweiten Webserver benutzt und in der Firewall den Port 80 auf dessen interne IP weitergeleitet. HTTPS geht auf einen anderen. Die Webserver können auf die gleichen Domain Namen antworten.
Wahnsinniger Einsatz von Zeit und Gehirnschmalz, danke.
Was mich nur bei Lets Encrypt stört ist die Tatsache, dass ich den Exchange über Port 80 unverschlüsselt verfügbar machen muss.