Seiten

Freitag, 24. Juli 2026

Let's Encrypt Zertifikate für Exchange automatisieren mit win-acme



Ein öffentliches Zertifikat gehört auf jeden Exchange-Server, der von aussen erreichbar ist. Der lästige Teil ist die Erneuerung: Let's-Encrypt-Zertifikate laufen nach 90 Tagen ab, und niemand will das alle drei Monate von Hand machen. Mit win-acme lässt sich das komplett automatisieren, inklusive Zuweisung an die Exchange-Dienste und geplanter Erneuerung. In diesem Beitrag zeige ich den kompletten Weg, und ich gehe auf einen kleinen Stolperstein im mitgelieferten Exchange-Skript ein, der mich kurz aufgehalten hat.

Warum win-acme

win-acme (WACS) ist ein schlanker ACMEv2-Client für Windows. Er fordert das Zertifikat bei Let's Encrypt an, legt es im Windows-Zertifikatspeicher ab, weist es über ein mitgeliefertes Skript den Exchange-Diensten zu und erstellt selbst eine geplante Aufgabe für die automatische Erneuerung. Kein zusätzlicher Dienst, keine wiederkehrende Handarbeit.

Voraussetzungen

Bevor es losgeht, sollten diese Punkte stehen:

  • win-acme in der "pluggable"-Variante herunterladen und das ZIP vor dem Entpacken entsperren (Rechtsklick, Eigenschaften, Zulassen)
  • Ausführung als Administrator direkt auf dem Exchange-Server
  • Die gewünschten Hostnamen müssen von aussen auf Port 80 erreichbar sein, denn die HTTP-01-Validierung von Let's Encrypt spricht diesen Port an

Ein Detail aus der Praxis: In meinem Fall lagen die Namen auf zwei verschiedenen öffentlichen IPs. owa und autodiscover zeigten auf die eine, smtp auf die andere. Das ist kein Problem, solange auf beiden IPs Port 80 zum selben Exchange-Server durchgereicht ist. Die selfhosting-Validierung von win-acme nutzt HTTP.SYS und läuft dadurch problemlos parallel zu IIS auf Port 80.

Der Befehl

Statt sich durch das interaktive Menü zu klicken, nehme ich den unattended-Aufruf. Der ist reproduzierbar, dokumentierbar und legt die geplante Aufgabe gleich mit an:

wacs.exe ^
  --source manual ^
  --host owa.example.com,autodiscover.example.com,smtp.example.com ^
  --commonname owa.example.com ^
  --validation selfhosting ^
  --store certificatestore ^
  --certificatestore My ^
  --installation script ^
  --script ".\Scripts\ImportExchange.ps1" ^
  --scriptparameters "'{CertThumbprint}' 'IIS,SMTP' '1'" ^
  --emailaddress admin@example.com ^
  --accepttos

Zwei Parameter verdienen eine kurze Erklärung. Mit --certificatestore My landet das Zertifikat im Personal-Store des Computers, wo Exchange es findet. Der win-acme-Standard "WebHosting" passt für Exchange nicht. Und --script ruft das mitgelieferte ImportExchange.ps1 auf, das intern Enable-ExchangeCertificate ausführt.

Der Stolperstein: LeaveOldExchangeCerts

Und genau hier liegt der Haken. Beim ersten Versuch habe ich den dritten Skript-Parameter, wie in vielen älteren Anleitungen zu lesen, als 'true' übergeben. Das Ergebnis:

Script error: ImportExchange.ps1 : Cannot process argument transformation
on parameter 'LeaveOldExchangeCerts'. Cannot convert value "true" to type
"System.Int32". Error: "Input string was not in a correct format."

In der aktuellen win-acme-Version ist der Parameter LeaveOldExchangeCerts im Skript als [int] deklariert, nicht als String oder Boolean. Ein 'true' lässt sich nicht in eine Zahl umwandeln, das Skript bricht ab.

Die Tücke daran: Das Zertifikat wird trotzdem korrekt ausgestellt und im Store abgelegt. Nur die Zuweisung an die Exchange-Dienste findet nicht statt, weil das Skript vor dem Enable-ExchangeCertificate abbricht. Ein Blick mit Get-ExchangeCertificate zeigt dann ein gültiges Zertifikat mit Services : None. Wer nur auf "Zertifikat da, alles gut" schaut, übersieht das leicht.

Die Lösung ist simpel: Der dritte Parameter gehört als Zahl übergeben. '1' bedeutet "alte Zertifikate stehen lassen", '0' entfernt sie. Deshalb steht im Befehl oben bereits '1'.

Mein Tipp: Vor dem ersten Lauf einen Blick in die param()-Zeile von Scripts\ImportExchange.ps1 werfen. Die Typen der Parameter ändern sich zwischen Versionen, und ein kurzer Blick spart die Fehlersuche.

Zuweisung nachträglich korrigieren

Ist das Zertifikat bereits ausgestellt, aber nicht zugewiesen, muss man nicht gleich ein neues anfordern. Die Zuweisung lässt sich direkt nachholen:

Enable-ExchangeCertificate -Thumbprint <Thumbprint> -Services IIS,SMTP

Alternativ den win-acme-Befehl einfach erneut ausführen, diesmal mit '1'. win-acme verwendet dann das gecachte Zertifikat wieder, verbraucht also kein weiteres Let's-Encrypt-Zertifikat, weist es diesmal korrekt zu und speichert die korrigierten Parameter für die Erneuerung.

Kontrolle

Get-ExchangeCertificate -Thumbprint <Thumbprint> |
  Format-List Thumbprint,Services,NotAfter,Subject

Erwartet wird jetzt Services : IIS, SMTP, ein NotAfter rund 90 Tage in der Zukunft und der richtige Subject.

Automatische Erneuerung

Die geplante Aufgabe legt win-acme selbst an. Sie prüft täglich und erneuert rechtzeitig vor Ablauf. Bei jeder Erneuerung läuft ImportExchange.ps1 erneut und bindet das neue Zertifikat an die Dienste. Damit ist der Kreis geschlossen, ohne dass man sich den Ablauftermin im Kalender notieren muss. Die Konfiguration der Erneuerung liegt als JSON unter C:\ProgramData\win-acme und lässt sich dort bei Bedarf direkt anpassen, falls man die Skript-Parameter nachträglich korrigieren muss.

Ein Hinweis für Hybrid-Umgebungen

Wer den Exchange in einem Hybrid mit Exchange Online betreibt, sollte einen Punkt im Kopf behalten. Die Hybrid-Connectors referenzieren das Transport-Zertifikat über TlsCertificateName, und das setzt sich aus Issuer und Subject zusammen. Solange Let's Encrypt bei der Erneuerung denselben Subject und denselben Issuer verwendet, bleibt die Bindung gültig. Wechselt Let's Encrypt aber das Zwischenzertifikat, ändert sich der Issuer, und der TlsCertificateName der Connectors stimmt nicht mehr. Dann bricht der abgesicherte Mailfluss, bis man die Bindung aktualisiert. Für produktive Hybrid-Umgebungen lohnt es sich deshalb, im Erneuerungs-Skript zu prüfen, ob Issuer und Subject noch passen, und bei Bedarf Set-SendConnector und Set-ReceiveConnector nachzuziehen. Manche entscheiden sich in diesem Szenario bewusst für ein kommerzielles Zertifikat mit einem Jahr Laufzeit.

Fazit

win-acme nimmt einem die Zertifikatsverwaltung auf Exchange fast vollständig ab. Der einzige echte Stolperstein war der als Integer deklarierte LeaveOldExchangeCerts-Parameter, der bei einem 'true' still das Zertifikat ausstellt, aber nicht zuweist. Wer den dritten Parameter als '1' übergibt und nach dem Lauf einmal Get-ExchangeCertificate prüft, ist auf der sicheren Seite.

Fragen oder Ergänzungen? Schreibt mir gerne an b.brunner@itrain.ch.

Keine Kommentare:

Kommentar veröffentlichen