Skip to content

Commit f2e4018

Browse files
authored
Update applications-dont-support-tls-1-2.md
1 parent 09bb120 commit f2e4018

File tree

1 file changed

+290
-33
lines changed

1 file changed

+290
-33
lines changed

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

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

22-
> [!IMPORTANT]
23-
> 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](https://azure.microsoft.com/updates/azuretls12/) 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.
24-
22+
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.
2523

2624
> [!NOTE]
27-
> Guest OS Family 6 releases enforces TLS 1.2 by explicitly disabling TLS 1.0 and 1.1 and defining a specific set of cipher suites.
25+
> Guest OS Family 6 releases enforces TLS 1.2 by disabling 1.0/1.1 ciphers.
2826
2927

3028
## Dropping support for TLS 1.0, TLS 1.1 and older cipher suites
3129
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.
3230

31+
For more information, see [Preparing for TLS 1.2 in Microsoft Azure](https://azure.microsoft.com/updates/azuretls12/)
32+
3333
## TLS configuration
3434
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.
3535

@@ -46,51 +46,308 @@ The server also comes with a limited set of cipher suites:
4646
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
4747
```
4848

49+
## Step 1: Create the PowerShell script to enable TLS 1.0 and TLS 1.1
4950

50-
## Step 1: Open your existing Azure Web Role project
51+
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.
5152

52-
> [!NOTE]
53-
> The entireity of these steps and scripts can be found in the following [GitHub Repo](https://github.com/microsoft/azure-ssl-configure).
5453

55-
Open your own existing Azure Web Role project to begin this process
54+
```Powershell
55+
# You can use the -SetCipherOrder (or -sco) option to also set the TLS cipher
56+
# suite order. Change the cipherorder variable below to the order you want to set on the
57+
# server. Setting this requires a reboot to take effect.
5658
57-
## Step 2: Add the startup scripts to your project
59+
Param(
60+
[parameter(Mandatory=$false)]
61+
[alias("sco")]
62+
[switch]$SetCipherOrder)
5863
59-
Add a new folder in your web role/worker role project called "Startup", copy [SSLConfigure.cmd](https://github.com/microsoft/azure-ssl-configure/blob/master/AzureCloudServiceSample/WebRoleSample/Startup/SSLConfigure.cmd) and [SSLConfigure.ps1](https://github.com/microsoft/azure-ssl-configure/blob/master/AzureCloudServiceSample/WebRoleSample/Startup/SSLConfigure.ps1) files into this folder, and add these files into your project.
64+
Function DisableRC4 {
65+
param ( $restart)
66+
$subkeys = Get-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL"
67+
$ciphers = $subkeys.OpenSubKey("Ciphers", $true)
68+
if($ciphers.SubKeyCount -eq 0) {
69+
$k1 = $ciphers.CreateSubKey("RC4 128/128")
70+
$k1.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
71+
$restart = $true
72+
$k2 = $ciphers.CreateSubKey("RC4 64/128")
73+
$k2.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
74+
$k3 = $ciphers.CreateSubKey("RC4 56/128")
75+
$k3.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
76+
$k4 = $ciphers.CreateSubKey("RC4 40/128")
77+
$k4.SetValue("Enabled", 0, [Microsoft.Win32.RegistryValueKind]::DWord)
78+
}
6079
61-
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*
80+
$restart
6281
63-
1) Under your WebRole, right-click on **SSLConfigure.cmd**
64-
2) Select **Properties**
65-
3) In the properties tab, change *Copy to Output Directory* to *Copy Always"*
66-
4) Repeat the steps for **SSLConfigure.ps1**
82+
}
83+
84+
Function Set-CryptoSetting {
85+
param (
86+
$keyindex,
87+
$value,
88+
$valuedata,
89+
$valuetype,
90+
$restart
91+
)
92+
93+
# Check for existence of registry key, and create if it does not exist
94+
If (!(Test-Path -Path $regkeys[$keyindex])) {
95+
New-Item $regkeys[$keyindex] | Out-Null
96+
}
97+
98+
# Get data of registry value, or null if it does not exist
99+
$val = (Get-ItemProperty -Path $regkeys[$keyindex] -Name $value -ErrorAction SilentlyContinue).$value
100+
101+
If ($null -eq $val) {
102+
# Value does not exist - create and set to desired value
103+
New-ItemProperty -Path $regkeys[$keyindex] -Name $value -Value $valuedata -PropertyType $valuetype | Out-Null
104+
$restart = $True
105+
Write-Host "Configuring $regkeys[$keyindex]...."
106+
} Else {
107+
# Value does exist - if not equal to desired value, change it
108+
If ($val -ne $valuedata) {
109+
Set-ItemProperty -Path $regkeys[$keyindex] -Name $value -Value $valuedata
110+
$restart = $True
111+
Write-Host "Configuring $regkeys[$keyindex]..."
112+
}
113+
}
114+
115+
$restart
116+
117+
}
118+
119+
$regkeys = @(
120+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0",
121+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client",
122+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server", #2
123+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1",
124+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client", #4
125+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server",
126+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2", #6
127+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client",
128+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server", #8
129+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0",
130+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client", #10
131+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server",
132+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0", #12
133+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client",
134+
"HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server", #14
135+
"HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002"
136+
)
137+
138+
Function Set-Windows10PlusCurveOrder {
139+
param ( $reboot)
140+
$desiredOrder = "NistP384;NistP256".Split(";")
141+
If ([Environment]::OSVersion.Version.Major -ge 10) {
142+
If (!(Test-Path -Path $regkeys[15])) {
143+
New-Item $regkeys[15] | Out-Null
144+
$reboot = $True
145+
}
146+
147+
$val = (Get-Item -Path $regkeys[15] -ErrorAction SilentlyContinue).GetValue("EccCurves", $null)
148+
149+
if( $null -eq $val) {
150+
New-ItemProperty -Path $regkeys[15] -Name EccCurves -Value $desiredOrder -PropertyType MultiString | Out-Null
151+
$reboot = $True
152+
} else {
153+
if ([System.String]::Join(';', $val) -ne [System.String]::Join(';', $desiredOrder)) {
154+
Write-Host "The original curve order ", `n, $val, `n, "needs to be updated to ", $desiredOrder
155+
Set-ItemProperty -Path $regkeys[15] -Name EccCurves -Value $desiredOrder
156+
$reboot = $True
157+
}
158+
}
159+
}
160+
161+
$reboot
162+
}
163+
164+
If ([Environment]::OSVersion.Version.Major -lt 10) {
165+
# This is for Windows before 10
166+
Write-Host "Configuring Windows before 10..."
167+
$cipherorder = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256,"
168+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256,"
169+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256,"
170+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256,"
171+
$cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256,"
172+
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,"
173+
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA"
174+
175+
} Else {
176+
177+
# this is for windows 10 or above
178+
Write-Host "Configuring Windows 10+..."
179+
$cipherorder = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,"
180+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,"
181+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,"
182+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,"
183+
$cipherorder += "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,"
184+
$cipherorder += "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,"
185+
$cipherorder += "TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_GCM_SHA256,"
186+
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,"
187+
$cipherorder += "TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA"
188+
}
189+
190+
# If any settings are changed, this will change to $True and the server will reboot
191+
192+
$reboot = $False
193+
194+
# Check for existence of registry keys (SSL 2.0, SSL 3.0, TLS 1.0, TLS 1.1, TLS 1.2), and create if they do not exist
195+
196+
For ($i = 0; $i -le 14; $i = $i + 1) {
197+
If (!(Test-Path -Path $regkeys[$i])) {
198+
New-Item $regkeys[$i] | Out-Null
199+
}
200+
}
201+
202+
####################### Candace Made Changes Here#############################
67203
68-
## Step 3: Update the Service Definition file
204+
# Ensure SSL 2.0 disabled for client/server
205+
$reboot = Set-CryptoSetting 10 DisabledByDefault 1 DWord $reboot
206+
$reboot = Set-CryptoSetting 10 Enabled 0 DWord $reboot
207+
$reboot = Set-CryptoSetting 11 DisabledByDefault 1 DWord $reboot
208+
$reboot = Set-CryptoSetting 11 Enabled 0 DWord $reboot
69209
70-
Add these lines to your ServiceDefinition.csdef file in your Azure project, place it under the corresponding role element of your role project.
210+
# Ensure SSL 3.0 disabled for client/server
211+
$reboot = Set-CryptoSetting 13 DisabledByDefault 1 DWord $reboot
212+
$reboot = Set-CryptoSetting 13 Enabled 0 DWord $reboot
213+
$reboot = Set-CryptoSetting 14 DisabledByDefault 1 DWord $reboot
214+
$reboot = Set-CryptoSetting 14 Enabled 0 DWord $reboot
71215
216+
# Ensure TLS 1.0 enabled for client/server
217+
$reboot = Set-CryptoSetting 1 DisabledByDefault 0 DWord $reboot
218+
$reboot = Set-CryptoSetting 1 Enabled 1 DWord $reboot
219+
$reboot = Set-CryptoSetting 2 DisabledByDefault 0 DWord $reboot
220+
$reboot = Set-CryptoSetting 2 Enabled 1 DWord $reboot
221+
222+
# Ensure TLS 1.1 disabled for client/server
223+
$reboot = Set-CryptoSetting 4 DisabledByDefault 0 DWord $reboot
224+
$reboot = Set-CryptoSetting 4 Enabled 1 DWord $reboot
225+
$reboot = Set-CryptoSetting 5 DisabledByDefault 0 DWord $reboot
226+
$reboot = Set-CryptoSetting 5 Enabled 1 DWord $reboot
227+
228+
# Ensure TLS 1.2 disabled for client/server
229+
$reboot = Set-CryptoSetting 7 DisabledByDefault 0 DWord $reboot
230+
$reboot = Set-CryptoSetting 7 Enabled 1 DWord $reboot
231+
$reboot = Set-CryptoSetting 8 DisabledByDefault 0 DWord $reboot
232+
$reboot = Set-CryptoSetting 8 Enabled 1 DWord $reboot
233+
234+
####################### Candace Made Changes Here#############################
235+
236+
$reboot = DisableRC4($reboot)
237+
238+
If ($SetCipherOrder) {
239+
If (!(Test-Path -Path $regkeys[15])) {
240+
New-Item $regkeys[15] | Out-Null
241+
$reboot = $True
242+
}
243+
244+
$val = (Get-Item -Path $regkeys[15] -ErrorAction SilentlyContinue).GetValue("Functions", $null)
245+
246+
if ($val -ne $cipherorder)
247+
{
248+
Write-Host "The original cipher suite order needs to be updated", `n, $val
249+
Set-ItemProperty -Path $regkeys[15] -Name Functions -Value $cipherorder
250+
$reboot = $True
251+
}
252+
}
253+
254+
$reboot = Set-Windows10PlusCurveOrder $reboot
255+
256+
# If any settings were changed, reboot
257+
# If any settings were changed, reboot
258+
If ($reboot)
259+
{
260+
Write-Host "Rebooting now..."
261+
Write-Host "Using this command: shutdown.exe /r /t 5 /c ""Crypto settings changed"" /f /d p:2:4 "
262+
shutdown.exe /r /t 5 /c "Crypto settings changed" /f /d p:2:4
263+
}
264+
Else
265+
{
266+
Write-Host "Nothing get updated."
267+
}
268+
269+
270+
<# If ($reboot) {
271+
# Randomize the reboot timing since it could be run in a large cluster.
272+
$tick = [System.Int32]([System.DateTime]::Now.Ticks % [System.Int32]::MaxValue)
273+
$rand = [System.Random]::new($tick)
274+
$sec = $rand.Next(30, 600)
275+
Write-Host "Rebooting after", $sec, " second(s)..."
276+
Write-Host shutdown.exe /r /t $sec /c "Crypto settings changed" /f /d p:2:4
277+
} Else {
278+
Write-Host "Nothing get updated."
279+
} #>
72280
```
73-
<WebRole>
74-
...
75-
<Startup>
76-
<Task commandLine="Startup\SSLConfigure.cmd" executionContext="elevated" taskType="simple">
77-
<Environment>
78-
<Variable name="ComputeEmulatorRunning">
79-
<RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
80-
</Variable>
81-
</Environment>
82-
</Task>
83-
</Startup>
84-
</WebRole>
281+
282+
## Step 2: Create a command file
283+
284+
Create a CMD file named **RunTLSSettings.cmd** using the below. Store this script on your local desktop for easy access in later steps.
285+
286+
```cmd
287+
PowerShell -ExecutionPolicy Unrestricted %~dp0TLSsettings.ps1
288+
REM This line is required to ensure the startup tasks does not block the role from starting in case of error. DO NOT REMOVE!!!!
289+
EXIT /B 0
85290
```
86291

87-
## Step 4: Update the publish profile
292+
## Step 3: Add the startup task to the role’s service definition (csdef)
88293

89-
If you have an existing Azure Web Role deployed, the recommended AzureDeploymentReplacementMethod in your publish profile is "AutomaticUpgrade", instead of "DeleteAndCreate". If you don't have existing deployment, you can use DeleteAndCreate too.
294+
Add the following snippet to your existing service definition file.
90295

296+
```
297+
<Startup>
298+
<Task executionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd">
299+
</Task>
300+
</Startup>
301+
```
302+
303+
Here is an example that shows both the worker role and web role.
304+
305+
```
306+
<?xmlversion="1.0"encoding="utf-8"?>
307+
<ServiceDefinitionname="CloudServiceName"xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition"schemaVersion="2015-04.2.6">
308+
<WebRolename="WebRole1"vmsize="Standard_D1_v2">
309+
<Sites>
310+
<Sitename="Web">
311+
<Bindings>
312+
<Bindingname="Endpoint1"endpointName="Endpoint1"/>
313+
</Bindings>
314+
</Site>
315+
</Sites>
316+
<Startup>
317+
<Taske xecutionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd">
318+
</Task>
319+
</Startup>
320+
<Endpoints>
321+
<InputEndpointname="Endpoint1"protocol="http"port="80"/>
322+
</Endpoints>
323+
</WebRole>
324+
<WorkerRolename="WorkerRole1"vmsize="Standard_D1_v2">
325+
<Startup>
326+
<Task executionContext="elevated" taskType="simple" commandLine="RunTLSSettings.cmd">
327+
</Task>
328+
</Startup>
329+
</WorkerRole>
330+
</ServiceDefinition>
331+
```
332+
333+
## Step 5: Add the scripts to your Cloud Service
91334

335+
1) In Visual Studio, right-click on your WebRole
336+
2) Select **Add**
337+
3) Select **Existing Item**
338+
4) In the file explorer, navigate to your desktop where you stored the **TLSsettings.ps1** and **RunTLSSettings.cmd** files
339+
5) Select the two files to add them to your Cloud Services project
340+
341+
## Step 6: Enable Copy to Output Directory
342+
343+
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*
344+
345+
1) Under your WebRole, right-click on RunTLSSettings.cmd
346+
2) Select **Properties**
347+
3) In the properties tab, change *Copy to Output Directory* to *Copy Always"*
348+
4) Repeat the steps for **TLSsettings.ps1**
92349

93-
## Step 5: Publish & Validate
350+
## Step 7: Publish & Validate
94351

95352
Now that the above steps have been complete, publish the update to your existing Cloud Service.
96353

0 commit comments

Comments
 (0)