|
| 1 | +--- |
| 2 | +title: Troubleshooting issues caused by applications that don’t support TLS 1.2 | Microsoft Docs |
| 3 | +description: Troubleshooting issues caused by applications that don’t support TLS 1.2 |
| 4 | +services: cloud-services |
| 5 | +documentationcenter: '' |
| 6 | +author: MicahMcKittrick-MSFT |
| 7 | +manager: vashan |
| 8 | +editor: '' |
| 9 | +tags: top-support-issue |
| 10 | +ms.assetid: |
| 11 | +ms.service: cloud-services |
| 12 | +ms.topic: troubleshooting |
| 13 | +ms.tgt_pltfrm: na |
| 14 | +ms.workload: |
| 15 | +ms.date: 01/17/2020 |
| 16 | +ms.author: tagore |
| 17 | +--- |
| 18 | +# Troubleshooting applications that don’t support TLS 1.2 |
| 19 | +This article describes how to enable the older TLS protocols (TLS 1.0 and 1.1) as well as applying legacy cipher suites to support the additional protocols on the Windows Server 2019 cloud service web and worker roles. |
| 20 | + |
| 21 | +We understand that while we are taking steps to deprecate TLS 1.0 and TLS 1.1, our customers may need to support the older protocols and cipher suites until they can plan for their deprecation. While we don't recommend re-enabling these legacy values, we are providing guidance to help customers. We encourage customers to evaluate the risk of regression before implementing the changes outlined in this article. |
| 22 | + |
| 23 | +> [!NOTE] |
| 24 | +> Guest OS Family 6 releases enforces TLS 1.2 by disabling 1.0/1.0 ciphers. |
| 25 | +
|
| 26 | + |
| 27 | +## Dropping support for TLS 1.0, TLS 1.1 and older cipher suites |
| 28 | +In support of our commitment to use best-in-class encryption, Microsoft announced plans to start migration away from TLS 1.0 and 1.1 in June of 2017. Since that initial announcement, Microsoft announced our intent to disable Transport Layer Security (TLS) 1.0 and 1.1 by default in supported versions of Microsoft Edge and Internet Explorer 11 in the first half of 2020. Similar announcements from Apple, Google, and Mozilla indicate the direction in which the industry is headed. |
| 29 | + |
| 30 | +## TLS configuration |
| 31 | +The Windows Server 2019 cloud server image is configured with TLS 1.0 and TLS 1.1 disabled at the registry level. This means applications deployed to this version of Windows AND using the Windows stack for TLS negotiation will not allow TLS 1.0 and TLS 1.1 communication. |
| 32 | + |
| 33 | +The server also comes with a limited set of cipher suites: |
| 34 | + |
| 35 | +```Powershell |
| 36 | + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 |
| 37 | + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 |
| 38 | + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 |
| 39 | + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 |
| 40 | + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 |
| 41 | + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 |
| 42 | + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 |
| 43 | + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 |
| 44 | +``` |
| 45 | + |
| 46 | +## Step 1: Create the PowerShell script to enable TLS 1.0 and TLS 1.1 |
| 47 | + |
| 48 | +Use the following code as an example to create a script that enables the older protocols and cipher suites. For the purposes of this documentation, this script will be named: TLSsettings.ps1. |
| 49 | + |
| 50 | +```Powershell |
| 51 | +#******************* FUNCTION THAT ACTUALLY UPDATES KEYS; WILL RETURN REBOOT FLAG IF CHANGES *********************** |
| 52 | +
|
| 53 | +Function Set-CryptoSetting { |
| 54 | + param ( |
| 55 | + $regKeyName, |
| 56 | + $value, |
| 57 | + $valuedata, |
| 58 | + $valuetype |
| 59 | + ) |
| 60 | + |
| 61 | + $restart = $false |
| 62 | + |
| 63 | + # Check for existence of registry key, and create if it does not exist |
| 64 | + If (!(Test-Path -Path $regKeyName)) { |
| 65 | + New-Item $regKeyName | Out-Null |
| 66 | + } |
| 67 | +
|
| 68 | + # Get data of registry value, or null if it does not exist |
| 69 | + $val = (Get-ItemProperty -Path $regKeyName -Name $value -ErrorAction SilentlyContinue).$value |
| 70 | +
|
| 71 | + If ($val -eq $null) { |
| 72 | + # Value does not exist - create and set to desired value |
| 73 | + New-ItemProperty -Path $regKeyName -Name $value -Value $valuedata -PropertyType $valuetype | Out-Null |
| 74 | + $restart = $true |
| 75 | + } |
| 76 | +
|
| 77 | + Else { |
| 78 | + # Value does exist - if not equal to desired value, change it |
| 79 | + If ($val -ne $valuedata) { |
| 80 | + Set-ItemProperty -Path $regKeyName -Name $value -Value $valuedata |
| 81 | + $restart = $true |
| 82 | + } |
| 83 | + } |
| 84 | +
|
| 85 | + $restart |
| 86 | +} |
| 87 | +
|
| 88 | +#*************************************************************************************************************** |
| 89 | +
|
| 90 | +#****************************** CIPHERSUITES FOR OS VERSIONS WINDOWS 10 AND ABOVE ****************************** |
| 91 | +
|
| 92 | +function Get-BaseCipherSuitesWin10Above() |
| 93 | +{ |
| 94 | + $cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" |
| 95 | + $cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" |
| 96 | + $cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" |
| 97 | + $cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" |
| 98 | + $cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" |
| 99 | + $cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" |
| 100 | + $cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" |
| 101 | + $cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" |
| 102 | +
|
| 103 | +# Legacy cipher suites |
| 104 | + $cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256" |
| 105 | + $cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256" |
| 106 | + $cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256" |
| 107 | + $cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256" |
| 108 | + $cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384" |
| 109 | + $cipherorder += "TLS_RSA_WITH_AES_128_GCM_SHA256" |
| 110 | + $cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256" |
| 111 | + $cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA256" |
| 112 | + $cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA" |
| 113 | + $cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA" |
| 114 | +
|
| 115 | + return $cipherorder |
| 116 | +} |
| 117 | +
|
| 118 | + |
| 119 | +#*************************************************************************************************************** |
| 120 | +
|
| 121 | +
|
| 122 | +#********************************************** REGISTRY KEYS **************************************************** |
| 123 | +
|
| 124 | + |
| 125 | +function Get-RegKeyPathToEnable() |
| 126 | +{ |
| 127 | + $regKeyPath = @( |
| 128 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2", |
| 129 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client", |
| 130 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" , |
| 131 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1", |
| 132 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client", |
| 133 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" , |
| 134 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0", |
| 135 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client", |
| 136 | + "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" |
| 137 | + ) |
| 138 | + return $regKeyPath |
| 139 | +} |
| 140 | +
|
| 141 | +#*************************************************************************************************************** |
| 142 | +
|
| 143 | +$localRegistryPath = @() |
| 144 | +
|
| 145 | +# Enable TLS 1.2, TLS 1.1 and TLS 1.0 |
| 146 | +$localRegistryPath += Get-RegKeyPathToEnable |
| 147 | +
|
| 148 | +#******************* CREATE THE REGISTRY KEYS IF THEY DON'T EXIST******************************** |
| 149 | +
|
| 150 | +# Check for existence of the registry keys, and create if they do not exist |
| 151 | +For ($i = 0; $i -lt $localRegistryPath .Length; $i = $i + 1) { |
| 152 | + Write-Log -Message "Checking for existing of key: $($localRegistryPath [$i]) " -Logfile $logLocation -Severity Information |
| 153 | + If (!(Test-Path -Path $localRegistryPath [$i])) { |
| 154 | + New-Item $localRegistryPath [$i] | Out-Null |
| 155 | + Write-Log -Message "Creating key: $($localRegistryPath [$i]) " -Logfile $logLocation -Severity Information |
| 156 | + } |
| 157 | +} |
| 158 | +
|
| 159 | +#********************************* EXPLICITLY Enable TLS12, TLS11 and TLS10********************************* |
| 160 | +
|
| 161 | +For ($i = 0; $i -lt $localRegistryPath .Length; $i = $i + 1) { |
| 162 | + if ($localRegistryPath [$i].Contains("Client") -Or $localRegistryPath [$i].Contains("Server")) { |
| 163 | + Write-Log -Message "Enabling this key: $($localRegistryPath [$i]) " -Logfile $logLocation -Severity Information |
| 164 | + $result = Set-CryptoSetting $localRegistryPath [$i].ToString() Enabled 1 DWord |
| 165 | + $result = Set-CryptoSetting $localRegistryPath [$i].ToString() DisabledByDefault 0 DWord |
| 166 | + $reboot = $reboot -or $result |
| 167 | + } |
| 168 | +} |
| 169 | + |
| 170 | +#**************************************** SET THE CIPHER SUITE ORDER******************************** |
| 171 | +
|
| 172 | +$cipherlist = @() |
| 173 | +
|
| 174 | +# Set cipher suite order |
| 175 | +$cipherlist += Get-BaseCipherSuitesWin10Above |
| 176 | +$cipherorder = [System.String]::Join(",", $cipherlist) |
| 177 | +$CipherSuiteRegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" |
| 178 | +
|
| 179 | +if (!(Test-Path -Path $CipherSuiteRegKey)) |
| 180 | +{ |
| 181 | + New-Item $CipherSuiteRegKey | Out-Null |
| 182 | + $reboot = $True |
| 183 | + Write-Log -Message "Creating key: $($CipherSuiteRegKey) " -Logfile $logLocation -Severity Information |
| 184 | +} |
| 185 | +
|
| 186 | +Set-ItemProperty -Path $CipherSuiteRegKey -Name Functions -Value $cipherorder |
| 187 | +
|
| 188 | +#********************************************* REBOOT ******************************************* |
| 189 | +
|
| 190 | +Write-Host "A reboot is required in order for changes to effect" |
| 191 | +Write-Host "Rebooting now..." |
| 192 | +shutdown.exe /r /t 5 /c "Crypto settings changed" /f /d p:2:4 |
| 193 | +``` |
| 194 | + |
| 195 | +## Step 2: Create a command file |
| 196 | + |
| 197 | +Create a CMD file with the following information . |
| 198 | + |
| 199 | +``` |
| 200 | +IF "%ComputeEmulatorRunning%" == "true" ( |
| 201 | + ECHO Not launching the script, since is DEV Machine >> "Log.txt" 2>&1 |
| 202 | +) ELSE ( |
| 203 | +
|
| 204 | +PowerShell .\TLSsettings.ps1 |
| 205 | + |
| 206 | +) |
| 207 | +
|
| 208 | +REM This line is required to ensure the startup tasks does not block the role from starting in case of error. DO NOT REMOVE!!!! |
| 209 | +
|
| 210 | +EXIT /B 0 |
| 211 | +``` |
| 212 | + |
| 213 | +## Step 3: Add the startup task to the role’s service definition (csdef) |
| 214 | + |
| 215 | +Here is an example that shows both the worker role and web role. |
| 216 | + |
| 217 | +``` |
| 218 | +<?xml version="1.0" encoding="utf-8"?> |
| 219 | +<ServiceDefinition name="NugetExampleCloudServices" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition" schemaVersion="2015-04.2.6"> |
| 220 | + <WebRole name="WebRole1" vmsize="Standard_D1_v2"> |
| 221 | + <Sites> |
| 222 | + <Site name="Web"> |
| 223 | + <Bindings> |
| 224 | + <Binding name="Endpoint1" endpointName="Endpoint1" /> |
| 225 | + </Bindings> |
| 226 | + </Site> |
| 227 | + </Sites> |
| 228 | + <Startup> |
| 229 | + <Task executionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd"> |
| 230 | + </Task> |
| 231 | + </Startup> |
| 232 | + <Endpoints> |
| 233 | + <InputEndpoint name="Endpoint1" protocol="http" port="80" /> |
| 234 | + </Endpoints> |
| 235 | + </WebRole> |
| 236 | + <WorkerRole name="WorkerRole1" vmsize="Standard_D1_v2"> |
| 237 | + <Startup> |
| 238 | + <Task executionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd"> |
| 239 | + </Task> |
| 240 | + </Startup> |
| 241 | + </WorkerRole> |
| 242 | +</ServiceDefinition> |
| 243 | +``` |
| 244 | + |
| 245 | +## Step 4: Validation |
| 246 | + |
| 247 | +You can use [SSLLabs](https://www.ssllabs.com/) to validate the TLS status of your endpoints |
| 248 | + |
| 249 | + |
0 commit comments