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?

Kok
źródło
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.
voretaq7
źródło
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>
Doug Wilson
źródło
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ą.

Owen Blacker
źródło
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;
    }
}
Greg Askew
źródło
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;
  }
}
erbz
źródło
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"

}
CarlR
źródło
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.

Chris
źródło
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
Vinit
źródło
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

Tony
źródło