Skip to content

Commit 7f721e4

Browse files
Merge pull request #106344 from mimckitt/patch-83
Update applications-dont-support-tls-1-2.md
2 parents 8c97619 + 47d1f2a commit 7f721e4

File tree

1 file changed

+126
-104
lines changed

1 file changed

+126
-104
lines changed

articles/cloud-services/applications-dont-support-tls-1-2.md

Lines changed: 126 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ ms.workload:
1515
ms.date: 01/17/2020
1616
ms.author: tagore
1717
---
18+
1819
# Troubleshooting applications that don’t support TLS 1.2
1920
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.
2021

@@ -23,7 +24,7 @@ We understand that while we are taking steps to deprecate TLS 1.0 and TLS 1.1, o
2324
> [!NOTE]
2425
> Guest OS Family 6 releases enforces TLS 1.2 by disabling 1.0/1.1 ciphers.
2526
26-
27+
2728
## Dropping support for TLS 1.0, TLS 1.1 and older cipher suites
2829
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.
2930

@@ -32,7 +33,7 @@ The Windows Server 2019 cloud server image is configured with TLS 1.0 and TLS 1.
3233

3334
The server also comes with a limited set of cipher suites:
3435

35-
```Powershell
36+
```
3637
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
3738
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
3839
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
@@ -42,14 +43,15 @@ The server also comes with a limited set of cipher suites:
4243
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
4344
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
4445
```
45-
46+
4647
## Step 1: Create the PowerShell script to enable TLS 1.0 and TLS 1.1
4748

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-
49+
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**. Store this script on your local desktop for easy access in later steps.
50+
51+
5052
```Powershell
5153
#******************* FUNCTION THAT ACTUALLY UPDATES KEYS; WILL RETURN REBOOT FLAG IF CHANGES ***********************
52-
54+
5355
Function Set-CryptoSetting {
5456
param (
5557
$regKeyName,
@@ -64,64 +66,64 @@ Function Set-CryptoSetting {
6466
If (!(Test-Path -Path $regKeyName)) {
6567
New-Item $regKeyName | Out-Null
6668
}
67-
69+
6870
# Get data of registry value, or null if it does not exist
6971
$val = (Get-ItemProperty -Path $regKeyName -Name $value -ErrorAction SilentlyContinue).$value
70-
72+
7173
If ($val -eq $null) {
7274
# Value does not exist - create and set to desired value
7375
New-ItemProperty -Path $regKeyName -Name $value -Value $valuedata -PropertyType $valuetype | Out-Null
7476
$restart = $true
7577
}
76-
78+
7779
Else {
7880
# Value does exist - if not equal to desired value, change it
7981
If ($val -ne $valuedata) {
8082
Set-ItemProperty -Path $regKeyName -Name $value -Value $valuedata
8183
$restart = $true
8284
}
8385
}
84-
86+
8587
$restart
8688
}
87-
89+
8890
#***************************************************************************************************************
89-
91+
9092
#****************************** CIPHERSUITES FOR OS VERSIONS WINDOWS 10 AND ABOVE ******************************
91-
93+
9294
function Get-BaseCipherSuitesWin10Above()
9395
{
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-
96+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,"
97+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,"
98+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,"
99+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,"
100+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,"
101+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,"
102+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,"
103+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,"
104+
103105
# 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"
106+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256,"
107+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256,"
108+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256,"
109+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256,"
110+
$cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384,"
111+
$cipherorder += "TLS_RSA_WITH_AES_128_GCM_SHA256,"
112+
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256,"
113+
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA256,"
114+
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA,"
113115
$cipherorder += "TLS_RSA_WITH_AES_128_CBC_SHA"
114-
115-
return $cipherorder
116+
117+
return $cipherorder
116118
}
119+
117120
118-
119121
#***************************************************************************************************************
120-
121-
122+
123+
122124
#********************************************** REGISTRY KEYS ****************************************************
123-
124-
125+
126+
125127
function Get-RegKeyPathToEnable()
126128
{
127129
$regKeyPath = @(
@@ -137,112 +139,132 @@ function Get-RegKeyPathToEnable()
137139
)
138140
return $regKeyPath
139141
}
140-
142+
141143
#***************************************************************************************************************
142-
144+
143145
$localRegistryPath = @()
144-
146+
145147
# Enable TLS 1.2, TLS 1.1 and TLS 1.0
146148
$localRegistryPath += Get-RegKeyPathToEnable
147-
149+
148150
#******************* CREATE THE REGISTRY KEYS IF THEY DON'T EXIST********************************
149-
151+
150152
# 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-
         }
153+
For ($i = 0; $i -lt $localRegistryPath.Length; $i = $i + 1) {
154+
Write-Host "Checking for existing of key: $($localRegistryPath[$i]) Severity Level: Information"
155+
If (!(Test-Path -Path $localRegistryPath[$i])) {
156+
New-Item $localRegistryPath [$i] | Out-Null
157+
Write-Host "Creating key: $($localRegistryPath[$i]) Severity Level: Information"
158+
}
157159
}
158-
160+
159161
#********************************* 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
162+
163+
For ($i = 0; $i -lt $localRegistryPath.Length; $i = $i + 1) {
164+
if ($localRegistryPath[$i].Contains("Client") -Or $localRegistryPath[$i].Contains("Server")) {
165+
Write-Host "Enabling this key: $($localRegistryPath[$i]) Severity: Information "
166+
$result = Set-CryptoSetting $localRegistryPath[$i].ToString() Enabled 1 DWord
167+
$result = Set-CryptoSetting $localRegistryPath[$i].ToString() DisabledByDefault 0 DWord
166168
$reboot = $reboot -or $result
167169
}
168170
}
169171
170172
#**************************************** SET THE CIPHER SUITE ORDER********************************
171-
173+
172174
$cipherlist = @()
173-
175+
174176
# Set cipher suite order
175177
$cipherlist += Get-BaseCipherSuitesWin10Above
176-
$cipherorder = [System.String]::Join(",", $cipherlist)
177178
$CipherSuiteRegKey = "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"
178-
179+
179180
if (!(Test-Path -Path $CipherSuiteRegKey))
180181
{
181182
New-Item $CipherSuiteRegKey | Out-Null
182183
$reboot = $True
183-
Write-Log -Message "Creating key: $($CipherSuiteRegKey) " -Logfile $logLocation -Severity Information
184+
Write-Host "Creating key: $($CipherSuiteRegKey) Severity: Information "
184185
}
185-
186-
Set-ItemProperty -Path $CipherSuiteRegKey -Name Functions -Value $cipherorder
187-
186+
187+
#Set-ItemProperty -Path $CipherSuiteRegKey -Name Functions -Value $cipherorder
188+
Set-ItemProperty -Path $CipherSuiteRegKey -Name Functions -Value $cipherlist
188189
#********************************************* REBOOT *******************************************
189-
190+
190191
Write-Host "A reboot is required in order for changes to effect"
191192
Write-Host "Rebooting now..."
192-
shutdown.exe /r /t 5 /c "Crypto settings changed" /f /d p:2:4
193+
shutdown.exe /r /t 5 /c "Crypto settings changed" /f /d p:2:4
193194
```
194-
195+
195196
## Step 2: Create a command file
196197

197-
Create a CMD file with the following information .
198+
Create a CMD file named **RunTLSSettings.cmd** using the below. Store this script on your local desktop for easy access in later steps.
198199

200+
```cmd
201+
PowerShell -ExecutionPolicy Unrestricted %~dp0TLSsettings.ps1
202+
REM This line is required to ensure the startup tasks does not block the role from starting in case of error. DO NOT REMOVE!!!!
203+
EXIT /B 0
199204
```
200-
IF "%ComputeEmulatorRunning%" == "true" (
201-
ECHO Not launching the script, since is DEV Machine >> "Log.txt" 2>&1
202-
) ELSE (
203205

204-
PowerShell .\TLSsettings.ps1
205-
206-
)
206+
## Step 3: Add the startup task to the role’s service definition (csdef)
207207

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!!!!
208+
Add the following snippet to your existing service definition file.
209209

210-
EXIT /B 0
211-
```
212210

213-
## Step 3: Add the startup task to the role’s service definition (csdef)
211+
```
212+
<Startup>
213+
<Task executionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd">
214+
</Task>
215+
</Startup>
216+
```
214217

215218
Here is an example that shows both the worker role and web role.
216-
219+
217220
```
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-
      <TaskexecutionContext="elevated"taskType="simple"commandLine="RunTLSSettings.cmd">
239-
      </Task>
240-
    </Startup>
241-
  </WorkerRole>
221+
<?xmlversion="1.0"encoding="utf-8"?>
222+
<ServiceDefinitionname="CloudServiceName"xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"schemaVersion="2015-04.2.6">
223+
<WebRolename="WebRole1"vmsize="Standard_D1_v2">
224+
<Sites>
225+
<Sitename="Web">
226+
<Bindings>
227+
<Bindingname="Endpoint1"endpointName="Endpoint1"/>
228+
</Bindings>
229+
</Site>
230+
</Sites>
231+
<Startup>
232+
<Taske xecutionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd">
233+
</Task>
234+
</Startup>
235+
<Endpoints>
236+
<InputEndpointname="Endpoint1"protocol="http"port="80"/>
237+
</Endpoints>
238+
</WebRole>
239+
<WorkerRolename="WorkerRole1"vmsize="Standard_D1_v2">
240+
<Startup>
241+
<Task executionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd">
242+
</Task>
243+
</Startup>
244+
</WorkerRole>
242245
</ServiceDefinition>
243246
```
244247

245-
## Step 4: Validation
248+
## Step 5: Add the scripts to your Cloud Service
249+
250+
1) In Visual Studio, right-click on your WebRole
251+
2) Select **Add**
252+
3) Select **Existing Item**
253+
4) In the file explorer, navigate to your desktop where you stored the **TLSsettings.ps1** and **RunTLSSettings.cmd** files
254+
5) Select the two files to add them to your Cloud Services project
255+
256+
## Step 6: Enable Copy to Output Directory
257+
258+
To ensure the scripts are uploaded with every update pushed from Visual Studio, the setting *Copy to Output Directory* needs to be set to *Copy Always*
259+
260+
1) Under your WebRole, right-click on RunTLSSettings.cmd
261+
2) Select **Properties**
262+
3) In the properties tab, change *Copy to Output Directory* to *Copy Always"*
263+
4) Repeat the steps for **TLSsettings.ps1**
264+
265+
## Step 7: Publish & Validate
266+
267+
Now that the above steps have been complete, publish the update to your existing Cloud Service.
246268

247269
You can use [SSLLabs](https://www.ssllabs.com/) to validate the TLS status of your endpoints
248270

0 commit comments

Comments
 (0)