Configure Exchange with One Certificate for Both Internal and External Connections

Brian St. Marie - Sr. Systems Engineer

Starting with Exchange 2007 and Outlook 2007, client connections to the server are encrypted using SSL technology.  This requires a valid certificate be installed on the Exchange server or the Outlook client will warn the user each time they open Outlook.  By default, Exchange installs a self-signed certificate during installation which will be automatically valid for any Outlook clients connecting from computers within the same domain as the server.  However, if you plan to set up remote users with Outlook using RPC over HTTPS (also known as Outlook Anywhere), the the users internet-facing Client Access Server will require an externally valid SSL certificate.  In situation where a company only has one Exchange server handling all roles, this quickly becomes a problem.  Once the externally valid certificate is installed on the Exchange server, all internal clients on Outlook 2007 or later will receive a certificate error each time Outlook is opened.  This is because the Exchange server is presenting itself to the clients with its valid internal network name (e.g. exchange.company.local), while the certificate shows its valid external name (e.g. mail.company.com).  This conflict is the source of the Outlook warning.

The simplest way to circumvent this issue is to purchase a mutli-domain certificate, which will be valid for both the external and internal name of the server.  There are two major downsides to this, however.  One is cost.  Multi-domain certificates are significantly more expensive than standard, single name certificates.  The second downside is that the certificate will contain the internal name of the server and the certificate will be available publicly for anyone to see.  This can be a security liability, exposing internal network information to anyone who cares to look.

The better solution is to modify the Exchange server to use *only* the external server name when making connections to clients.  This allows a single name certificate to be used to secure all connections made by the server and ensures the server will only ever refer to itself by this chosen external name.  The steps to accomplish this are somewhat complex, but thankfully, some great people have written Powershell scripts which execute the necessary commands for both Exchange 2007 and Exchange 2010.  Using these scripts automatically changes the name used both internally and externally by all virtual directories as well as the SCP on the server.

Below are copies of the scripts for both Exchange 2010 and Exchange 2007.

Brian St. Marie - Sr. Systems Engineer

========================================================

 

Exchange 2007  Credit to Exchange Ninjas (http://www.exchangeninjas.com/set-allvdirs)

 

========================================================

 

# Script to allow you to set all virtual directories to a common name like mail.company.com

 

Start-Transcript

 

# Variables

 

[string]$UMExtend = '/UnifiedMessaging/Service.asmx'

[string]$OABExtend = '/OAB'

[string]$SCPExtend = '/Autodiscover/Autodiscover.xml'

[string]$EWSExtend = '/EWS/Exchange.asmx'

[string]$ConfirmPrompt = 'Set this Value? (Y/N)'

[string]$NoChangeForeground = 'white'

[string]$NoChangeBackground = 'red'

 

Write-host 'This will allow you to set the virtual directories associated with Autodiscover provided services to the name you provide.'

Write-host ''

[string]$base = Read-host 'Base name of virtual directory (e.g. mail.company.com)'

write-host ''

# =======================================================

# Validate if a third party trusted certificate is being used

# because BITS won't use untrusted certificates

[string]$set = Read-host 'Is the certificate being used an internally generated certificate? (Y/N)'

Write-host ''

 

if ($set -eq 'Y')    {

    [string]$OABprefix = 'http://'

}    else    {

    [string]$OABprefix = 'https://'

}

 

# =======================================================

# Build the Autodiscover URL and set the SCP Value

 

Write-host 'Setting Autodiscover Service Connection Point' -foregroundcolor Yellow

write-host ''

 

$SCPURL = 'https://' + $base + $SCPExtend

 

[array]$SCPCurrent = Get-ClientAccessServer

 

Foreach ($value in $SCPCurrent) {

    Write-host 'Looking at Server: ' $value.name

    Write-host 'Current SCP value: ' $value.AutoDiscoverServiceInternalUri.absoluteuri

    Write-host 'New SCP Value:     ' $SCPURL

    [string]$set = Read-host $ConfirmPrompt

    write-host ''

   

    if ($set -eq 'Y')    {

         Set-ClientAccessServer -id $value.identity -AutoDiscoverServiceInternalUri $SCPURL

    }    else {

        write-host 'Autodiscover Service Connection Point internal value NOT changed' -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

 

# =======================================================

# Build the EWS URL and set the internal Value

 

Write-host 'Setting Exchange Web Services Virtual Directories' -foregroundcolor Yellow

write-host ''

 

$EWSURL = 'https://' + $base + $EWSExtend

 

[array]$EWSCurrent = Get-WebServicesVirtualDirectory

 

Foreach ($value in $EWSCurrent) {

    Write-host 'Looking at Server: ' $value.server

    Write-host 'Current Internal Value: ' $value.internalURL

    Write-host 'New Internal Value:     ' $EWSUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host ''

 

    if ($set -eq 'Y')    {

        Set-WebServicesVirtualDirectory -id $value.identity -InternalURL $EWSURL

     } else {

        write-host 'Exchange Web Services Virtual Directory internal value NOT changed' -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

     }

 

    Write-host 'Looking at Server: ' $value.server

    Write-host 'Current External Value: ' $value.externalURL

    Write-host 'New External Value:     ' $EWSUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host ''

 

    if ($set -eq 'Y')    {

        Set-WebServicesVirtualDirectory -id $value.identity -ExternalURL $EWSURL

    } else {

        write-host 'Exchange Web Services Virtual Directory external value NOT changed' -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

 

# ======================================================

# Build the OAB URL and set the internal Value

 

Write-host 'Setting OAB Virtual Directories' -foregroundcolor Yellow

write-host ''

 

$OABURL = $OABprefix + $base + $OABExtend

 

[array]$OABCurrent = Get-OABVirtualDirectory

 

Foreach ($value in $OABcurrent) {

    Write-host 'Looking at Server: ' $value.server

    Write-host 'Current Internal Value: ' $value.internalURL

    Write-host 'New Internal Value:     ' $OABUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host ''

 

    if ($set -eq 'Y')    {

        Set-OABVirtualDirectory -id $value.identity -InternalURL $OABURL

    } else {

        write-host 'OAB Virtual Directory internal value NOT changed' -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

 

    Write-host 'Looking at Server: ' $value.server

    Write-host 'Current External Value: ' $value.externalURL

    Write-host 'New External Value:     ' $OABUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host ''

 

    if ($set -eq 'Y') {

        Set-OABVirtualDirectory -id $value.identity -ExternalURL $OABURL

    } else {

        write-host 'OAB Virtual Directory external value NOT changed' -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

 

# =======================================================

# Build the UM URL and set the internal Value

 

Write-host 'Setting UM Virtual Directories' -foregroundcolor Yellow

write-host ''

 

$UMURL = 'https://' + $base + $UMExtend

 

[array]$UMCurrent = Get-UMVirtualDirectory

 

foreach ($value in $UMCurrent) {

    Write-host 'Looking at Server: ' $value.server

    Write-host 'Current Internal Value: ' $value.internalURL

    Write-host 'New Internal Value:     ' $UMUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host ''

 

    if ($set -eq 'Y') {

        Set-UMVirtualDirectory -id $value.identity -InternalURL $UMURL

    } else {

        write-host 'UM Virtual Directory internal value NOT changed' -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

 

    Write-host 'Looking at Server: ' $value.server

    Write-host 'Current External Value: ' $value.externalURL

    Write-host 'New External Value:     ' $UMUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host ''

 

    if ($set -eq 'Y') {

        Set-UMVirtualDirectory -id $value.identity -ExternalURL $UMURL

    } else {

        write-host 'UM Virtual Directory external value NOT changed' -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

Stop-Transcript

 

 

 

========================================================

 

Exchange 2010                  Credit to Barry Martin (http://virtualbarrymartin.me/2009/12/29/how-to-setup-exchange-2010-to-use-a-single-certificate-for-internal-and-external-use/)

 

========================================================

 

# Script to allow you to set all virtual directories to a common name like mail.company.com

Start-Transcript

# Variables

[string]$UMExtend = “/UnifiedMessaging/Service.asmx”

[string]$OWAExtend = “/OWA”

[string]$OABExtend = “/OAB”

[string]$SCPExtend = “/Autodiscover/Autodiscover.xml”

[string]$EWSExtend = “/EWS/Exchange.asmx”

[string]$ECPExtend = “/ECP”

[string]$ConfirmPrompt = “Set this Value? (Y/N)”

[string]$NoChangeForeground = “white”

[string]$NoChangeBackground = “red”

Write-host “This will allow you to set the virtual directories associated with setting up a single SSL certificate to work with Exchange 2010.”

Write-host “”

[string]$base = Read-host “Base name of virtual directory (e.g. mail.company.com)”

write-host “”

# =======================================================

# Validate if a third party trusted certificate is being used

# because BITS won’t use untrusted certificates

[string]$set = Read-host “Is the certificate being used an internally generated certificate? (Y/N)”

Write-host “”

if ($set -eq “Y”)    {

    [string]$OABprefix = “http://”

}    else    {

    [string]$OABprefix = “https://”

}

# =======================================================

# Build the Autodiscover URL and set the SCP Value

Write-host “Setting Autodiscover Service Connection Point” -foregroundcolor Yellow

write-host “”

$SCPURL = “https://” + $base + $SCPExtend

[array]$SCPCurrent = Get-ClientAccessServer

Foreach ($value in $SCPCurrent) {

    Write-host “Looking at Server: ” $value.name

    Write-host “Current SCP value: ” $value.AutoDiscoverServiceInternalUri.absoluteuri

    Write-host “New SCP Value:     ” $SCPURL

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

  

    if ($set -eq “Y”)    {

         Set-ClientAccessServer -id $value.identity -AutoDiscoverServiceInternalUri $SCPURL

    }    else {

        write-host “Autodiscover Service Connection Point internal value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

# =======================================================

# Build the EWS URL and set the internal Value

Write-host “Setting Exchange Web Services Virtual Directories” -foregroundcolor Yellow

write-host “”

$EWSURL = “https://” + $base + $EWSExtend

[array]$EWSCurrent = Get-WebServicesVirtualDirectory

Foreach ($value in $EWSCurrent) {

    Write-host “Looking at Server: ” $value.server

    Write-host “Current Internal Value: ” $value.internalURL

    Write-host “New Internal Value:     ” $EWSUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”)    {

        Set-WebServicesVirtualDirectory -id $value.identity -InternalURL $EWSURL

     } else {

        write-host “Exchange Web Services Virtual Directory internal value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

     }

    Write-host “Looking at Server: ” $value.server

    Write-host “Current External Value: ” $value.externalURL

    Write-host “New External Value:     ” $EWSUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”)    {

        Set-WebServicesVirtualDirectory -id $value.identity -ExternalURL $EWSURL

    } else {

        write-host “Exchange Web Services Virtual Directory external value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

# ======================================================

# Build the OAB URL and set the internal Value

Write-host “Setting OAB Virtual Directories” -foregroundcolor Yellow

write-host “”

$OABURL = $OABprefix + $base + $OABExtend

[array]$OABCurrent = Get-OABVirtualDirectory

Foreach ($value in $OABcurrent) {

    Write-host “Looking at Server: ” $value.server

   Write-host “Current Internal Value: ” $value.internalURL

    Write-host “New Internal Value:     ” $OABUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”)    {

        Set-OABVirtualDirectory -id $value.identity -InternalURL $OABURL

    } else {

        write-host “OAB Virtual Directory internal value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

    Write-host “Looking at Server: ” $value.server

    Write-host “Current External Value: ” $value.externalURL

    Write-host “New External Value:     ” $OABUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”) {

        Set-OABVirtualDirectory -id $value.identity -ExternalURL $OABURL

    } else {

        write-host “OAB Virtual Directory external value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

# =======================================================

# Build the UM URL and set the internal Value

Write-host “Setting UM Virtual Directories” -foregroundcolor Yellow

write-host “”

$UMURL = “https://” + $base + $UMExtend

[array]$UMCurrent = Get-UMVirtualDirectory

foreach ($value in $UMCurrent) {

    Write-host “Looking at Server: ” $value.server

    Write-host “Current Internal Value: ” $value.internalURL

    Write-host “New Internal Value:     ” $UMUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”) {

        Set-UMVirtualDirectory -id $value.identity -InternalURL $UMURL

    } else {

        write-host “UM Virtual Directory internal value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

    Write-host “Looking at Server: ” $value.server

    Write-host “Current External Value: ” $value.externalURL

    Write-host “New External Value:     ” $UMUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”) {

        Set-UMVirtualDirectory -id $value.identity -ExternalURL $UMURL

    } else {

        write-host “UM Virtual Directory external value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

# =======================================================

# Build the ECP URL and set the internal Value

Write-host “Setting ECP Virtual Directories” -foregroundcolor Yellow

write-host “”

$ECPURL = “https://” + $base + $ECPExtend

[array]$ECPCurrent = Get-ECPVirtualDirectory

foreach ($value in $ECPCurrent) {

    Write-host “Looking at Server: ” $value.server

    Write-host “Current Internal Value: ” $value.internalURL

    Write-host “New Internal Value:     ” $ECPUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”) {

        Set-ECPVirtualDirectory -id $value.identity -InternalURL $ECPURL

    } else {

        write-host “ECP Virtual Directory internal value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

    Write-host “Looking at Server: ” $value.server

    Write-host “Current External Value: ” $value.externalURL

    Write-host “New External Value:     ” $ECPUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”) {

        Set-ECPVirtualDirectory -id $value.identity -ExternalURL $ECPURL

    } else {

       write-host “ECP Virtual Directory external value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}

# =======================================================

# Build the OWA URL and set the internal Value

Write-host “Setting OWA Virtual Directories” -foregroundcolor Yellow

write-host “”

$OWAURL = “https://” + $base + $OWAExtend

[array]$OWACurrent = Get-OWAVirtualDirectory

foreach ($value in $OWACurrent) {

    Write-host “Looking at Server: ” $value.server

    Write-host “Current Internal Value: ” $value.internalURL

    Write-host “New Internal Value:     ” $OWAUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”) {

        Set-OWAVirtualDirectory -id $value.identity -InternalURL $OWAURL

    } else {

        write-host “OWA Virtual Directory internal value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

    Write-host “Looking at Server: ” $value.server

    Write-host “Current External Value: ” $value.externalURL

    Write-host “New External Value:     ” $OWAUrl

    [string]$set = Read-host $ConfirmPrompt

    write-host “”

    if ($set -eq “Y”) {

        Set-OWAVirtualDirectory -id $value.identity -ExternalURL $OWAURL

    } else {

       write-host “OWA Virtual Directory external value NOT changed” -foregroundcolor $NoChangeForeground -backgroundcolor $NoChangeBackground

    }

}