Last active
March 22, 2021 04:31
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.