Configuring and Testing SSL Settings on App Service Environment (ASE)

PLEASE NOTE: There are new features available for switching off TLS 1.0. I recommend using those instead.

Azure App Service Environment (ASE) is a private deployment of Azure Web Apps in a virtual network. Because it allows virtual network isolation, it is ideally suited for Government Web Apps and it is now available in Azure Government.

It has been recommended by NIST that TLS 1.0 be disabled for Government web sites. I have written about this issue for public Web Apps and how to use an App Gateway to disable TLS 1.0. One of the nice features of the ASE is that you can control the SSL policy for the environment, i.e., you don't need an App Gateway in order to control the SSL policy.

I have posted a template for deploying an ASE, and in that example TLS 1.0 is disabled in the template through the clusterSettings parameter:

[plain]
{
"apiVersion": "2016-09-01",
"type": "Microsoft.Web/hostingEnvironments",
"name": "[parameters('appServiceEnvironmentName')]",
"location": "[parameters('existingAseLocation')]",
"properties": {
"clusterSettings": [
{
"name": "DisableTls1.0",
"value": "1"
}
]
}
}
[/plain]

In this blog post I will show you how to verify the settings and make changes to them using PowerShell.

In previous blog posts, I have recommended https://ssllabs.com for testing websites. It is a great tool, but it requires the website to be publically accessible. In many cases, an ASE website would not be. We need a tool that allow us to test private websites internally from the virtual network. I recommend this list of SSL Assessment Tools. There are many different tools available but in this blog post, I have used the SSLyze tool. It is written in Python and there is also a nice library that you can use in to write your own custom tools for testing. For Windows, you can download an executable here.

Here is an example of using the tool to scan an ASE environment where TLS 1.0 is still enabled:

[ps]

.\sslyze.exe --tlsv1 app1.cloudynerd.us:443

CHECKING HOST(S) AVAILABILITY
-----------------------------
app1.cloudynerd.us:443 10.0.1.11

SCAN RESULTS FOR APP1.CLOUDYNERD.US:443 - 10.0.1.11
---------------------------------------------------

* TLSV1 Cipher Suites:
Preferred:
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ECDH-256 bits 256 bits

Accepted:
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ECDH-256 bits 256 bits
TLS_RSA_WITH_AES_256_CBC_SHA - 256 bits
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ECDH-256 bits 128 bits
TLS_RSA_WITH_AES_128_CBC_SHA - 128 bits

Rejected:
TLS_RSA_WITH_SEED_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_RC4_128_SHA TCP / Received FIN
TLS_RSA_WITH_RC4_128_MD5 TCP / Received FIN
TLS_ECDH_anon_WITH_AES_256_CBC_SHA TCP / Received FIN

... # Many more rejected cipher suites
[/ps]

Notice that there are some accepted TLS 1.0 ciphers. In order to switch TLS 1.0 off, we need to modify the clusterSettings of the ASE, which we can do with PowerShell. First, let's grab the current properties of the ASE:

[ps]
$r = Get-AzureRmResource -ResourceGroupName RESOURCE-GROUP `
-ResourceType Microsoft.Web/hostingEnvironments `
-ResourceName ASE-NAME -ApiVersion 2016-09-01

$currentSettings = $r.Properties.clusterSettings
[/ps]

If you look at that object, you will see something like:

[ps]
$currentSettings

name value
---- -----
DefaultSslCertificateThumbprint 6C31BA8690B8XXXXXXXXXXXXXXXXXXXXX
[/ps]

In this case, we want to add a custom setting to disable TLS 1.0:

[ps]
$currentSettings += New-Object -TypeName PSCustomObject -Property @{name="DisableTls1.0"; value=1}
[/ps]

Then we can modify the resource:

[ps]
#Update Properties
$r.Properties.clusterSettings = $currentSettings

#Update resource
Set-AzureRmResource -ResourceGroupName RESOURCE-GROUP `
-ResourceType Microsoft.Web/hostingEnvironments `
-ResourceName ASE-NAME -ApiVersion 2016-09-01 `
-PropertyObject $r.Properties -Force
[/ps]

Running this last command will take some time to run while the cluster updates. If you have DisableTls1.0 enabled and you want to disable it, you should modify the parameter in the clusterSettings instead of adding to it as we have done above. The list of custom settings for the ASE is maintained here. As you can see you can also control specific ciphers.

Once the update of the ASE parameters is complete, you should be able to repeat the scan and verify that your changes have taken effect:

[ps]
.\sslyze.exe --tlsv1 app1.cloudynerd.us:443

CHECKING HOST(S) AVAILABILITY
-----------------------------

app1.cloudynerd.us:443 10.0.1.11

SCAN RESULTS FOR APP1.CLOUDYNERD.US:443 - 10.0.1.11
---------------------------------------------------

* TLSV1 Cipher Suites:
Rejected:
TLS_RSA_WITH_SEED_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_RC4_128_SHA TCP / Received FIN
TLS_RSA_WITH_RC4_128_MD5 TCP / Received FIN
TLS_RSA_WITH_NULL_SHA256 TLS / No ciphers available
TLS_RSA_WITH_NULL_SHA TCP / Received FIN
TLS_RSA_WITH_NULL_MD5 TCP / Received FIN
TLS_RSA_WITH_IDEA_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_DES_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_AES_256_GCM_SHA384 TLS / No ciphers available
TLS_RSA_WITH_AES_256_CBC_SHA256 TLS / No ciphers available
TLS_RSA_WITH_AES_256_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_AES_128_GCM_SHA256 TLS / No ciphers available
TLS_RSA_WITH_AES_128_CBC_SHA256 TLS / No ciphers available
TLS_RSA_WITH_AES_128_CBC_SHA TCP / Received FIN
TLS_RSA_WITH_3DES_EDE_CBC_SHA TCP / Received FIN
TLS_RSA_EXPORT_WITH_RC4_40_MD5 TCP / Received FIN

... # Many more rejected cipher suites
[/ps]

After the modification, all ciphers are rejected for TLS 1.0.

And that's it, you now have a way of checking specific TLS settings and capabilities of your ASE using command line tools such as SSLyze. You can modify the setting of your ASE with PowerShell and verify that you have the desired configuration.

Please let me know if you have questions/comments/suggestions.