Edit: There is now an option in the resource manager that allows you set the minimum TLS version to 1.2.
Disabling SSL and early TLS is a PCI Compliance requirement. After several research, trial and errors, I have put up this guide that will help you achieve this without using an App Service Environment (ASE).
Secure cryptographic protocols have been around for years now with the release of SSL 2.0 in 1995 by Netscape — they never released 1.0 to the public. Since then, different versions have been released to address various vulnerabilities. These protocols provide authentication and data encryption between servers and network applications. In 1999, TLS 1.0 was introduced as a new version of SSL 3.0 ( why not just continue to SSL 4.0 :) )
POODLE, a man-in-the-middle exploit is a well known SSL vulnerability. In December 2014, security researchers discovered that a POODLE-type attack could also be launched directly at TLS. This discovery possibly led the PCI Council in their version 3.1 of the Data Security Standard(DSS), to declare that SSL and early TLS can no longer be used after June 30, 2016. (The deadline has been extended to June 30th, 2018)
The can’t be done
To pass PCI Compliance, your host needs to have SSL and TLS 1.0 disabled and support only TLS 1.2 or later ( lastest version is v1.2, with TLS 1.3 currently in draft ).
Now according to the Azure team, App Service is using a shared infrastructure, and the only way to disable this is to do so across board — which they can’t because there’s a surprising number of customers that still require it.
I need to point out that as of the time of this writing, the proposed way to disable TLS 1.0 below, is deemed not supported by Azure. So far, the only recommended way to do this is by using an App Service Environment (more like a private VPS) — needless to say, you get to pay a premium price for this. Check this thread for more information
The How? — Using Application Gateway
Application Gateway is one of the different options to distribute network traffic in Azure — It is a load balancer.
Prerequisite: You have an existing Web App and a domain with access to modify DNS records. You can read up on creating a Web App here .
1, Get your passworded PFX — Usually your Certificate Authority (CA) — where you bought your SSL/TLS certificate from — should provide you this. If you are using free ssl from letsencrypt ( as i did here) then you’ll have to convert the certificate files to pfx using this ssl converter.
- FTP to your Web App
- Navigate to /SiteExtensions/letsencrypt/config and download the certificates.
- Upload the files <domain>-crt.pem and <domain>-key.pem , select PFX/PKCS#12 as the format to convert to and choose a password.
2, Create an Application Gateway in Azure
- Go to New > Networking > Application Gateway
- Choose the Standard or WAF (to use Azure Firewall) tier
- Location MUST be same as that of your Web App
- Create a new Virtual Network and Public IP address (IP type should be public)
- Select the Listener Protocol to be HTTPS and upload the PFX you just converted
- Finish setup (this might take about 15 -20 minutes to complete)
3, Configure your domain
- Go to your registrar and point your A record to the public IP you just created. This IP is attached to your Application Gateway.
I would recommend pointing to the Application Gateway DNS <something>.cloudapp.net so that if the IP changes, nothing breaks, but most registrars like Godaddy allow only IP address as an A record value. If this is an issue, use a CNAME
4, Connect your Gateway to your Web app
- On your Application Gateway, Go to Backend pools, click on the created pool and click Add Target
- Enter the Azure generated domain for your Web App <webapp>.azurewebsites.net and save.
- Go to Health probes to add a custom probe. Enter a name and select HTTP as the protocol. Use <webapp>.azurewebsites.net as the host and select the root path (/) then save.
- After your custom health probe has been created, go to HTTP settings, select Use custom probe then choose the probe you just created.
- Go to Backend health. If the status show Healthy then you are good to proceed
You can try browsing your domain now and verify that it works fine and the https lock sign is not crossed on your browser.
If you get a 502 error, remove all redirect rules from your web config.
Note: From the setup, your Gateway is listening only on port 443, browsing the site without https will not work.
5, Disable TLS 1.0
If you run an SSL test, at the Configuration section, you can see that TLS 1.0, 1.1 and 1.2 are all supported. We are going to support only 1.2. Disabling TlS can only be done only via Azure PowerShell. Make sure you have the latest version installed.
- Authenticate with your email and password
- Enter the following command
$gw = Get-AzureRmApplicationGateway -Name <gatewayname> -ResourceGroupName <resourcegroup> Set-AzureRmApplicationGatewaySslPolicy -DisabledSslProtocols TLSv1_0, TLSv1_1 -ApplicationGateway $gw $gw | Set-AzureRmApplicationGateway
The last command will take some time to complete. Once its done, run another SSL test, you should see only TLS 1.2 supported.
6, Create HTTP Listener and Redirect HTTP to HTTPS
For the most part you are done, but your web app is dead on HTTP. A simple server redirect rule in your web config will conflict with your Gateway’s internal routing rules and cause a 502 bad gateway error.
Note: Make sure you have the latest version of Azure PowerShell installed. Some of the commands might not work with older versions.
- Authenticate with your email and password
- Enter the following command
# Get the application gateway
$gw = Get-AzureRmApplicationGateway -Name <gatewayname> -ResourceGroupName <resourcegroup>
# Get the existing HTTPS listener
$httpslistener = Get-AzureRmApplicationGatewayHttpListener -Name appGatewayHttpListener -ApplicationGateway $gw
# Get the existing front end IP configuration
$fipconfig = Get-AzureRmApplicationGatewayFrontendIPConfig -Name appGatewayFrontendIP -ApplicationGateway $gw
# Add a new front end port to support HTTP traffic
Add-AzureRmApplicationGatewayFrontendPort -Name appGatewayFrontendPort2 -Port 80 -ApplicationGateway $gw
# Get the recently created port
$fp = Get-AzureRmApplicationGatewayFrontendPort -Name appGatewayFrontendPort2 -ApplicationGateway $gw
# Create a new HTTP listener using the port created earlier
Add-AzureRmApplicationGatewayHttpListener -Name appgatewayhttplistener2 -Protocol Http -FrontendPort $fp -FrontendIPConfiguration $fipconfig -ApplicationGateway $gw
# Get the new listener
$listener = Get-AzureRmApplicationGatewayHttpListener -Name appgatewayhttplistener2 -ApplicationGateway $gw
# Add a redirection configuration using a permanent redirect
Add-AzureRmApplicationGatewayRedirectConfiguration -Name sendHttptoHttps -RedirectType Permanent -TargetListener $httpslistener -IncludePath $true -IncludeQueryString $true -ApplicationGateway $gw
# Get the redirect configuration
$myredirectconfig = Get-AzureRmApplicationGatewayRedirectConfiguration -Name sendHttptoHttps -ApplicationGateway $gw
# Add a new rule to handle the redirect and use the new listener
Add-AzureRmApplicationGatewayRequestRoutingRule -Name myrule -RuleType Basic -HttpListener $listener -RedirectConfiguration $myredirectconfig -ApplicationGateway $gw
# Update the application gateway
Set-AzureRmApplicationGateway -ApplicationGateway $gw
That’s it. Now check out the redirect on your browser. To redirect www to non-www simply add a www CNAME record and point it to your Web App’s azure assigned domain <webapp>.azurewebsites.net . The Application Gateway will handle the redirect.
Introduction to Application Gateway in Azure
Application Gateway SSL Termination
Configuring Application Gateway redirect rule
Poodle vulnerability in SSL 3
SSL and TLS no longer acceptable for PCI Compliance