Skip to content

Instantly share code, notes, and snippets.

@JimWolff
Last active March 22, 2021 04:31
Downloads IISCrypto cli, uses custom template based on bestpractice, to fix ssl security on servers, enables http2 on win2k16 server and grade A+ in qualys ssl server test if using TLS1.2 only template
# 2018-08-17 reintroduced templates for 2012 with ciphers: 0x9C, 0x9D they are considered weak, but are the only AEAD ciphers available for 2012 atm.
# updated 2018-08-16 with some extra steps like enabling OCSP for SNI, added TLS1.2 only option for pre win2k16 aswell, added check to see if HTTP/2 was disabled.
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Write-Host "Starting as administrator and using Bypass ExecutionPolicy.";Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
# Go to a location we have write access to.
Set-Location ~\Downloads
# Global variables and settings.
[System.Net.ServicePointManager]::SecurityProtocol = 192 -bor 768 -bor 3072 # .Net doesn't enable tls1.1 and 1.2 by default, but can run it as long as .net 4.5 is installed. Which we need to download from sites that only allows tls1.2
$icDownloadUrl = "http://www.nartac.com/Downloads/IISCrypto/IISCryptoCli.exe"
$icDownloadName = "IISCryptoCli.exe"
$templateName = "template.ictpl"
$templateUrl_2016_tls12only = "https://cdn.rawgit.com/JimWolff/4353334ee634c68753c4e61736ed0509/raw/88cbf054689e60fe7d79558423659bfd02ef5c87/bbp_http2fs_tls1.2only_win2k16-2018-04-18.ictpl"
$templateUrl_2016_broad = "https://cdn.rawgit.com/JimWolff/d8ea8ee58360f75c9283c6d74165774b/raw/d0018fc9ff611edc7ac0882de8737b776c33449a/bbp_http2fs_win2k16-2018-03-12.ictpl"
$templateUrl_pre2016_broad = "https://cdn.rawgit.com/JimWolff/f6969253fb23744ea2bfae57d8b990b1/raw/79c0d72878b54bf363501aa454d1e60078b92c98/bpp_2018-03-12.ictpl"
$templateUrl_pre2016_tls12only = "https://cdn.rawgit.com/JimWolff/cb86f299f16924363da43630a817438b/raw/67c40620cedb1a97e08fcb7a3cc2c4bdd11c26ba/bpp_2018-08-16_tls1.2only.ictpl"
$ocspRegPath = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\"
$oscpForSni = "EnableOcspStaplingForSni"
if(-Not (Test-Path -Path $icDownloadName)) {
Write-Host "Downloading IIS Crypto tool." -ForegroundColor Green
iwr -UseBasicParsing -Uri $icDownloadUrl -OutFile $icDownloadName
}
$chType = [System.Management.Automation.Host.ChoiceDescription]
$broadSupport = New-Object $chType "&Broad Support","Uses template with TLS 1.0 and TLS 1.1 support for broad backwards compatability"
$bestSecurity = New-Object $chType "Best &Security","Only enables TLS 1.2 protocol, this gives an A+ security rating for qualsys server test, but removes support for old systems that only run TLS 1.0/1.1 like: Android pre. 4.4.2, Baidu Jan 2015, IE<=10, Java<=7u25, OpenSSL<=0.9.8y, Safari 7 on OS X 10.8. more details: https://www.ssllabs.com/ssltest/clients.html"
$templateOptions = [System.Management.Automation.Host.ChoiceDescription[]]($bestSecurity, $broadSupport)
$templateResult = $host.ui.PromptForChoice("Security settings", "Do you want to use a broader template supporting TLS 1.0/1.1 or a more secure template only supporting TLS 1.2 (and ability to get A+ grade on IIS server with HSTS enabled)", $templateOptions, 0)
Write-Host "Downloading selected security template." -ForegroundColor Green
$isWin2k16 = (gwmi win32_operatingsystem | % caption) -like "Microsoft Windows Server 2016*"
if($isWin2k16){
if($templateResult -eq 0)
{
iwr -UseBasicParsing -Uri $templateUrl_2016_tls12only -OutFile $templateName
} else {
iwr -UseBasicParsing -Uri $templateUrl_2016_broad -OutFile $templateName
}
} else {
if($templateResult -eq 0)
{
iwr -UseBasicParsing -Uri $templateUrl_pre2016_tls12only -OutFile $templateName
} else {
iwr -UseBasicParsing -Uri $templateUrl_pre2016_broad -OutFile $templateName
}
}
Write-Host "IIS Crypto is applying selected template." -ForegroundColor Green
Start-Process -FilePath ".\$icDownloadName" -ArgumentList "/template",".\$templateName" -NoNewWindow -PassThru -Wait | out-null
# Cleanup
ri -Path $icDownloadName,$templateName -Confirm
$schannel = gi -Path "$ocspRegPath"
if($schannel.GetValue($oscpForSni) -eq $null -Or $schannel.GetValue($oscpForSni) -eq 0)
{
# ask to add OCSP for SNI
$oscp_yes = New-Object $chType "&Yes","Creates a scheduled task to run once tomorrow at 03:00 local time."
$oscp_no = New-Object $chType "&No","Exits the powershell script."
$oscp_options = [System.Management.Automation.Host.ChoiceDescription[]]($oscp_yes, $oscp_no)
$oscp_result = $host.ui.PromptForChoice("Enable OCSP Stapling for SNI:", "OCSP Stapling for SNI is currently disabled. Enabling this could provide performance benefits for HTTPS, unless you are using many ( > 100 ) certificates. More info: https://technet.microsoft.com/en-us/library/dn786418(v=ws.11).aspx", $oscp_options, 0)
switch ($oscp_result)
{
0 {
Write-Host "Creating OCSP Stapling for SNI registry key. ($ocspRegPath $oscpForSni)" -ForegroundColor Green
New-ItemProperty -Path "$ocspRegPath" -Name "$oscpForSni" -Value 1 -PropertyType DWord -Force | out-null
}
else {
Write-Host "Skipped."
}
}
} else {
Write-Host "OCSP Stapling for SNI is already enabled." -ForegroundColor Green
}
# check if HTTP/2 is disabled.
$http2Path = gi -Path "HKLM:\System\CurrentControlSet\Services\HTTP\Parameters"
$http2key1 = "EnableHttp2Tls"
$http2key2 = "EnableHttp2Cleartext"
if($isWin2k16 -And (($http2Path.GetValue($http2key1) -ne $null -And $http2Path.GetValue($http2key1) -eq 1) -Or ($http2Path.GetValue($http2key2) -ne $null -And $http2Path.GetValue($http2key2) -eq 1)))
{
Write-Host "Http/2 is currently disabled on your server, this might not be intended and isn't recommended." -ForegroundColor Green
}
$yes = New-Object $chType "&Yes","Creates a scheduled task to run once tomorrow at 03:00 local time."
$no = New-Object $chType "&No","Exits the powershell script."
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice("ScheduledTask to Restart-Computer:", "Do you want to create a scheduled task to restart the computer?", $options, 0)
$taskName = "FixSSLSecurity-OneTimeRestartJob"
$taskTriggerTime = (Get-Date).Date.AddDays(1).AddHours(3)
switch ($result) {
0 {
Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue -OutVariable existingTask | out-null
if($existingTask) {
$newTime = New-ScheduledTaskTrigger -Once -At $taskTriggerTime
Set-ScheduledTask -TaskName $taskName -Trigger $newTime | out-null
Write-Host "$taskName Exists. Task trigger restart time set to:" (Get-Date -Date $taskTriggerTime -Format f)
} else {
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "Restart-Computer"
$trigger = New-ScheduledTaskTrigger -Once -At $taskTriggerTime
$principal = New-ScheduledTaskPrincipal "SYSTEM" -RunLevel Highest
$task = New-ScheduledTask -Action $action -Trigger $trigger -Principal $principal
Try {
Register-ScheduledTask $taskName -InputObject $task -ErrorAction Stop | out-null
Write-Host "$taskName Created. Computer will restart once, at:" (Get-Date -Date $taskTriggerTime -Format f)
} Catch {
Write-Host "Error, could not create ScheduledTask:" $_.Exception.Message
Break
}
}
}
1 { "No Scheduled task created. Remember to schedule a restart of the server for changes to take effect!" }
}
Write-Host "Press any key to close ..." -ForegroundColor Green
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
Copy link

ghost commented Mar 22, 2021

I think you may have a glitch in your code at this section:

if($isWin2k16 -And (($http2Path.GetValue($http2key1) -ne $null -And $http2Path.GetValue($http2key1) -eq 1) -Or ($http2Path.GetValue($http2key2) -ne $null -And $http2Path.GetValue($http2key2) -eq 1)))
{
Write-Host "Http/2 is currently disabled on your server, this might not be intended and isn't recommended." -ForegroundColor Green
}

You do a value check on the keys and whether they're equal to 1. I think you meant 0 as the check other than $null. Also they've since adjusted the Windows 10/Server 2016 value to be a DWORD value named "DuoEnabled" in the "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters" registry location and set to 1. More details on it here "https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis" and this is at least on the server end. I think the other two are on the client end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment