Qual è il modo migliore per attivare HTTP Strict Transport Security su un server Web IIS 7?
Posso semplicemente usare la GUI e aggiungere l'intestazione della risposta HTTP corretta o dovrei usare appcmd e, in caso affermativo, cosa cambia?
Qual è il modo migliore per attivare HTTP Strict Transport Security su un server Web IIS 7?
Posso semplicemente usare la GUI e aggiungere l'intestazione della risposta HTTP corretta o dovrei usare appcmd e, in caso affermativo, cosa cambia?
Risposte:
IIS ha la possibilità di aggiungere intestazioni personalizzate alle risposte . Questo sembrerebbe essere il modo più semplice per farlo.
Secondo la documentazione su IIS.net è possibile aggiungere queste intestazioni tramite Gestione IIS:
- Nel riquadro Connessioni, vai al sito, all'applicazione o alla directory per cui desideri impostare un'intestazione HTTP personalizzata.
- Nel riquadro Home, fare doppio clic su Intestazioni risposta HTTP.
- Nel riquadro Intestazioni risposta HTTP, fai clic su Aggiungi ... nel riquadro Azioni.
- Nella finestra di dialogo Aggiungi intestazione risposta HTTP personalizzata, impostare il nome e il valore per l'intestazione personalizzata, quindi fare clic su OK.
Questo ci consente di gestire sia il reindirizzamento HTTP sia di aggiungere l'intestazione Strict-Transport-Security alle risposte HTTPS con un singolo sito IIS (il modulo di riscrittura URL deve essere installato):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}"
redirectType="Permanent" />
</rule>
</rules>
<outboundRules>
<rule name="Add Strict-Transport-Security when HTTPS" enabled="true">
<match serverVariable="RESPONSE_Strict_Transport_Security"
pattern=".*" />
<conditions>
<add input="{HTTPS}" pattern="on" ignoreCase="true" />
</conditions>
<action type="Rewrite" value="max-age=31536000; includeSubDomains; preload" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
<action type="Rewrite" value="max-age=31536000 ;includeSubDomains; preload" />
ottenere un passaggio su hstspreload.org
https://somedomain.com/https://somedomain.com/relatedpath
e il risultato è che il percorso viene abbandonato.
Per integrare la risposta di voretaq7 , puoi anche farlo usando il file Web.config (NB: da usare solo per siti SSL, poiché aggiungerà l'intestazione per le risposte HTTP e HTTPS, che è contro la specifica RFC 6797, si prega di consultare la spiegazione di seguito) - aggiungere un blocco come segue:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Strict-Transport-Security" value="max-age=31536000"/>
</customHeaders>
</httpProtocol>
</system.webServer>
Ovviamente, potresti già avere un system.webServer
blocco nel tuo Web.config, quindi aggiungi questo, se è così. Preferiamo gestire le cose nel Web.config piuttosto che nella GUI, perché significa che le modifiche alla configurazione possono essere impegnate nel nostro repository Git.
Se si desidera gestire il reindirizzamento da HTTP a SSL, come menzionato da Greg Askew , potrebbe essere più semplice farlo con un sito Web separato in IIS. Ecco come gestiamo la richiesta di SSL per alcuni siti client. Quel sito contiene solo un reindirizzamento HTTP e alcune correzioni per la divulgazione di informazioni , tutto in Web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<httpRuntime requestValidationMode="2.0" enableVersionHeader="false" />
</system.web>
<system.webServer>
<httpRedirect enabled="true" destination="https://www.domain.co.uk/"
httpResponseStatus="Permanent" />
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
<rewrite>
<outboundRules>
<rule name="Remove RESPONSE_Server">
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Questa è la nostra soluzione preferita per un paio di motivi: possiamo facilmente registrare separatamente il traffico reindirizzato (poiché si trova in un diverso registro IIS), non comporta più codice in Global.asax.cs (non abbiamo alcun codice lì dentro, che è un po 'più conveniente per un sito Umbraco) e, soprattutto, significa che tutta la configurazione è ancora presente nel nostro repository GIT.
Modificato per aggiungere: per essere chiari, al fine di ottemperare a RFC 6797 , l' Strict-Transport-Security
intestazione personalizzata NON DEVE essere aggiunta alle richieste fatte da HTTP non crittografato. Per essere conforme a RFC6797, DEVI avere due siti in IIS, come ho descritto dopo il primo blocco di codice. Come sottolinea Chris , RFC 6797 include:
Un host HSTS NON DEVE includere il campo di intestazione STS nelle risposte HTTP trasmesse su trasporto non sicuro.
pertanto l'invio Strict-Transport-Security
dell'intestazione del cliente in risposta a una richiesta non SSL non sarebbe conforme alle specifiche.
Vorrei usare l'esempio dal link Wikipedia a cui hai fatto riferimento ed eseguire l'attività in global.asax per il sito. Ciò consente di reindirizzare la richiesta a un URL https, quindi inserire l'intestazione nella risposta.
Ciò è dovuto al fatto che l'intestazione HSTS deve essere ignorata se non è in una risposta https.
protected void Application_BeginRequest()
{
switch (Request.Url.Scheme)
{
case "https":
Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
break;
case "http":
var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", path);
break;
}
}
Questo sembra essere un modo abbastanza sicuro per farlo. Aggiungi questo codice in Global.asax: l'evento Application_BeginRequest viene generato per primo nel ciclo di vita della richiesta Asp.net: http://msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs. 110) aspx
Secondo le specifiche, le richieste http non devono rispondere con l'intestazione, quindi questo codice lo aggiunge solo per le richieste https. Max-age è in numero di secondi ed è generalmente una buona idea inserire un valore elevato qui (IE - 31536000 indica che il sito eseguirà SSL solo per i prossimi 365 giorni)
protected void Application_BeginRequest(Object sender, EventArgs e)
{
switch (Request.Url.Scheme)
{
case "https":
Response.AddHeader("Strict-Transport-Security", "max-age=31536000");
break;
case "http":
var path = "https://" + Request.Url.Host + Request.Url.PathAndQuery;
Response.Status = "301 Moved Permanently";
Response.AddHeader("Location", path);
break;
}
}
Utilizzando l'esempio fornito da Doug Wilson, ho creato le seguenti due funzioni di PowerShell per aggiungere regole di riscrittura degli URL per il reindirizzamento a HTTPS e per l'aggiunta di intestazioni HSTS.
Questi sono stati testati su Windows 2012 e Windows 2012 R2.
Tutto quello che devi fare è fornire il nome del sito web. Opzionalmente puoi assegnare un nome diverso alle regole se non ti piacciono le impostazioni predefinite.
Una cosa da notare è che dal mio test, le variabili del server devono essere aggiunte all'elenco di autorizzazioni prima di essere nelle intestazioni di risposta. Le funzioni fanno questo per te.
EDIT: vedi riferimento su Url Rewrite per le intestazioni HTTP qui: http://www.iis.net/learn/extensions/url-rewrite-module/setting-http-request-headers-and-iis-server-variables
Function Add-HTTPSRedirectRewriteRule()
{
<#
.SYNOPSIS
This function is used to create a URL Rewrite Rule that redirects HTTP requests to HTTPS using a 301
RuleName is optional and will default to "Redirect to HTTPS"
.SYNTAX
Add-HTTPSRedirectRewriteRule -WebsiteName "www.mywebsite.com"
.EXAMPLES
Add-HTTPSRedirectRewriteRule -WebsiteName "www.mywebsite.com"
Add-HTTPSRedirectRewriteRule -WebsiteName "www.mywebsite.com" -RuleName "my rule name"
#>
[cmdletbinding(positionalbinding=$false)]
Param
(
[parameter(mandatory=$true)][String] [ValidateNotNullOrEmpty()] $WebsiteName,
[parameter(mandatory=$false)][String] $RuleName="Redirect to HTTPS"
)
Write-Verbose -Message "Creating the Url Rewrite rule ""$RuleName"" in website ""$WebsiteName"""
Remove-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -filter "system.webServer/rewrite/rules" -name "." -AtElement @{name="$RuleName"} -ErrorAction SilentlyContinue
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location "$WebsiteName" -filter "system.webServer/rewrite/rules" -name "." -value @{name="$RuleName";stopProcessing='True'}
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location "$WebsiteName" -filter "system.webServer/rewrite/rules/rule[@name='$RuleName']/match" -name "url" -value "(.*)"
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location "$WebsiteName" -filter "system.webServer/rewrite/rules/rule[@name='$RuleName']/conditions" -name "." -value @{input='{HTTPS}';pattern='off'}
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location "$WebsiteName" -filter "system.webServer/rewrite/rules/rule[@name='$RuleName']/action" -name "type" -value "Redirect"
Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location "$WebsiteName" -filter "system.webServer/rewrite/rules/rule[@name='$RuleName']/action" -name "url" -value "https://{HTTP_HOST}/{R:1}"
}
Function Add-HSTSHeaderRewriteRule()
{
<#
.SYNOPSIS
This function is used to create a URL Rewrite Rule that sets an HTTP Response Header for Strict-Transport-Security
when the protocol requested is HTTPS
RuleName is optional and will default to "Add Strict-Transport-Security header when request is HTTPS"
.SYNTAX
Add-HSTSHeaderRewriteRule -WebsiteName "www.mywebsite.com"
.EXAMPLES
Add-HSTSHeaderRewriteRule -WebsiteName "www.mywebsite.com"
Add-HSTSHeaderRewriteRule -WebsiteName "www.mywebsite.com" -RuleName "my rule name"
#>
[cmdletbinding(positionalbinding=$false)]
Param
(
[parameter(mandatory=$true)][String] [ValidateNotNullOrEmpty()] $WebsiteName,
[parameter(mandatory=$false)][String]$RuleName="Add Strict-Transport-Security header when request is HTTPS"
)
$serverVariable = "RESPONSE_Strict_Transport_Security"
Write-Verbose -Message "Creating the HSTS Header rule ""$RuleName"" in website ""$WebsiteName"""
Remove-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location "$WebsiteName" -filter "system.webServer/rewrite/allowedServerVariables" -name "." -AtElement @{name="$serverVariable"} -ErrorAction SilentlyContinue
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST' -location "$WebsiteName" -filter "system.webServer/rewrite/allowedServerVariables" -name "." -value @{name="$serverVariable"}
Remove-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -name "." -filter "system.webServer/rewrite/outboundRules" -AtElement @{name="$RuleName"} -ErrorAction SilentlyContinue
Add-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -filter "system.webServer/rewrite/outboundRules" -name "." -value @{name="$RuleName"}
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -filter "system.webServer/rewrite/outboundRules/rule[@name='$RuleName']/match" -name "serverVariable" -value $serverVariable
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -filter "system.webServer/rewrite/outboundRules/rule[@name='$RuleName']/match" -name "pattern" -value ".*"
Add-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -filter "system.webServer/rewrite/outboundRules/rule[@name='$RuleName']/conditions" -name "." -value @{input='{HTTPS}';pattern='on'}
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -filter "system.webServer/rewrite/outboundRules/rule[@name='$RuleName']/action" -name "type" -value "Rewrite"
Set-WebConfigurationProperty -pspath "MACHINE/WEBROOT/APPHOST" -location "$WebsiteName" -filter "system.webServer/rewrite/outboundRules/rule[@name='$RuleName']/action" -name "value" -value "max-age=31536000"
}
Secondo i produttori del modulo IIS di HTTP Strict Transport Security, la semplice aggiunta dell'intestazione personalizzata non è conforme alla bozza di specifica (RFC 6797).
Dovresti effettivamente installare questo modulo IIS per attivare HSTS su IIS 7.
Aggiornamento 26 ottobre 2014 : grazie al commentatore di seguito, ho letto di nuovo la pagina del modulo e in particolare la parte che giustifica l'uso del modulo rispetto all'aggiunta di intestazioni personalizzate.
Un host HSTS NON DEVE includere il campo di intestazione STS nelle risposte HTTP trasmesse su trasporto non sicuro.
Se ti assicuri di aggiungere le intestazioni solo in HTTPS e NON in HTTP, non hai bisogno di questo modulo e puoi usare la risposta di Doug Wilson. Non usare la risposta di Owen Blacker perché non ha la condizione https.
Questo può essere fatto aggiungendo il seguente blocco in Web.Config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name ="CustomName" value="MyCustomValue"/>
</customHeaders>
</httpProtocol>
</system.webServer>
Dobbiamo configurare su IIS che ha la capacità di rispondere alle intestazioni personalizzate:
Solo per aggiungere, vedo nei commenti 2 persone che parlano di 500 errori quando lo fai. Ho avuto questo
Se viene visualizzato un errore 500 in IIS, è possibile che sia stata aggiunta la regola sia al livello principale, impostato su ereditato, sia a livello di sito.
per esempio
Default Web Site <- here
Some Web Site <- here
IIS / Il browser non sembra fornire alcuna informazione in merito, indipendentemente dalle impostazioni di gestione degli errori