Работа с сертификатами Exchange
Установка сертификатов для IMAP
В случае, если мы используем wildcard-сертификат, дополнительно назначать его отдельно - не требуется.
Необходимо только указать хостнейм для подключения, сервер сам найдёт wildcard-сертификат.
Set-IMAPSettings -X509CertificateName mail.domain.com
Действующий сертификат IMAP будет не виден в списке назначенных сертификатов для сервиса IMAP, если вывести его следующей командой:
Get-ExchangeCertificate | select Thumbprint, Services, NotAfter, Subject, CertificateDomains | where {$_.Services -match "IMAP"} | fl
Если нам всё-таки необходимо назначить сертификат IMAP напрямую, сделать это можно следующим образом:
Enable-ExchangeCertificate -Thumbprint 9043B6B42D0BB935E4CB84F81111506012322A51 -Services 'imap'
Назначение сертификата службам SMTP
Enable-ExchangeCertificate -Thumbprint 9043B6B42D0BB935E4CB84F81111506012322A51 -Services 'smtp'
Edge Transports
На серверах Edge Transport не стоит добавлять такие же сертификаты (скажем, один и тот же wildcard-сертификат), как и на mailbox ДЛЯ ВНУТРЕННЕГО ТРАНСПОРТА. В этом случае подписка может работать некорректно.
Данной командой можно узнать текущий сертификат smtp на Edge Transport:
Get-TransportService | fl *InternalT*
Импорт сертификата на сервер и замена
Начиная с Exchange Server 2019 CU12, сертификат можно импортировать только через PowerShell. Импортировать через веб-админку нельзя.
Пример командлета, импортирующего сертификат:
Import-ExchangeCertificate -Server "mx1" -FileData ([System.IO.File]::ReadAllBytes('C:\cert\cert.p12')) -PrivateKeyExportable:$true -Password (ConvertTo-SecureString -String 'password' -AsPlainText -Force)
После импорта сертификата - его можно назначать сервисам Exchange - к примеру, IIS.
Проверить назначенный сертификат легко в настройках IIS. Пример можно увидеть на скриншоте ниже.
Сертификат сайта Exchange Backend менять на внешний WildCard - не обязательно.
На серверы Edge Transports можно установить сертификат через оснастку mmc.
Изменение сертификата на send-connector
Если мы попробуем удалить старый сертификат после назначения нового через веб - мы получим сообщение, что сертификат нельзя удалять, т.к. он уже назначен коннектору отправки.
Это намекает нам на то, что сертификат необходимо поменять на коннекторе отправки тоже. Здесь есть нюанс, связанный с тем, что при простом выполнении команды Get-SendConnector | fl, мы не сможем получить thumbprint сертификата, а получим только имя. Если имена сертификатов совпадают, что часто бывает, когда продляем сертификат от одного и того же УЦ - потребуется сгенерировать имя нового сертификата специальным образом, как описано далее в этом разделе и установить его на коннектор.
В случае, если коннектор отправки реализован через сервера Edge - описанные действия выполняем на серверах Edge Transport, куда устаналиваем через mmc новый сертификат.
Чтобы определить - какие именно транспортные серверы участвуют в коннекторе отправки, выполняем команду:
Get-SendConnector -Identity "EdgeSync - Default-First-Site-Name to Internet" | Format-List SourceTransportServers
Для реализации данной задачи нам потребуется узнать thumbprints старого и нового сертификатов. Выполняем команду на сервере, где они установлены.
Get-ExchangeCertificate | Format-List FriendlyName,Subject,Issuer,CertificateDomains,Thumbprint,NotBefore,NotAfter
Для минимизации проблем с потоком почты - лучше остановить сервис транспорта (на всех серверах коннектора отправки):
Stop-Service MSExchangeTransport
Теперь очистим свойство сертификата коннектора отправки следующей командой:
Set-SendConnector -Identity "EdgeSync - Default-First-Site-Name to Internet" -TlsCertificateName $Null
Удаляем старый сертификат со ВСЕХ транспортных серверов (можно удалить через mmc):
Remove-ExchangeCertificate -Server MX_EDGE -Thumbprint <old certificate thumbprint>
Теперь сгенерируем имя для нового сертификата, используя полученный выше thumbprint:
$cert = Get-ExchangeCertificate -Thumbprint <new certificate thumbprint> $tlscertificatename = "<i>$($cert.Issuer)<s>$($cert.Subject)"
После чего, наконец, установим его на коннектор отправки, используя полученное имя:
Set-SendConnector -Identity "EdgeSync - Default-First-Site-Name to Internet" -TlsCertificateName $tlscertificatename
Запускаем транспортную службу на всех серверах, где останавливали:
Start-Service MSExchangeTransport
Если после этого мы хотим удалить старый сертификат, но всё равно получаем в веб-интерфейсе прежнюю ошибку - удаляем сертификат со всех серверов, на которых он установлен при помощи mmc.
Назначение нового сертификата для SMTP edge-транспорта
Назначения сертификата send-коннектору недостаточно. После этого обязательно назначить сертификат службам SMTP на Edge Transport серверах. Если этого не сделать, рискуем получить задержки при доставке писем, а также неработающее шифрование почты. В логах edge, расположенных в папке:
C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\Edge\ProtocolLog\SmtpSend
Обнаружим ошибку:
TLS negotiation failed with error UnknownCredentials
Если мы запустим на эджах команду Get-ExchangeCertificate, мы увидим, что новый сертификат (thumbprint которого будет и в логе) - не назначен сервису SMTP. Отметим thumbprint сертификата и назначим его ОДНИМ ИЗ сертификатов SMTP:
Enable-ExchangeCertificate CERT_THUMBPRINT -Services SMTP
Если мы используем один с серверами mailbox - wildcard сертификат - мы не хотим назначать его сертификатом по умолчанию, т.к. такие сертификаты на edge использовать нельзя и к тому же, сломает edge subscription. Поэтому, при выполнении командлета Enable-ExchangeCertificate - на запрос о замене сертификата следует ответить “n”. В этом случае сервису SMTP будет назначено несколько сертификатов, это позволит работать TLS на Send-коннекторе и оновременно не сломает работу edge subscription.
Два сертификата на SMTP:
Скрипт для определения используемого сертификата на SMTP-коннекторах на нескольких серверах
#Get all Exchange Servers in the environment $ExchangeServers = (Get-ExchangeServer |Where-Object {$_.ServerRole -like "mailbox"} )| Select-Object Name,DistinguishedName $Results = @() #Process Information ForEach($Server in $ExchangeServers){ $TransportCert = (Get-ADObject -Identity $Server.DistinguishedName -Properties *).msExchServerInternalTLSCert $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $CertBlob = [System.Convert]::ToBase64String($TransportCert) $Cert.Import([Convert]::FromBase64String($CertBlob)) $server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertSubject -Value $Cert.Subject $server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertFriendlyName -Value $Cert.FriendlyName $server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertThumbprint -Value $Cert.Thumbprint $server | Add-Member -MemberType NoteProperty -Name DefaultTLSCertExpireDate -Value $Cert.NotAfter $Results += $Server } #Show result $Results | Out-GridView