Recently I’ve been updating the configuration of a bunch of personal servers to match the 2016 PCI requirements. One of the 2016 PCI requirements requires you to disable TLS 1.0 as it is now considered insecure. One of the problems with doing this of course is the fact that WebDeploy uses SSL and by default won’t allow connections and deployments to occur with TLS disabled. Luckily the fix is rather simple.
Disabling TLS 1.0 (and other out of date Ciphers)
While locking down a server to be PCI compliant for 2016, you need to disable TLS 1.0
There’s a great utility for enabling and disabling Ciphers on Windows servers – IIS Crypto by Nartac Software.
To use IIS Crypto to disable TLS 1.0 you simply open it, uncheck TLS 1.0, agree to the RDP connectivity warning (not and issue on Window Server 2012+), and restart the box.
Once you’ve disabled TLS 1.0 WebDeploy connections will begin to fail when deploying.
Take the example error message below:
Could not complete the request to remote agent URL 'https://XXXX:8172/msdeploy.axd?site=websitename'.
The underlying connection was closed: An unexpected error occured on a send.
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Given WebDeploy allows you to deploy stuff, not being able to connect is problematic.
The fix - Getting deployments working again
It turns out that after much stuffing around on my servers, the issue actually lies with the client doing the deploying.
The issue lies in .Net and it’s default settings for use of SSL.
By default .Net has a setting called “useStrongCrypto” that allows the client PC to use TLS 1.1 and higher.
To enable secure your local client PC to use TLS 1.1 and higher (or as Microsoft terms is “strong crypto”) you need to edit the following registry entries:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319\SchUseStrongCrypto = 00000001
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319\SchUseStrongCrypto = 00000001
Or you could simply cut and paste the following into a .reg file and run it (only do this if you know what you’re doing).
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319] "SchUseStrongCrypto"=dword:00000001 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319] "SchUseStrongCrypto"=dword:00000001
It’s that simple. Now your client PC will support connecting to WebDeploy again, and you’ll be supporting only stronger ciphers.
It seems really strange to me that the .Net framework would be set to not support higher security Ciphers than SSL 3.0 and TLS 1.0 – especially now that they’ve been found to be insecure and open to attack.
I’m glad there was a simple solution that allowed me to secure my servers and still deploy to them, but that seems beside the point as this has raised with me that by default .Net applications won’t connect over these stronger ciphers, even if they are available. With all of the commotion that has gone on over the past 2 years regarding web security, Microsoft should be setting a better example here and defaulting to higher ciphers at all times. I understand this comes at a cost in terms of CPU load and connectivity speed for lower performance clients, but in 2016 this is really less of an issue than it’s ever been in the history of computing, and is a small price to pay for the world to remain confident in their connectivity being secure.