web-dev-qa-db-fra.com

Activez HTTP Strict Transport Security (HSTS) dans IIS 7

Quelle est la meilleure façon d'activer HTTP Strict Transport Security sur un IIS 7 serveur Web?

Puis-je simplement passer par l'interface graphique et ajouter l'en-tête de réponse HTTP approprié ou dois-je utiliser appcmd et si oui, quels commutateurs?

77
Bob

IIS a la possibilité d'ajouter des en-têtes personnalisés aux réponses . Cela semble être la façon la plus simple de s'y prendre.

Selon la documentation sur IIS.net vous pouvez ajouter ces en-têtes via IIS Manager:

  • Dans le volet Connexions, accédez au site, à l'application ou au répertoire pour lequel vous souhaitez définir un en-tête HTTP personnalisé.
  • Dans le volet Accueil, double-cliquez sur En-têtes de réponse HTTP.
  • Dans le volet En-têtes de réponse HTTP, cliquez sur Ajouter ... dans le volet Actions.
  • Dans la boîte de dialogue Ajouter un en-tête de réponse HTTP personnalisé, définissez le nom et la valeur de votre en-tête personnalisé, puis cliquez sur OK.
17
voretaq7

Cela nous permet de gérer à la fois la redirection HTTP et d'ajouter l'en-tête Strict-Transport-Security aux réponses HTTPS avec un seul site IIS (le module de réécriture d'URL doit être installé):

<?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>
116
Doug Wilson

Pour compléter la réponse de voretaq7 , vous pouvez également le faire en utilisant le fichier Web.config (NB: à utiliser uniquement pour les sites SSL, car il ajoutera l'en-tête des réponses HTTP et HTTPS, qui est contre la spécification RFC 6797, veuillez consulter l'explication ci-dessous) - ajoutez un bloc comme suit:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Strict-Transport-Security" value="max-age=31536000"/>
        </customHeaders>
    </httpProtocol>
</system.webServer>

De toute évidence, vous avez peut-être déjà un system.webServer bloquer dans votre Web.config, alors ajoutez ceci à cela, si c'est le cas. Nous préférons gérer les choses dans le Web.config plutôt que dans l'interface graphique, car cela signifie que les modifications de configuration peuvent être validées dans notre référentiel Git.

Si vous souhaitez gérer la redirection HTTP vers SSL, comme Greg Askew mentionné, vous trouverez peut-être plus facile de le faire avec un site Web distinct dans IIS. C'est ainsi que nous gérons l'exigence de SSL pour certains sites clients. Ce site contient uniquement une redirection HTTP et quelques correctifs information-divulgation , tous dans le 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>

C'est notre solution préférée pour plusieurs raisons - nous pouvons facilement enregistrer séparément le trafic redirigé (car il se trouve dans un autre IIS log), cela n'implique pas plus de code dans Global.asax. cs (nous n'avons pas de code là-dedans, ce qui est un peu plus pratique pour un site Umbraco) et, ce qui est important, cela signifie que toute la configuration est toujours conservée dans notre dépôt GIT.

Modifié pour ajouter: Pour être clair, afin de se conformer à RFC 6797 , le Strict-Transport-Security en-tête personnalisé NE DOIT PAS être ajouté aux demandes effectuées par HTTP non chiffré. Pour être conforme à RFC6797, vous DEVEZ avoir deux sites dans IIS, comme je l'ai décrit après le premier bloc de code. Comme le souligne Chris , la RFC 6797 comprend:

Un hôte HSTS NE DOIT PAS inclure le champ d'en-tête STS dans les réponses HTTP transmises via un transport non sécurisé.

donc envoyer le Strict-Transport-Security l'en-tête du client en réponse à une demande non SSL ne serait pas conforme à la spécification.

40
Owen Blacker

J'utiliserais l'exemple du lien Wikipédia auquel vous avez fait référence et j'exécuterais l'activité dans global.asax pour le site. Cela permet de rediriger la demande vers une URL https, et alors d'insérer l'en-tête dans la réponse.

Cela est dû au fait que l'en-tête HSTS doit être ignoré s'il ne figure pas dans une réponse 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;
    }
}
9
Greg Askew

Cela semble être un moyen assez sûr de le faire. Ajoutez ce code dans Global.asax - l'événement Application_BeginRequest se déclenche en premier dans le cycle de vie de la demande Asp.net: http://msdn.Microsoft.com/en-us/library/system.web.httpapplication.beginrequest ( v = vs.110) .aspx

Selon la spécification, les requêtes http ne doivent pas répondre avec l'en-tête - donc ce code ne l'ajoute que pour les requêtes https. L'âge maximum est en nombre de secondes, et c'est généralement une bonne idée de mettre une grande valeur ici (IE - 31536000 indique que le site exécutera SSL uniquement pendant les 365 prochains jours)

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;
  }
}
3
erbz

En utilisant l'exemple fourni par Doug Wilson, j'ai créé les deux fonctions PowerShell suivantes pour ajouter des règles de réécriture d'URL pour la redirection vers HTTPS et pour ajouter des en-têtes HSTS.

Ceux-ci ont été testés sur Windows 2012 et Windows 2012 R2.

Il vous suffit de fournir le nom du site. Vous pouvez éventuellement donner un nom différent aux règles si vous n'aimez pas les valeurs par défaut.

Une chose à noter est que d'après mes tests, les variables serveur doivent être ajoutées à la liste d'autorisation avant d'être dans les en-têtes de réponse. Les fonctions le font pour vous.

EDIT: Voir la référence sur la réécriture d'URL pour les en-têtes HTTP ici: 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"

}
2
CarlR

Selon les créateurs de HTTP Strict Transport Security IIS Module, le simple ajout de l'en-tête personnalisé n'est pas conforme au projet de spécification (RFC 6797).

Vous auriez en fait besoin d'installer ceci Module IIS pour activer HSTS sur IIS 7.

Mise à jour du 26 octobre 2014 : Merci au commentateur ci-dessous, j'ai relu la page du module et en particulier la partie qui justifie l'utilisation du module plutôt que l'ajout d'en-têtes personnalisés .

Un hôte HSTS NE DOIT PAS inclure le champ d'en-tête STS dans les réponses HTTP transmises via un transport non sécurisé.

Si vous vous assurez d'ajouter les en-têtes uniquement en HTTPS et NON en HTTP, vous n'avez pas besoin de ce module et vous pouvez utiliser la réponse de Doug Wilson. N'utilisez pas la réponse d'Owen Blacker car elle n'a pas la condition https.

1
Chris

Cela peut être fait en ajoutant le bloc suivant dans Web.Config:

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name ="CustomName" value="MyCustomValue"/>
      </customHeaders>
    </httpProtocol>
</system.webServer>

Nous devons configurer sur IIS qui a la possibilité de personnaliser les en-têtes pour répondre:

  • Accédez au Gestionnaire des services Internet (IIS).
  • Configurez les en-têtes de réponse qui sont ajoutés à la réponse du serveur.
  • Ajoutez maintenant votre nom d'en-tête personnalisé et votre valeur personnalisée (le nom et la valeur d'en-tête personnalisés doivent être identiques à ceux de Web.Config). Vous pouvez trouver sur blog
1
Vinit

Juste pour ajouter, je vois dans les commentaires 2 personnes parlant de 500 erreurs lorsque vous faites cela. J'avais ça.

Si vous obtenez une erreur 500 dans IIS, cela peut être dû au fait que vous avez ajouté la règle à la fois au niveau supérieur, défini sur hérité et au niveau du site.

par exemple.

Default Web Site <- here
  Some Web Site <- here

IIS/Le navigateur ne semble pas vous donner d'informations sur ce que vous avez fait, quels que soient vos paramètres de gestion des erreurs

0
tony