Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for IIS on Windows 1809 #36

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/js/configs.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,54 @@ module.exports = {
supportsOcspStapling: false,
tls13: '12.0',
},
iis: {
hasVersions: false,
highlighter: 'ps',
latestVersion: '10.0.17763', // https://en.wikipedia.org/wiki/Internet_Information_Services
name: 'Microsoft Internet Information Services',
supportedCiphers: [ // https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/tls-cipher-suites-in-windows-10-v1809
'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384',
'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256',
'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384',
'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256',
'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384',
'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256',
'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA',
'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA',
'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA',
'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA',
'TLS_RSA_WITH_AES_256_GCM_SHA384',
'TLS_RSA_WITH_AES_128_GCM_SHA256',
'TLS_RSA_WITH_AES_256_CBC_SHA256',
'TLS_RSA_WITH_AES_128_CBC_SHA256',
'TLS_RSA_WITH_AES_256_CBC_SHA',
'TLS_RSA_WITH_AES_128_CBC_SHA',
'TLS_RSA_WITH_3DES_EDE_CBC_SHA',
'TLS_RSA_WITH_NULL_SHA256',
'TLS_DHE_RSA_WITH_AES_256_CBC_SHA',
'TLS_DHE_RSA_WITH_AES_128_CBC_SHA',
'TLS_DHE_DSS_WITH_AES_256_CBC_SHA256',
'TLS_DHE_DSS_WITH_AES_128_CBC_SHA256',
'TLS_DHE_DSS_WITH_AES_256_CBC_SHA',
'TLS_DHE_DSS_WITH_AES_128_CBC_SHA',
'TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA',
'TLS_RSA_WITH_RC4_128_SHA',
'TLS_RSA_WITH_RC4_128_MD5',
'TLS_RSA_WITH_DES_CBC_SHA',
'TLS_DHE_DSS_WITH_DES_CBC_SHA',
'TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA',
'TLS_RSA_WITH_NULL_MD5',
'TLS_RSA_EXPORT1024_WITH_RC4_56_SHA',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These may be supported (yikes, are they really???), but we should definitely not include them here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How else would you suggest to handle this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you prefer to drop all obvious insecure cipher suites (NULL, SHA1, CBC, etc...)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@april what's to do for me here?

'TLS_RSA_EXPORT_WITH_RC4_40_MD5',
'TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA',
],
supportsHsts: true,
supportsOcspStapling: true,
tls13: noSupportedVersion,
lennybacon marked this conversation as resolved.
Show resolved Hide resolved
usesOpenssl: false,
},
traefik: {
cipherFormat: 'go',
highlighter: 'ini',
Expand Down
4 changes: 3 additions & 1 deletion src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import ini from 'highlight.js/lib/languages/ini';
import json from 'highlight.js/lib/languages/json';
import nginx from 'highlight.js/lib/languages/nginx';
import yaml from 'highlight.js/lib/languages/yaml';
import ps from 'highlight.js/lib/languages/powershell';
hljs.registerLanguage('apache', apache);
hljs.registerLanguage('ini', ini);
hljs.registerLanguage('json', json);
hljs.registerLanguage('nginx', nginx);
hljs.registerLanguage('ps', ps);
lennybacon marked this conversation as resolved.
Show resolved Hide resolved
hljs.registerLanguage('yaml', yaml);

import '../css/index.scss';
Expand Down Expand Up @@ -136,4 +138,4 @@ $().ready(() => {
await sleep(750);
$('#copy').tooltip('hide');
});
});
});
19 changes: 12 additions & 7 deletions src/js/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,16 @@ export default async function () {
protocols = protocols.filter(ciphers => ciphers !== 'TLSv1.3');
}

let ciphers = configs[server].cipherFormat ? ssc.ciphers[configs[server].cipherFormat] : ssc.ciphers.openssl;
let openssl_ciphers = configs[server].cipherFormat ? ssc.ciphers[configs[server].cipherFormat] : ssc.ciphers.openssl;
let windows_ciphers = [];
if (configs[server].supportedCiphers) {
ciphers = ciphers.filter(suite => configs[server].supportedCiphers.indexOf(suite) !== -1);
} else {
ciphers = ciphers;
}
windows_ciphers = openssl_ciphers.filter(suite =>
{
var suiteName ='TLS_' + suite.replace(/-/g, '_').replace('_AES128_','_WITH_AES_128_').replace('_AES256_','_WITH_AES_256_');
return configs[server].supportedCiphers.indexOf(suiteName) !== -1
});
openssl_ciphers = openssl_ciphers.filter(suite => configs[server].supportedCiphers.indexOf(suite) !== -1);
}

const state = {
form: {
Expand All @@ -45,8 +49,9 @@ export default async function () {
serverVersion: form['server-version'].value,
},
output: {
ciphers,
cipherSuites: ssc.ciphersuites,
ciphers: openssl_ciphers, // OpenSSL
windowsCiphers: windows_ciphers, // Windows and so IIS
cipherSuites: ssc.openssl_ciphersuites,
date: date.toISOString().substr(0, 10),
dhCommand: ssc.dh_param_size >= 2048 ? `curl ${url.origin}/ffdhe${ssc.dh_param_size}.txt` : `openssl dhparam ${ssc.dh_param_size}`,
dhParamSize: ssc.dh_param_size,
Expand Down
187 changes: 187 additions & 0 deletions src/templates/partials/iis.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
# {{output.date}}, {{{output.link}}}
function Set-Cipher($name, $value){
Write-Host "Set-Ciphers ``$name`` ``$value``"
$key = [Microsoft.Win32.Registry]::LocalMachine;
$subKey = $key.CreateSubKey("SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\$name")
$return = $subKey.SetValue("Enabled", $value, [Microsoft.Win32.RegistryValueKind]::DWord)
$subKey.Close();
$key.Close();
}

function Reset-Ciphers(){
Write-Host "Reset-Ciphers"
$sChannelKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers"
Remove-Item -Path $sChannelKey -Recurse -Force
$return = New-Item -Path $sChannelKey
$return = Set-ItemProperty -Path $sChannelKey -Name "EventLogging" -Value 1 -Type DWord
$return = Set-ItemProperty -Path $sChannelKey -Name "DisableRenegoOnClient" -Value 1 -Type DWord
$return = Set-ItemProperty -Path $sChannelKey -Name "DisableRenegoOnServer" -Value 1 -Type DWord
}

function Set-Hash($name, $value){
Write-Host "Set-Hashes ``$name`` ``$value``"
$hashKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes\$name"
if($false -eq (Test-Path $hashKey)){
$return = New-Item -Path $hashKey
}
$return = Set-ItemProperty -Path $hashKey -Name "Enabled" -Value $value -Type DWord
}

function Reset-Hashes(){
Write-Host "Reset-Hashes"
$hashesKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Hashes"
Remove-Item -Path $hashesKey -Recurse -Force
$return = New-Item -Path $hashesKey
}

function Set-KeyExchangeAlgorithm($name, $value){
Write-Host "Set-KeyExchangeAlgorithm ``$name`` ``$value``"
$keyExchangeAlgorithmKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\$name"
if($false -eq (Test-Path $keyExchangeAlgorithmKey)){
$return = New-Item -Path $keyExchangeAlgorithmKey
}
$return = Set-ItemProperty -Path $keyExchangeAlgorithmKey -Name "Enabled" -Value $value -Type DWord
}

function Reset-KeyExchangeAlgorithms(){
Write-Host "Reset-KeyExchangeAlgorithms"
$keyExchangeAlgorithmsKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms"
Remove-Item -Path $keyExchangeAlgorithmsKey -Recurse -Force
$return = New-Item -Path $keyExchangeAlgorithmsKey
}

function Set-SChannelProtocol($name, $value, $clientAlso){
Write-Host "Set-SChannelProtocol ``$name`` ``$value``"
$protocolKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$name"
if($false -eq (Test-Path $protocolKey)){
$return = New-Item -Path $protocolKey
}
$protocolKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$name\Server"
if($false -eq (Test-Path $protocolKey)){
$return = New-Item -Path $protocolKey
}
Set-ItemProperty -Path $protocolKey -Name "Enabled" -Value $value -Type DWord
if($value -eq 0x00000000){
$return = Set-ItemProperty -Path $protocolKey -Name "DisabledByDefault" -Value 0x00000001 -Type DWord
}else{
$return = Set-ItemProperty -Path $protocolKey -Name "DisabledByDefault" -Value 0x00000000 -Type DWord
}
if($clientAlso){
$protocolKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\$name\Client"
if($false -eq (Test-Path $protocolKey)){
$return = New-Item -Path $protocolKey
}
if($value -eq 0x00000000){
$return = Set-ItemProperty -Path $protocolKey -Name "DisabledByDefault" -Value 0x00000001 -Type DWord
}else{
$return = Set-ItemProperty -Path $protocolKey -Name "DisabledByDefault" -Value 0x00000000 -Type DWord
}
}
}

function Reset-SChannelProtocols(){
Write-Host "Reset-SChannelProtocols"
$protocolKey = "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\"
$r = Remove-Item -Path $protocolKey -Recurse -Force
$return = New-Item -Path $protocolKey
}

function Remove-RegistryValue($path, $name){
Write-Host "Remove-RegistryValue ``$name``"
$key = Get-Item -LiteralPath $path
if ($key.GetValue($name, $null) -ne $null) {
$r = Remove-ItemProperty -Path $path -Name $name
}
}

# Restrict the use of certain cryptographic algorithms and protocols in Schannel.dll
# https://support.microsoft.com/en-us/help/245030/how-to-restrict-the-use-of-certain-cryptographic-algorithms-and-protoc
Reset-Chihers
Set-Cipher -name "AES 128/128" -value 0xffffffff
Set-Cipher -name "AES 256/256" -value 0xffffffff
Set-Cipher -name "DES 56/56" -value 0x00000000
Set-Cipher -name "NULL" -value 0x00000000
Set-Cipher -name "RC2 128/128" -value 0x00000000
Set-Cipher -name "RC2 40/128" -value 0x00000000
Set-Cipher -name "RC2 56/128" -value 0x00000000
Set-Cipher -name "RC4 128/128" -value 0x00000000
Set-Cipher -name "RC4 40/128" -value 0x00000000
Set-Cipher -name "RC4 56/128" -value 0x00000000
Set-Cipher -name "RC4 64/128" -value 0x00000000
Set-Cipher -name "Triple DES 168/168" -value 0x00000000

Reset-Hashes
Set-Hash -name "MD5" -value 0x00000000
Set-Hash -name "SHA" -value 0x00000000
Set-Hash -name "SHA256" -value 0xffffffff
Set-Hash -name "SHA384" -value 0xffffffff
Set-Hash -name "SHA512" -value 0xffffffff

Reset-KeyExchangeAlgorithms
Set-KeyExchangeAlgorithm -name Diffie-Hellman -value 0xffffffff
Set-KeyExchangeAlgorithm -name PKCS -value 0xffffffff
Set-KeyExchangeAlgorithm -name ECDH -value 0xffffffff

Reset-SChannelProtocols
Set-SChannelProtocol -name "Multi-Protocol Unified Hello" -value 0x00000000
Set-SChannelProtocol -name "PCT 1.0" -value 0x00000000
Set-SChannelProtocol -name "SSL 2.0" -value 0x00000000
Set-SChannelProtocol -name "SSL 3.0" -value 0x00000000
Set-SChannelProtocol -name "TLS 1.0" -value 0x00000000
Set-SChannelProtocol -name "TLS 1.1" -value 0x00000000
Set-SChannelProtocol -name "TLS 1.2" -value 0xffffffff

Remove-RegistryValue `
-path "HKLM:\SOFTWARE\Policies\Microsoft\Cryptography\Configuration\SSL\00010002" `
-name "Functions"

$ssl_ciphers = '{{{join output.windowsCiphers ","}}}'.Split(',') `
| Foreach-Object { "TLS_$($_)".replace("-", "_").replace("_AES128_", "_WITH_AES128_").replace("_AES256_", "_WITH_AES256_") };

import-module tls
#https://docs.microsoft.com/en-us/powershell/module/tls/get-tlsciphersuite?view=win10-ps

Foreach($suites in Get-TlsCipherSuite){
Foreach($suite in $suites){
if($ssl_ciphers.IndexOf($suite.Name) -eq -1){
Write-Host "Disable-TlsCipherSuite ``$($suite.Name)``"
Disable-TlsCipherSuite -Name "$($suite.Name)";
}
}
}

Foreach($suite in $ssl_ciphers){
Write-Host "Enable ``$suite``"
Enable-TlsCipherSuite -Name "$suite"
}

{{#if form.ocsp}}
Write-Host "Enable OCSP stapling for SNI"
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\" -Name "EnableOcspStaplingForSni" -PropertyType DWord -Value 1
{{/if}}

{{#if form.hsts}}
#https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10-version-1709/iis-10-version-1709-hsts

Import-Module IISAdministration

Reset-IISServerManager -Confirm:$false
Start-IISCommitDelay

$ConfigSection = Get-IISConfigSection -SectionPath "system.applicationHost/sites"
Foreach($SitesCollection in Get-IISConfigCollection -ConfigElement $ConfigSection){
foreach($item in $SitesCollection){
$siteName = $item.GetAttributeValue("name")
$tlsBindings = Get-WebBinding -Name "$siteName" | Where-Object { $_.protocol -eq "https"} | Select-Object -First 1
if($tlsBindings -ne $null){
Write-Host "Enable HSTS on site ``$($siteName)``"
$Site = Get-IISConfigCollectionElement -ConfigCollection $SitesCollection -ConfigAttribute @{"name" = "$siteName"}
$Elem = Get-IISConfigElement -ConfigElement $Site -ChildElementName "limits"
Set-IISConfigAttributeValue -ConfigElement $Elem -AttributeName "MaxUrlSegments" -AttributeValue 16
}
}
}

Stop-IISCommitDelay
Remove-Module IISAdministration
{{/if}}