Skip to content

Commit

Permalink
Merge pull request #2234 from microsoft/lusassl-hybridmailflowadjustm…
Browse files Browse the repository at this point in the history
…ents

Improve hybrid transport certificate testing
  • Loading branch information
dpaulson45 authored Dec 3, 2024
2 parents bc1ea32 + e2140d1 commit 24ca159
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
$tcpKeepAlive = $osInformation.RegistryValues.TCPKeepAlive
$organizationInformation = $HealthServerObject.OrganizationInformation

# cSpell:disable
$eopDomainRegExPattern = "^[^.]+\.mail\.protection\.(outlook\.com|partner\.outlook\.cn|office365\.us)$"
$remoteRoutingDomainRegExPattern = "^[^.]+\.mail\.(onmicrosoft\.com|partner\.onmschina\.cn|onmicrosoft\.us)$"
$serviceDomainRegExPattern = "^mail\.protection\.(outlook\.com|partner\.outlook\.cn|office365\.us)$"
# cSpell:enable

$baseParams = @{
AnalyzedInformation = $AnalyzeResults
DisplayGroupingKey = (Get-DisplayResultsGroupingKey -Name "Frequent Configuration Issues" -DisplayOrder $Order)
Expand Down Expand Up @@ -299,8 +305,8 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
$sendConnectors = $exchangeInformation.ExchangeConnectors | Where-Object { $_.ConnectorType -eq "Send" }

foreach ($sendConnector in $sendConnectors) {
$smartHostMatch = ($sendConnector.SmartHosts -like "*.mail.protection.outlook.com").Count -gt 0
$dnsMatch = $sendConnector.SmartHosts -eq 0 -and ($sendConnector.AddressSpaces.Address -like "*.mail.onmicrosoft.com").Count -gt 0
$smartHostMatch = ($sendConnector.SmartHosts -match $eopDomainRegExPattern).Count -gt 0
$dnsMatch = $sendConnector.SmartHosts -eq 0 -and ($sendConnector.AddressSpaces.Address -match $remoteRoutingDomainRegExPattern).Count -gt 0

if ($dnsMatch -or $smartHostMatch) {
$exoConnector.Add($sendConnector)
Expand All @@ -315,12 +321,17 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
$showMoreInfo = $false

foreach ($connector in $exoConnector) {
# Misconfigured connector is if TLSCertificateName is not set or CloudServicesMailEnabled not set to true
if ($connector.CloudEnabled -eq $false -or
$connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameEmpty") {

# If CloudServiceMailEnabled is not set to true it means the connector is misconfigured
# If no Fqdn is set on the connector, the Fqdn of the computer is used to perform best matching certificate selection
# There is a risk that the Fqdn is an internal one (e.g., server.contoso.local) which will lead to a broken hybrid mail flow in case that TlsCertificateName is not set
if (($connector.CloudEnabled -eq $false) -or
($null -eq $connector.Fqdn -and
$connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameEmpty")) {
$params = $baseParams + @{
Name = "Send Connector - $($connector.Identity.ToString())"
Details = "Misconfigured to send authenticated internal mail to M365." +
Details = "Misconfigured to send authenticated internal mail to M365" +
"`r`n`t`t`tFqdn set: $($null -ne $connector.Fqdn)" +
"`r`n`t`t`tCloudServicesMailEnabled: $($connector.CloudEnabled)" +
"`r`n`t`t`tTLSCertificateName set: $($connector.CertificateDetails.TlsCertificateNameStatus -ne "TlsCertificateNameEmpty")"
DisplayCustomTabNumber = 2
Expand All @@ -342,11 +353,11 @@ function Invoke-AnalyzerFrequentConfigurationIssues {
$showMoreInfo = $true
}

if ($connector.TlsDomain -ne "mail.protection.outlook.com" -and
if ($connector.TlsDomain -notmatch $serviceDomainRegExPattern -and
$connector.TlsAuthLevel -eq "DomainValidation") {
$params = $baseParams + @{
Name = "Send Connector - $($connector.Identity.ToString())"
Details = "TLSDomain not set to mail.protection.outlook.com"
Details = "TLSDomain not set to service domain (e.g.,mail.protection.outlook.com)"
DisplayCustomTabNumber = 2
DisplayWriteType = "Yellow"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ function Invoke-AnalyzerHybridInformation {
$exchangeInformation = $HealthServerObject.ExchangeInformation
$getHybridConfiguration = $HealthServerObject.OrganizationInformation.GetHybridConfiguration

# Check if the server is configured as sending or receiving transport server - if it is, the certificate used for hybrid mail flow must exist on the machine
$certificateShouldExistOnServer = $getHybridConfiguration.SendingTransportServers.DistinguishedName -contains $exchangeInformation.GetExchangeServer.DistinguishedName -or
$getHybridConfiguration.ReceivingTransportServers.DistinguishedName -contains $exchangeInformation.GetExchangeServer.DistinguishedName

if ($exchangeInformation.BuildInformation.VersionInformation.BuildVersion -ge "15.0.0.0" -and
$null -ne $getHybridConfiguration) {

Expand Down Expand Up @@ -354,6 +358,9 @@ function Invoke-AnalyzerHybridInformation {
}
} else {
$cloudConnectorTlsCertificateName = "Not set"

Write-Verbose "Server is configured for hybrid mail flow and the transport certificate should exist on this server? $certificateShouldExistOnServer"

if ($null -ne $connector.CertificateDetails.TlsCertificateName) {
$cloudConnectorTlsCertificateName = $connector.CertificateDetails.TlsCertificateName
}
Expand All @@ -365,87 +372,90 @@ function Invoke-AnalyzerHybridInformation {
}
Add-AnalyzedResultInformation @params

$params = $baseParams + @{
Name = "Certificate Found On Server"
Details = $connector.CertificateDetails.CertificateMatchDetected
DisplayWriteType = $cloudConnectorWriteType
}
Add-AnalyzedResultInformation @params

if ($connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameEmpty") {
# Don't perform the following checks if the server is not a sending or receiving transport server configured for hybrid mail flow (there is a high chance that the certificate didn't exist which is by design)
if ($certificateShouldExistOnServer) {
$params = $baseParams + @{
Details = "There is no 'TlsCertificateName' configured for this cloud mail enabled connector.`r`n`t`tThis will cause mail flow issues in hybrid scenarios. More information: https://aka.ms/HC-HybridConnector"
DisplayWriteType = $cloudConnectorWriteType
DisplayCustomTabNumber = 2
}
Add-AnalyzedResultInformation @params
} elseif ($connector.CertificateDetails.CertificateMatchDetected -eq $false) {
$params = $baseParams + @{
Details = "The configured 'TlsCertificateName' was not found on the server.`r`n`t`tThis may cause mail flow issues. More information: https://aka.ms/HC-HybridConnector"
DisplayWriteType = $cloudConnectorWriteType
DisplayCustomTabNumber = 2
Name = "Certificate Found On Server"
Details = $connector.CertificateDetails.CertificateMatchDetected
DisplayWriteType = $cloudConnectorWriteType
}
Add-AnalyzedResultInformation @params
} else {
Add-AnalyzedResultInformation -Name "Certificate Thumbprint(s)" @baseParams

foreach ($thumbprint in $($connector.CertificateDetails.CertificateLifetimeInfo).keys) {
if ($connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameEmpty") {
$params = $baseParams + @{
Details = $thumbprint
Details = "There is no 'TlsCertificateName' configured for this cloud mail enabled connector.`r`n`t`tThis will cause mail flow issues in hybrid scenarios. More information: https://aka.ms/HC-HybridConnector"
DisplayWriteType = $cloudConnectorWriteType
DisplayCustomTabNumber = 2
}
Add-AnalyzedResultInformation @params
}

Add-AnalyzedResultInformation -Name "Lifetime In Days" @baseParams

foreach ($thumbprint in $($connector.CertificateDetails.CertificateLifetimeInfo).keys) {
switch ($($connector.CertificateDetails.CertificateLifetimeInfo)[$thumbprint]) {
{ ($_ -ge 60) } { $certificateLifetimeWriteType = "Green"; break }
{ ($_ -ge 30) } { $certificateLifetimeWriteType = "Yellow"; break }
default { $certificateLifetimeWriteType = "Red" }
}

} elseif ($connector.CertificateDetails.CertificateMatchDetected -eq $false) {
$params = $baseParams + @{
Details = ($connector.CertificateDetails.CertificateLifetimeInfo)[$thumbprint]
DisplayWriteType = $certificateLifetimeWriteType
Details = "The configured 'TlsCertificateName' was not found on the server.`r`n`t`tThis may cause mail flow issues. More information: https://aka.ms/HC-HybridConnector"
DisplayWriteType = $cloudConnectorWriteType
DisplayCustomTabNumber = 2
}
Add-AnalyzedResultInformation @params
}
} else {
Add-AnalyzedResultInformation -Name "Certificate Thumbprint(s)" @baseParams

foreach ($thumbprint in $($connector.CertificateDetails.CertificateLifetimeInfo).keys) {
$params = $baseParams + @{
Details = $thumbprint
DisplayCustomTabNumber = 2
}
Add-AnalyzedResultInformation @params
}

$connectorCertificateMatchesHybridCertificate = $false
$connectorCertificateMatchesHybridCertificateWritingType = "Yellow"
if (($connector.CertificateDetails.TlsCertificateSet) -and
(-not([System.String]::IsNullOrEmpty($getHybridConfiguration.TlsCertificateName))) -and
($connector.CertificateDetails.TlsCertificateName -eq $getHybridConfiguration.TlsCertificateName)) {
$connectorCertificateMatchesHybridCertificate = $true
$connectorCertificateMatchesHybridCertificateWritingType = "Green"
}
Add-AnalyzedResultInformation -Name "Lifetime In Days" @baseParams

foreach ($thumbprint in $($connector.CertificateDetails.CertificateLifetimeInfo).keys) {
switch ($($connector.CertificateDetails.CertificateLifetimeInfo)[$thumbprint]) {
{ ($_ -ge 60) } { $certificateLifetimeWriteType = "Green"; break }
{ ($_ -ge 30) } { $certificateLifetimeWriteType = "Yellow"; break }
default { $certificateLifetimeWriteType = "Red" }
}

$params = $baseParams + @{
Details = ($connector.CertificateDetails.CertificateLifetimeInfo)[$thumbprint]
DisplayWriteType = $certificateLifetimeWriteType
DisplayCustomTabNumber = 2
}
Add-AnalyzedResultInformation @params
}

$params = $baseParams + @{
Name = "Certificate Matches Hybrid Certificate"
Details = $connectorCertificateMatchesHybridCertificate
DisplayWriteType = $connectorCertificateMatchesHybridCertificateWritingType
}
Add-AnalyzedResultInformation @params
$connectorCertificateMatchesHybridCertificate = $false
$connectorCertificateMatchesHybridCertificateWritingType = "Yellow"
if (($connector.CertificateDetails.TlsCertificateSet) -and
(-not([System.String]::IsNullOrEmpty($getHybridConfiguration.TlsCertificateName))) -and
($connector.CertificateDetails.TlsCertificateName -eq $getHybridConfiguration.TlsCertificateName)) {
$connectorCertificateMatchesHybridCertificate = $true
$connectorCertificateMatchesHybridCertificateWritingType = "Green"
}

if (($connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameSyntaxInvalid") -or
(($connector.CertificateDetails.GoodTlsCertificateSyntax -eq $false) -and
($null -ne $connector.CertificateDetails.TlsCertificateName))) {
$params = $baseParams + @{
Name = "TlsCertificateName Syntax Invalid"
Details = "True"
DisplayWriteType = $cloudConnectorWriteType
Name = "Certificate Matches Hybrid Certificate"
Details = $connectorCertificateMatchesHybridCertificate
DisplayWriteType = $connectorCertificateMatchesHybridCertificateWritingType
}
Add-AnalyzedResultInformation @params

$params = $baseParams + @{
Details = "The correct syntax is: '<I>X.500Issuer<S>X.500Subject'"
DisplayWriteType = $cloudConnectorWriteType
DisplayCustomTabNumber = 2
if (($connector.CertificateDetails.TlsCertificateNameStatus -eq "TlsCertificateNameSyntaxInvalid") -or
(($connector.CertificateDetails.GoodTlsCertificateSyntax -eq $false) -and
($null -ne $connector.CertificateDetails.TlsCertificateName))) {
$params = $baseParams + @{
Name = "TlsCertificateName Syntax Invalid"
Details = "True"
DisplayWriteType = $cloudConnectorWriteType
}
Add-AnalyzedResultInformation @params

$params = $baseParams + @{
Details = "The correct syntax is: '<I>X.500Issuer<S>X.500Subject'"
DisplayWriteType = $cloudConnectorWriteType
DisplayCustomTabNumber = 2
}
Add-AnalyzedResultInformation @params
}
Add-AnalyzedResultInformation @params
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ function Get-ExchangeConnectors {
$exchangeFactoryConnectorReturnObject = [PSCustomObject]@{
Identity = $ConnectorObject.Identity
Name = $ConnectorObject.Name
Fqdn = $ConnectorObject.Fqdn
Enabled = $ConnectorObject.Enabled
CloudEnabled = $false
ConnectorType = $null
Expand Down

0 comments on commit 24ca159

Please sign in to comment.