Włącz zabezpieczenia ścisłego transportu HTTP (HSTS) w IIS 7


75

Jak najlepiej włączyć HTTP Strict Transport Security na serwerze sieci Web IIS 7?

Czy mogę po prostu przez GUI i dodać odpowiedni nagłówek odpowiedzi HTTP, czy powinienem używać appcmd, a jeśli tak, jakie przełączniki?


1
Wiele z tego zależy od tego , jak generujesz rzeczy, które obsługuje IIS (na przykład. Możesz ustawić nagłówek na stronach PHP lub ASP.NET z poziomu aplikacji). Czy możesz nam powiedzieć więcej o swoim przypadku użycia?
— voretaq7,

Odpowiedzi:


18

IIS ma możliwość dodawania niestandardowych nagłówków do odpowiedzi . Wydaje się, że jest to najłatwiejszy sposób.

Zgodnie z dokumentacją na stronie IIS.net można dodać te nagłówki za pomocą Menedżera IIS:

  • W okienku Połączenia przejdź do witryny, aplikacji lub katalogu, dla którego chcesz ustawić niestandardowy nagłówek HTTP.
  • W okienku głównym kliknij dwukrotnie Nagłówki odpowiedzi HTTP.
  • W panelu Nagłówki odpowiedzi HTTP kliknij Dodaj ... w okienku Akcje.
  • W oknie dialogowym Dodawanie niestandardowego nagłówka odpowiedzi HTTP ustaw nazwę i wartość niestandardowego nagłówka, a następnie kliknij przycisk OK.

5
Można to również zrobić w pliku Web.config, który może być preferowany. Opublikowałem szczegóły jako nową odpowiedź, ponieważ byłyby one naprawdę trudne do odczytania bez formatowania kodu źródłowego, które nie jest dostępne w komentarzach.
— Owen Blacker

3
Według twórców modułu HTTP Strict Transport Security IIS samo dodanie niestandardowego nagłówka nie jest zgodne ze szkicową specyfikacją (RFC 6797). W rzeczywistości trzeba zainstalować ten moduł IIS.
— Chris

@Chris Oni (trochę) się mylą. Nie chodzi o specyfikację - są tam absolutnie poprawne - ale o fakt, że nie ma „prostego” sposobu na zachowanie zgodności z modułem: po prostu utwórz 2 witryny, jedną dla SSL (z nagłówkiem) i jedną dla non-SSL ( bez nagłówka). Z pewnością moduł jest nieco bardziej elegancki , ale nie jest konieczny (i nie jest w ogóle uzasadniony, jeśli twoja witryna jest tylko https i nie udostępniasz prostych odpowiedzi HTTP).
— voretaq7

1
@Chris Powinieneś jednak dodać odpowiedź odnoszącą się do tego modułu - bezpłatne poprawki! (Nie wiedziałem o jego istnieniu, a dla wielu ludzi jest to prawdopodobnie łatwiejsza / lepsza opcja niż niestandardowe nagłówki)
— voretaq7

112

Dzięki temu możemy obsłużyć zarówno przekierowanie HTTP, jak i dodać nagłówek Strict-Transport-Security do odpowiedzi HTTPS za pomocą pojedynczej witryny IIS (moduł Rewrite URL musi być zainstalowany):

<?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>

7
Dzięki, to najlepsza odpowiedź! Dodaje również nagłówek do statycznych plików HTML, w przeciwieństwie do podejścia programowego. I nie dodaje się do HTTP, co jest zgodne ze standardem.
— Jeow Li Huan,

4
@ Matematy Czy masz przepisywanie adresów URL zainstalowane w IIS?
— Doug Wilson

3
Nie, po dalszych badaniach dowiedziałem się, że tag przepisywania jest dostarczany przez rozszerzenie (d'oh). Wszystkie odpowiedzi, które mogłem znaleźć, nie wspominają o rozszerzeniu jako zależności, być może możesz rzucić jeden linijkę w odpowiedź, mówiąc, że potrzebujesz.
— Matematyki,

2
hstspreload.org chce, aby użytkownik dodał `; includeSubDomains; preload` po wartości maksymalnego wieku. opcje Pełna linia będzie: <action type="Rewrite" value="max-age=31536000 ;includeSubDomains; preload" />uzyskać przepustkę na hstspreload.org
— JP Hellemons,

2
Grupa przechwytywania R: 1 ze wzorcem (. *) Odpowiada całemu adresowi URL, protokołowi i wszystkim, a próba konkatenacji {HOST_HOST} / {R: 1} oznacza, że ​​dostałeś, https://somedomain.com/https://somedomain.com/relatedpatha wynik jest taki, że ścieżka została porzucona.
— AaronLS,

38

Aby uzupełnić odpowiedź voretaq7 , możesz to zrobić również za pomocą pliku Web.config (Uwaga: do użytku tylko w witrynach SSL, ponieważ doda nagłówek dla odpowiedzi HTTP i HTTPS, co jest niezgodne ze specyfikacją RFC 6797, zobacz wyjaśnienie poniżej) - dodaj blok w następujący sposób:

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

Oczywiście możesz mieć już system.webServerblok w pliku Web.config, więc dodaj to do tego, jeśli tak. Wolimy obsługę rzeczy w Web.config niż w GUI, ponieważ oznacza to, że zmiany konfiguracji mogą zostać zatwierdzone w naszym repozytorium Git.

Jeśli chcesz obsłużyć przekierowanie HTTP na SSL, jak wspomniał Greg Askew , możesz łatwiej to zrobić z osobną witryną w IIS. W ten sposób radzimy sobie z wymaganiem protokołu SSL w przypadku niektórych witryn klienckich. Ta witryna zawiera tylko przekierowanie HTTP i niektóre poprawki ujawniania informacji , wszystko w pliku 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>

Jest to nasze preferowane rozwiązanie z kilku powodów - możemy łatwo rejestrować przekierowany ruch osobno (ponieważ znajduje się w innym dzienniku IIS), nie wymaga więcej kodu w Global.asax.cs (nie mamy żadnego kodu tam, co jest nieco wygodniejsze dla witryny Umbraco) i, co ważne, oznacza to, że cała konfiguracja jest nadal przechowywana w naszym repozytorium GIT.

Edytowane w celu dodania: Aby było jasne, aby zachować zgodność z RFC 6797 , NIE WOLNO dodawać Strict-Transport-Securityniestandardowego nagłówka do żądań wysyłanych przez niezaszyfrowany HTTP. Aby być zgodnym z RFC6797, MUSISZ mieć dwie witryny w IIS, jak opisałem po pierwszym bloku kodu. Jak podkreśla Chris , RFC 6797 obejmuje:

Host HSTS NIE MOŻE zawierać pola nagłówka STS w odpowiedziach HTTP przesyłanych niezabezpieczonym transportem.

więc wysłanie Strict-Transport-Securitynagłówka klienta w odpowiedzi na żądanie inne niż SSL nie byłoby zgodne ze specyfikacją.


1
Aby dodać do odpowiedzi Owena Blackera, w IIS używam URLScan 3.1 i mam globalnie usunąć SERWER z odpowiedzi, ustawiając RemoveServerHeader = 1, pozostałe ustawienia muszą być zawarte w każdym pliku web.config witryny. Wolę to, aby po prostu usunąć wartość.
— KeyOfJ

URLScan jest bardzo popularnym rozwiązaniem i, sugerowałbym, lepszym niż to, które sugeruję. Ale nie zawsze jest to najwygodniejsze rozwiązanie: o)
— Owen Blacker

Należy pamiętać, że dodanie tego do witryny z włączoną HTTPS i HTTP (aby można było przekierować) spowoduje uszkodzenie strony! Otrzymasz 500 informacji bez informacji, nawet z CustomErrors Mode = „Off”, bez błędów w logach.
— Chris Moschini,

@ChrisMoschini Powinienem był wyjaśnić, że pierwsza linia Web.config powinna być przeznaczona dla witryny obsługującej wyłącznie protokół SSL.
— Owen Blacker

1
@Lenne Scott Hanselman napisał bardzo dobry opis tego, dlaczego STS nie należy do nagłówka podczas korzystania z HTTP. Przeczytaj więcej tutaj
— David Yates

8

Chciałbym skorzystać z przykładu z linku z Wikipedii, do którego się odwołałeś, i wykonać działanie w global.asax dla witryny. Umożliwia to przekierowanie żądania do adresu URL https, a następnie wstawienie nagłówka do odpowiedzi.

Wynika to z faktu, że nagłówek HSTS musi zostać zignorowany, jeśli nie znajduje się w odpowiedzi 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;
    }
}

3

To wydaje się być całkiem bezpiecznym sposobem na zrobienie tego. Dodaj ten kod do Global.asax - zdarzenie Application_BeginRequest jest uruchamiane najpierw w cyklu życia żądania Asp.net: http://msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs. 110) .aspx

Zgodnie ze specyfikacją żądania HTTP nie mogą odpowiadać nagłówkiem - więc ten kod dodaje go tylko do żądań https. Maksymalny wiek to liczba sekund i zwykle dobrym pomysłem jest umieszczenie tutaj dużej wartości (IE - 31536000 wskazuje, że witryna będzie obsługiwać SSL tylko przez następne 365 dni)

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

2

Korzystając z przykładu podanego przez Douga Wilsona, stworzyłem następujące dwie funkcje PowerShell, aby dodać reguły przepisywania adresów URL w celu przekierowania do HTTPS i dodawania nagłówków HSTS.

Zostały one przetestowane w systemach Windows 2012 i Windows 2012 R2.

Wszystko, co musisz zrobić, to podać nazwę strony internetowej. Opcjonalnie możesz nadać regułom inną nazwę, jeśli nie podoba Ci się wartość domyślna.

Jedną z rzeczy, na które należy zwrócić uwagę, jest to, że z moich testów Zmienne Serwerowe należy dodać do listy dozwolonych, zanim znajdą się w nagłówkach odpowiedzi. Funkcje zrobią to za Ciebie.

EDYCJA: Zobacz odniesienie do przepisywania adresów URL dla nagłówków HTTP tutaj: 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"

}

1

Według twórców modułu HTTP Strict Transport Security IIS samo dodanie niestandardowego nagłówka nie jest zgodne ze szkicową specyfikacją (RFC 6797).

W rzeczywistości należy zainstalować ten moduł IIS, aby włączyć HSTS w IIS 7.

Aktualizacja 26 okt 2014 : Dzięki komentatorowi ponownie przeczytałem stronę modułu, a konkretnie tę część, która uzasadnia użycie modułu zamiast dodawania niestandardowych nagłówków.

Host HSTS NIE MOŻE zawierać pola nagłówka STS w odpowiedziach HTTP przesyłanych niezabezpieczonym transportem.

Jeśli dodasz nagłówki tylko w HTTPS, a NIE w HTTP, nie potrzebujesz tego modułu i możesz użyć odpowiedzi Douga Wilsona. Nie używaj odpowiedzi Owena Blackera, ponieważ nie ma on warunku https.


1
Czy więc niektóre inne odpowiedzi, które wysyłają tylko nagłówek do żądań HTTPS, również rozwiązują ten problem? Czy twój moduł robi coś innego / dodatkowego niż inne rozwiązania?
— slolife

@slolife Zaktualizowałem swoją odpowiedź. Możesz użyć kodu z odpowiedzi Douga Wilsona. Nie potrzebujesz tego modułu. Widzę teraz, że jest to również omówione w komentarzach do przyjętej odpowiedzi. Nie wiem, czy ten moduł robi coś innego / dodatkowego niż inne rozwiązania. Ale nie dokonałem też wyczerpującej kontroli kodu źródłowego .
— Chris

Powinienem był powiedzieć, że pierwszy plik Web.config powinien zostać zaimplementowany w witrynie obsługującej wyłącznie protokół SSL. Zmodyfikuję swoją odpowiedź, aby to wyjaśnić.
— Owen Blacker

1

Można to zrobić, dodając następujący blok w Web.Config:

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

Musimy skonfigurować w IIS, który ma możliwość dostosowywania nagłówków do odpowiedzi:

  • Przejdź do Menedżera internetowych usług informacyjnych (IIS).
  • Skonfiguruj nagłówki odpowiedzi, które są dodawane do odpowiedzi z serwera.
  • Teraz dodaj niestandardową nazwę nagłówka i niestandardową wartość (niestandardowa nazwa i wartość nagłówka powinny być takie same jak w Web.Config). Możesz znaleźć na blogu

0

Żeby dodać, widzę w komentarzach 2 osoby mówiące o 500 błędach, kiedy to robisz. Miałem to

Jeśli w usługach IIS pojawi się błąd 500, może to oznaczać, że dodałeś regułę zarówno na najwyższym poziomie, ustawiono na odziedziczony, jak i na poziomie witryny.

na przykład

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

Usługi IIS / Przeglądarka nie wydają żadnych informacji o tym, co zrobiłeś, niezależnie od ustawień obsługi błędów

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.