Exchange Zertifikate Rechte
Wieder einmal stand eine einfache Verlängerung eines Exchange SMTP-Transport-Zertifikats an. Der Weg war aber steinig und hat mir viele Details zu Exchange und Zertifikate geliefert.
Beachten Sie dazu auch die Seite Exchange Zertifikat Insights
Auslöser
Wer Exchange Hybrid betreibt ist gut damit beraten, für den SMTP-Transport ein eigenes Zertifikat zu nutzen und nicht ein Wildcard, welches z.B. auch der reguläre Mailserver zum Versand verwendet. Es muss aber ein öffentliches Zertifikat sein, damit Exchange Online den OnPremises-Server eingehend akzeptiert und als "OnPremises-Connector" über die "Org-Connector Attribution" erkennt oder Sie nutzen eine separate Source-IP ihrer OnPremises Umgebung als Kriterium. In die Gegenrichtung von Exchange Online zu Exchange OnPremises können Sie TLS auch mit beliebigen Zertifikaten zulassen.
Wir haben ein Zertifikats-Request erstellt und von der öffentlichen PKI signieren lassen und wieder eingespielt. Natürlich haben wir an die Pflege der SAN-Namen, die Installation der Intermediate-CAs und die Auswahl des richtigen Keyproviders (Nicht CNG!) geachtet. In der MMC war das alte und das neue Zertifikat nebeneinander sichtbar und beide hatten auch einen privaten Schlüssel.
Dennoch war schon nach der Installation des Zertifikats samt privatem Key auf dem Exchange Server keine Mailkommunikation mehr möglich. Ich nutze zum Test dazu mein Skript Get-TCPCert.
PS C:\Script> .\get-tcpcert.ps1 -remotehost localhost -port 25 -sniname hybrid.msxfaq.com -starttls datetime : 2024-10-13 08:37:26Z remotehost : localhost sniname : hybrid.msxfaq.com dnsanswer : localhost remoteip : 127.0.0.1 Port : 25 TCPStatus : TLSStatus : TLSHandshakeFail SslProtocol : Fail CipherAlgorithm : HashAlgorithm : KeyExchangeAlgorithm : CN : DnsNameList : Subject : NotAfter : NotBefore : validdays : Issuer : Thumbprint : SerialNumber : SignatureAlgorithmFriendlyName : RawData : Extensions : ExtensionSANName : ExtensionKeyUsages : dnstimems : 1 connecttimems : 1 tlstimems : 4 totaltimems : 7
Sobald ich das neue Zertifikat aus dem Computerstore entfernt habe, hat der Exchange Transport Service sofort und ohne Neustart wieder das alte noch gültige Zertifikat verwendet. Das hat natürlich meine Neugier geweckt aber vor allem hatte ich nur noch ein paar Tage Zeit das Zertifikat zu tauschen.
Wir haben das Problem letztlich durch eine neuen Zertifikats-Request gelöst. Die Ursache für das komische Verhalten von Exchange haben wir noch nicht final ermittelt. Die Seite und die Schritte der Fehlersuche sind aber vielleicht doch für den ein oder anderen Administrator interessant.
- Exchange and support for CNG/KSP certificates
https://jetzemellema.blogspot.com/2015/03/exchange-and-support-for-cngksp.html
Private Key Rechte
Nachdem ich das Zertifikat auf dem Produktionssystem erst mal wieder entfernt habe, habe ich auf einem Testsystem das Zertifikat importiert und mir die Details angeschaut. Es gibt z.B. einen Unterschied, ob ich ein Zertifikat als PFX-Datei per MMC oder Exchange Powershell importiere:
Schritt | PowerShell | MMC |
---|---|---|
Zertifikat einspielen |
Import-ExchangeCertificate ` -FileData ([System.IO.File]::ReadAllBytes('C:\Certificates\Transport2024.pfx')) ` -Password (Read-Host "Enter password" -AsSecureString) ` -PrivateKeyExportable $true Die Anforderung über ECP oder PowerShell mit und Installation ergibt identische Ergebnisse |
Doppelklick auf die PFX-Datei und Import in den Zertifikatspeicher des Computers.
|
Exchange Status |
Nach dem Import des Zertifikats ist es in allen drei Fällen in Exchange noch nicht aktiviert. [PS] C:\>Get-ExchangeCertificate Thumbprint Services Subject ---------- -------- ------- BBDD09730D0264FF7FA4AFD8FE078AC3E42DF14B ....... CN=hybrid.msxfaq.com, O=MSFAQ, L=Paderborn, S=Nor... 7BCD045D32EA19AC93C932D8E3C2F06E4EFA14CD ....SF. CN=Federation 6FC282ED7DD5A9409F29765319038E9AABE77F47 IP.WS.. CN=outlook.msxfaq.com, C=DE FD3714B3BF5C9B62FF2080DAF82A204F4F4B52A1 ....... CN=CLIUSR 0C11E52AB42DACBB7626C698BC4CEA203AEDF8AC ....S.. CN=hybrid.msxfaq.com, O=MSXFAQ, L=Paderborn, S=Nor... 6DAD3D03D52E69CF18FEAF7C20E325B74E4F3B57 ....S.. CN=EX1 3F593F7D40A31EB5306D542845FB5627D92BAD0A ....... CN=WMSvc-SHA2-EX1 8EABEC8EB8F4D14083BFE000BB2B544ADBAF74F4 ....S.. CN=Microsoft Exchange Server Auth Certificate Das erste Exchange Zertifikat hat noch kein "S" in den Services und die Ausgabe war bei beiden Import-Wegen identisch. Achtung:
|
|
Rechte auf privaten Schlüssel |
Ich habe mir über die MMC die Berechtigungen auf den privaten Key angeschaut. Das geht sehr einfach über die MMC:
Und hier gibt es tatsächlich Unterschiede je nach Importweg. |
|
Private Key Permission |
Beim Import über die PowerShell bekommt "SYSTEM" das Recht "Full Control", während Administrators nur "Read" bekommt.
|
Beim Import über die MMC bekommt "SYSTEM" ebenfalls das Recht "Full Control". Die Gruppe der Administrators bekommt nun aber auch ein "Full Control" und zusätzlich wird noch eine unbekannte "LogonSessionID" mit "Read" addiert.
|
Rechte nach Enable-ExchangeCertificate |
Wenn ich dann einen "Enable-ExchangeCertificate" ausführe, dann werden die Rechte um "NETWORK SERVICE" mit READ erweitert.
|
Wenn ich dann einen "Enable-ExchangeCertificate" ausführe, dann werden die Rechte um "NETWORK SERVICE" mit READ erweitert.
|
Das erscheint mir logisch, da die TransportDienste nicht mit "SYSTEM" sondern nur mit "Network Service" laufen:
Daher dürfte ein "Enable-ExchangeCertificate" schon sinnvoll und für viele andere Dienste auch erforderlich sein. Warum aber der Transport-Dienst auch ohne diese Recht zumindest eingehende Verbindungen mit dem neuen Zertifikat anbietet, bleibt mir ein Rätsel.
- Exchange Zertifikat Insights
- Selection of Inbound
Anonymous TLS Certificates
https://learn.microsoft.com/en-us/previous-versions/office/exchange-server-2010/bb430790(v=exchg.14191)
Certutil
Auch wenn das Problem durch ein ganz neues Zertifikat letztlich gelöst wurde, habe ich da alte Zertifikat noch weiter analysiert und mit CERTUTIL kann ich mir sowohl die PFX-Datei als auch ein installiertes Zertifikat anschauen.
Wichtig: Alle Befehle in einer administrativen Shell starten.
Direkt nach dem Request funktioniert ein "-VerifyKeys" ohne Probleme.
C:\>certutil -store my BBDD09730D0264FF7FA4AFD8FE078AC3E42DF14B -verifykeys my "Personal" ================ Certificate 2 ================ Serial Number: 06a89933175402e5d7fbe485f9c9623b Issuer: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US NotBefore: 18.10.2024 02:00 NotAfter: 18.10.2025 01:59 Subject: CN=hybrid.msxfaq.com, MSXFAQ, L=Paderborn, S=Nordrhein-Westfalen, C=DE Non-root Certificate Cert Hash(sha1): bbdd09730d0264ff7fa4afd8fe078ac3e42df14b Key Container = 6b6eaec653c539a3fff39ce5c34b39a3_784b76a9-b2fd-4090-ba30-bfcf8a033039 Simple container name: te-47c80fad-6df8-452c-9ae1-3a9a4064e407 Provider = Microsoft RSA SChannel Cryptographic Provider Encryption test passed CertUtil: -store command completed successfully.
Kaum habe ich aber einen "Enable-ExchangeCertificate" gemacht, funktioniert die Prüfung nicht mehr.
# Das neue Zertifikat C:\>certutil -store my BBDD09730D0264FF7FA4AFD8FE078AC3E42DF14B -verifykeys my "Personal" ================ Certificate 2 ================ Serial Number: 06a89933175402e5d7fbe485f9c9623b Issuer: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US NotBefore: 18.10.2024 02:00 NotAfter: 18.10.2025 01:59 Subject: CN=hybrid.msxfaq.com, MSXFAQ, L=Paderborn, S=Nordrhein-Westfalen, C=DE Non-root Certificate Cert Hash(sha1): bbdd09730d0264ff7fa4afd8fe078ac3e42df14b Key Container = 6b6eaec653c539a3fff39ce5c34b39a3_784b76a9-b2fd-4090-ba30-bfcf8a033039 Simple container name: te-47c80fad-6df8-452c-9ae1-3a9a4064e407 Provider = Microsoft RSA SChannel Cryptographic Provider Encryption test passed CertUtil: -store command FAILED: 0x80070050 (WIN32: 80 ERROR_FILE_EXISTS) CertUtil: The file exists.
# Problematisches Zertifikat C:\> certutil -store my CF8E46E1682273FBC901A752E47C837F8FB00E11 -verifykeys my "Personal" ================ Certificate 1 ================ Serial Number: 0ae57ddbb755f07a62922a82c40c2263 Issuer: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US NotBefore: 14.10.2024 02:00 NotAfter: 15.10.2025 01:59 Subject: CN=hybrid.msxfaq.com, O=MSXFAQ, L=Paderborn, S=Nordrhein-Westfalen, C=DE Non-root Certificate Cert Hash(sha1): cf8e46e1682273fbc901a752e47c837f8fb00e11 Key Container = {19B15E64-E7E6-4273-8F62-65718173EBC4} Unique container name: d8e888d203ca20b86c23f8ba8546da56_f1a5d978-e239-405a-b311-95efaebc0482 Provider = Microsoft RSA SChannel Cryptographic Provider Private key is NOT exportable Encryption test passed CertUtil: -store command FAILED: 0x80070050 (WIN32: 80 ERROR_FILE_EXISTS) CertUtil: The file exists.
Der Fehler kommt aber sowohl beim funktionierenden als auch beim problematischen Zertifikat aber beide liefern auch einen "Encryption test passed".
Wenn ich den Aufruf ohne Admin-Rechte mache, dann erhalte ich einen "Access is Denied" und ein "Missing stored keyset". Das ist aber erwartet.
C:\> certutil -store my CF8E46E1682273FBC901A752E47C837F8FB00E11 -verifykeys my "Personal" ================ Certificate 1 ================ Serial Number: 0ae57ddbb755f07a62922a82c40c2263 Issuer: CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1, O=DigiCert Inc, C=US NotBefore: 14.10.2024 02:00 NotAfter: 15.10.2025 01:59 Subject: CN=hybrid.msxfaq.com, O=MSXFAQ, L=Paderborn, S=Nordrhein-Westfalen, C=DE Non-root Certificate Cert Hash(sha1): cf8e46e1682273fbc901a752e47c837f8fb00e11 Key Container = {19B15E64-E7E6-4273-8F62-65718173EBC4} Unique container name: d8e888d203ca20b86c23f8ba8546da56_f1a5d978-e239-405a-b311-95efaebc0482 Provider = Microsoft RSA SChannel Cryptographic Provider Missing stored keyset CertUtil: -store command FAILED: 0x80070005 (WIN32: 5 ERROR_ACCESS_DENIED) CertUtil: Access is denied.
Mit CERTUTIL kann ich daher ein installiertes Zertifikat prüfen aber weiter bin ich damit nicht gekommen.
Irritierend war dabei, dass ich das problematische Zertifikat auf dem Server problemlos an eine IIS-Instanz binden und nutzen konnte. Der private und öffentliche Schlüssel in der PFX-Datei passen zueinander.
- certutil - Verifykeys
https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/certutil#-verifykeys - CertUtil
https://www.axel-hahn.de/batch/helferlein-und-tabellen/alle-windows-kommandos?id=certutil
Zwischenstand
Der Import der PFX-Datei in zwei anderen Test-Umgebungen war problemlos möglich und das Zertifikat wurde vom Exchange Transport klaglos angenommen.
Da ich den Fehler nur auf diesen Servern nachstellen konnte aber das Zertifikat ansonsten überall sonst funktioniert, habe ich das Thema bislang nicht weiter verfolgt
Es hat mich aber schon gefuchst, dass ich die Ursache nicht ermitteln konnte. Weder im Application- noch Security-Eventlog oder mit aktiviertem CAPI2-Debugging war etwas zu finden. Auch das Hochsetzen des EventlogLevel der verschiedenen Exchange Transport Komponenten hat keine weiteren Eventlogs generiert. Ich wüsste wirklich gerne genauer, was den Exchange Transport dazu gebracht hat, das Zertifikat beim STARTTLS nicht auszuliefern. Der SMTP-Dienst hat nämlich schon STARTTLS angeboten und auf eine entsprechende Anforderung auch umgeschaltet. Allerdings auf das "CLIENT HELLO" nicht weiter reagiert. Das konnte ich mit WireShark noch sehen.
Weitere Links
- Office 365 Inbound Mailrouting
- OnPremises-Connector
- Org-Connector Attribution
- Get-TCPCert
- Exchange Zertifikat Insights
- CAPI2-Debugging
- WireShark
- Selection of Inbound
Anonymous TLS Certificates
https://learn.microsoft.com/en-us/previous-versions/office/exchange-server-2010/bb430790(v=exchg.14191) - Default permissions for the MachineKeys folders
https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/default-permissions-machinekeys-folders - Exchange and support for CNG/KSP certificates
https://jetzemellema.blogspot.com/2015/03/exchange-and-support-for-cngksp.html - Schannel – The internal error state is 10013 (Solved)
https://port135.com/schannel-the-internal-error-state-is-10013-solved/ - A fatal error occurred while creating a TLS client
credential. The internal error state is 10013
https://stackoverflow.com/questions/53121859/a-fatal-error-occurred-while-creating-a-tls-client-credential-the-internal-erro