Let´s encrypt-Zertifikate automatisieren
Let´s encryp-Zertifikate autmatisieren
Sparfüchse aufgepasst! 🙂 Sicher hat der ein oder andere schon von Let´s encrypt gehört: Eine tolle Sache! Kostenlose SSL-Zertifikate, die von allen gängigen Browsern als vertrauenswürdig angesehen werden, SAN support…
Ab 01/2018 sollen sogar Wildcard-Zertifikate unterstützt werden. Über z.B. SSLforFree lässt sich recht bequem arbeiten und man erhält vor Ablauf der Zertifikate eine Erinnerungsmail, praktisch. Mindestens mal für Test- und Entwicklungssysteme sehr interessant!
Nicht ganz so trivial ist dabei aber die Erbringung des Nachweises, dass man Besitzer der jeweiligen öffentlichen Domänen ist. Es stehen 3 Überprüfungsmethoden zur Verfügung: Upload von Infos zu einem FTP-Server (noch keine Erfahrung), Upload zu einem HTTP-Server oder Upload zum öffentlichen DNS. Wir schauen uns kurz die letzten beiden an.
- DNS: Wenn ich ein Zertifikat für „sub.domain.com“ beantragen möchte, muss ich für diesen Namen im öffentlichen DNS einen speziellen TXT-Eintrag mit kryptischem Inhalt erstellen. Soweit, so gut. Wenn ich eine Reihe von SANs benötige, wird das schon etwas aufwändig und mühselig – je nach DNS-Provider und Güte des Tools kann es auch nervtötend werden.
- HTTP: Wenn ich ein Zertifikat für „sub.domain.com“ beantragen möchte, muss ich einen unter diesem Namen per HTTP (ohne „s“) erreichbaren Web-Server bereitstellen (!) und dort im WWW-Root ein Verzeichnis namens „.well-known“ sowie einen Unterordner „acme-challenge“ anlegen. Dort hinein kommen spezielle Dateien mit kryptischen Namen. Klingt kompliziert? Ist es auch. Mal eben einen Web-Server für jeden Namen bereitstellen ist schon eine Herausforderung. Hier ist es ja nicht nur damit getan, z.B. ein zusätzliches Binding im IIS zu konfigurieren (wenn denn überhaupt IIS zum Einsatz kommt). HTTP-Anfragen müssen auch von extern hereinkommen können und an die richtige Stelle gelangen – ein geeignetes HTTP-Publishing ist also Pflicht. Wenn ich auch noch eine Reihe von SANs benötige, brauche ich für alle Namen auch jeweils ein Publishing. Dieses muss jeweils zu einem Web-Server zeigen, in dessen WWW-Root ein Ordner „.well-known“ existiert, usw.
Übrigens: Einmal präpariert, sind die Nachweise nicht von Dauer. Nach 90 Tagen verlieren sie ihre Gültigkeit und müssen erneuert werden.
Das wäre alles halb so schlimm, wenn die eigentlichen Zertifikate länger gültig wären. Sind sie aber leider nicht: Nach 3 Monaten ist auch hier Schluss und sie müssen erneuert werden. Dies gilt auch für die o.g. Autorisierungsnachweise. Und dann wäre da noch eine Kleinigkeit: Die neuen Zertifikate müssen ja auch noch den anhängigen Diensten wie z.B. Exchange, ADFS, WAP, RDS oder IIS bekannt gemacht werden, das war ja Ziel des Spiels. Natürlich kann man all das manuell machen. Mit einer guten Doku kann das sogar gut funktionieren. Aber bequem ist anders und wenn viele Dienste aktualisiert werden müssen, artet das in eine Menge Arbeit aus. Nun gut – ohne Herausforderungen wird es schnell langweilig. Es muss also eine bessere Lösung her…
Kann man das nicht irgendwie automatisieren?
Einige findige Leute haben sich diese Frage auch schon gestellt und bemerkenswerte Lösungen auf Powershell-Basis (ACMESharp Modul) entwickelt. Diese sind jeweils auf bestimmte Zielsysteme zugeschnitten, z.B.
a) für Exchange von Frank Zoechling,
b) für RDS-Server von Daniel Melanchthon oder
c) für IIS-WebServer von Marc Durdin.
Wohlgemerkt sind alle Lösungen auf exakt einen Server geeicht – also für jeden Server ein eigenes Zertifikat. Hat man mehr als 1 Exchange Server (z.B. in einer DAG) oder eine aus mehreren Servern bestehende RDS-Farm, muss man die Skripte nachfeilen.
Das Prinzip bei allen:
- Autorisierungsinfos für die öffentlichen Domänen erstellen
- Der eine (b) favorisiert DNS , weil es simpler ist und weniger Anpassungen in der Infrastruktur erfordert. Allerdings ist hier die Automatisierung schwierig – je nach DNS-Provider mal mehr, mal weniger. Eine Standardlösung für alle DNS-Provider ist nur schwer vorstellbar.
- Die anderen (a, c) favorisieren HTTP, weil es tatsächlich vollständig automatisierbar ist. Diverse Publishings mit geschickten Umleitungen etc. sind aufwändig und komplex, der Aufwand fällt aber bei gleichbleibenden Domänen nur einmal an.
- Anfordern des Zertifikats, dabei Überprüfung der in Schritt 1 erstellten Autorisierungsinfos
- Export des Zertifikats ins PFX-Format
- Einbinden des Zertifikats in die jeweiligen Dienste
Sofern man kein Problem mit der HTTP-Variante und ihren Nachteilen hat (und sich alles um Single-Server-Deployments dreht), lassen sich die Skripte a) für Exchange Server und c) für IIS-WebServer schon mal prima einsetzen. Gleiches gilt für RDS und b) wenn man mit einer Halbautomatik erst einmal zufrieden ist.
Ich für meinen Teil hatte für meine Testumgebung etwas speziellere Wünsche. Da ich dort nur eine öffentliche IP habe und einen großen Fuhrpark von Servern, Diensten und (sub-)domains versorgen muss, benötige ich ein SAN-Zertifikat mit sämtlichen DNS-Namen, das auf viele verschiedene Server zum Einsatz kommt. D.h. ich musste dafür sorgen, dass Autorisierungsinfos für alle Domänen zugreifbar sind. Nach einigen Modifikationen war das Skript von Frank Zoechling soweit, dass es im WWW-Root eines Web-Servers die Infos für alle Domänen ablegte.

Nun noch eine Veröffentlichungsregel auf dem guten alten TMG, die incoming HTTP an diese Domänen zum obigen Web-Server leitet.

Damit war Punkt 1 erledigt, Punkt 2 und 3 funktionierten ohne weitere Modifikationen.

Punkt 4 sind eigene, separate Skripte auf den jeweiligen Zielservern (Exchange, ADFS, usw.), bislang noch nicht vollständig automatisiert. Bis hierhin zu kommen war schon eine Menge Arbeit, aber es hat sich gelohnt!
Es folgt eine Liste von Befehlen, die ich auf den jeweiligen Systemen abfeuere sowie ggf. weiterführende Infos.
Exchange 2016
- Import-ExchangeCertificate -FileName \\centralserver\share\certnewest.pfx -FriendlyName „SAN domain.com“ -Password (ConvertTo-SecureString „HOCHGEHEIMESPASSWORT“ -AsPlainText -Force) -PrivateKeyExportable:$true | Enable-ExchangeCertificate -Services „SMTP, IMAP, POP, IIS“ -force
Exchange 2010
- $ex=Import-ExchangeCertificate -FileData ([Byte[]]$(Get-Content -Path \\centralserver\share\certnewest.pfx -Encoding byte -ReadCount 0)) -FriendlyName $ExchangeSubject -Password (ConvertTo-SecureString „HOCHGEHEIMESPASSWORT“ -AsPlainText -Force) -PrivateKeyExportable:$true
- Enable-ExchangeCertificate -Services „SMTP, IMAP, POP, IIS“ -force -thumbprint $ex.Thumbprint
IIS
- Teile bei Marc Durdin geklaut und angepasst.
RDS
- Hier habe ich ein Skript von Ryan Mangan angepasst und um Teile von Daniel Melanchthon ergänzt
ADFS
- Die Funktion „Set-CertificatePermission“ stammt auch aus den Tiefen des WWW
- $certresult=Import-PfxCertificate -CertStoreLocation cert:localmachine\my -FilePath \\centralserver\share\certnewest.pfx -Password (ConvertTo-SecureString „HOCHGEHEIMESPASSWORT“ -AsPlainText -Force)
- $installedcert=Get-ChildItem Cert:\LocalMachine\My | ? {$_.Thumbprint -eq $certresult.Thumbprint}
- Set-AdfsSslCertificate -Thumbprint $installedcert.Thumbprint
- Get-AdfsSslCertificate
- Set-CertificatePermission -pfxThumbPrint $installedcert.Thumbprint -serviceAccount „s_adfs“
- Set-AdfsCertificate -CertificateType Service-Communications -Thumbprint $certresult.Thumbprint
- Restart-Service adfssrv
WAP
- Hier fehlt noch die vernünftige Speicherung des „FederationServiceTrustCredential“, bislang nur interaktiv
- $certresult=Import-PfxCertificate -CertStoreLocation cert:localmachine\my -FilePath \\centralserver\share\certnewest.pfx -Password (ConvertTo-SecureString „HOCHGEHEIMESPASSWORT“ -AsPlainText -Force)
- $installedcert=Get-ChildItem Cert:\LocalMachine\My | ? {$_.Thumbprint -eq $certresult.Thumbprint}
- Install-WebApplicationProxy -FederationServiceTrustCredential (Get-Credential) -CertificateThumbprint $installedcert.Thumbprint -FederationServiceName ‚adfs.domain.com‘
Work Folders
- $certresult=Import-PfxCertificate -CertStoreLocation cert:localmachine\my -FilePath \\centralserver\share\certnewest.pfx -Password (ConvertTo-SecureString „HOCHGEHEIMESPASSWORT“ -AsPlainText -Force)
- cmd /c netsh http delete sslcert ipport=0.0.0.0:443
- cmd /c netsh http add sslcert ipport=0.0.0.0:443 certhash=$certresult.Thumbprint appid=“{CE66697B-3AA0-49D1-BDBD-A25C8359FD5D}“ certstorename=MY
Kemp VLM, SharePoint
- Offen: Hier muss ich mir noch etwas überlegen/auf die Suche gehen
Fazit: Das Ganze ist noch eine offene Baustelle, von einer vollständigen Automatisierung bin ich noch ein Stück entfernt. Nichtsdestotrotz ist auch der aktuelle Stand mehr als nützlich und vereinfacht die Angelegenheit enorm. Let´s encrypt-Zertifikate sind eine tolle Sache. Aller Automatisierung zum Trotz sollten diese jedoch meiner Meinung nach Stand heute besser nicht in produktiven Umgebungen eingesetzt werden. Dann lieber ein paar Euro in ein 3 Jahre gültiges Zertifikat investieren. Für Test- und Entwicklungsumgebungen eignet sich das Ganze aber sehr gut!
Ich hoffe, diese Infos sind für den ein oder anderen nützlich.