Exchange 2016: Let’s Encrypt Zertifikat erneuern

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:

Let's Encrypt erneuern

Let's Encrypt erneuern

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…

8 Gedanken zu „Exchange 2016: Let’s Encrypt Zertifikat erneuern“

  1. 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

    Antworten
  2. 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

    Antworten
  3. 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…

    Antworten
  4. 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.

    Antworten
  5. 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.

    Antworten

Schreibe einen Kommentar