Skip to content

Instantly share code, notes, and snippets.

@JimWolff
Last active March 22, 2021 04:31
Show Gist options
  • Save JimWolff/fc35d863db8971b2a73c96f90c5002e4 to your computer and use it in GitHub Desktop.
Save JimWolff/fc35d863db8971b2a73c96f90c5002e4 to your computer and use it in GitHub Desktop.
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")
@zappz88
Copy link

zappz88 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