Aktivieren Sie die strenge HTTP-Transportsicherheit (HSTS) in IIS 7

75

Was ist die beste Methode, um HTTP Strict Transport Security auf einem IIS 7-Webserver zu aktivieren?

Kann ich einfach über die GUI den richtigen HTTP-Antwortheader hinzufügen oder sollte ich appcmd verwenden und wenn ja, welche Schalter?

Bob
quelle
1
Vieles davon hängt davon ab, wie Sie die Inhalte generieren, die IIS bereitstellt (z. B. können Sie den Header in PHP- oder ASP.NET-Seiten in Ihrer Anwendung festlegen). Können Sie uns mehr über Ihren Anwendungsfall erzählen?
Voretaq7

Antworten:

18

IIS kann Antworten benutzerdefinierte Header hinzufügen . Dies scheint der einfachste Weg zu sein, dies zu tun.

Gemäß der Dokumentation auf IIS.net können Sie diese Header über den IIS-Manager hinzufügen:

  • Wechseln Sie im Bereich Verbindungen zu der Site, der Anwendung oder dem Verzeichnis, für die bzw. das Sie einen benutzerdefinierten HTTP-Header festlegen möchten.
  • Doppelklicken Sie im Bereich Startseite auf HTTP-Antwortheader.
  • Klicken Sie im Bereich HTTP-Antwortheader im Bereich Aktionen auf Hinzufügen ....
  • Legen Sie im Dialogfeld Benutzerdefinierten HTTP-Antwortheader hinzufügen den Namen und den Wert für Ihren benutzerdefinierten Header fest, und klicken Sie dann auf OK.
voretaq7
quelle
5
Es ist auch möglich, dies in der Web.config zu tun, was Sie vielleicht bevorzugen. Ich habe die Details als neue Antwort veröffentlicht, da sie ohne die Quellcode-Formatierung, die in Kommentaren nicht verfügbar ist, nur schwer zu lesen wären.
Owen Blacker
3
Laut den Herstellern des IIS-Moduls für strenge HTTP-Transportsicherheit entspricht das Hinzufügen des benutzerdefinierten Headers nicht dem Spezifikationsentwurf (RFC 6797). Sie müssten dieses IIS-Modul tatsächlich installieren.
Chris
@ Chris Sie sind (irgendwie) falsch. Nicht um die Spezifikation - sie sind dort absolut korrekt - sondern um die Tatsache, dass es keinen "einfachen" Weg gibt, außer ihrem Modul zu entsprechen: Erstellen Sie einfach zwei Sites, eine für SSL (mit dem Header) und eine für Nicht-SSL ( ohne den Header). Sicher ist das Modul etwas eleganter , aber es ist nicht notwendig (und überhaupt nicht garantiert, wenn Ihre Site nur https-fähig ist und Sie keine einfachen HTTP-Antworten liefern).
Voretaq7
1
@ Chris Sie sollten eine Antwort hinzufügen, die auf dieses Modul verweist - kostenlose Upvotes! (Ich wusste nicht, dass es existiert, und für viele Leute ist es wahrscheinlich eine einfachere / bessere Option als das benutzerdefinierte Header-Zeug)
voretaq7
112

Auf diese Weise können wir sowohl die HTTP-Umleitung als auch den Strict-Transport-Security-Header zu HTTPS-Antworten mit einer einzigen IIS-Site hinzufügen (das URL-Rewrite-Modul muss installiert sein):

<?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
quelle
7
Danke, das ist die beste Antwort! Fügt den Header im Gegensatz zum programmatischen Ansatz auch statischen HTML-Dateien hinzu. Und fügt nicht zu HTTP hinzu und entspricht damit dem Standard.
Jeow Li Huan
4
@Mathemats Haben Sie URL Rewrite in IIS installiert?
Doug Wilson
3
Nein, nach weiteren Recherchen habe ich herausgefunden, dass das Rewrite-Tag von der Extension (d'oh) bereitgestellt wird. In allen Antworten, die ich finden konnte, wird die Erweiterung nicht als Abhängigkeit erwähnt. Vielleicht können Sie einen Einzeiler in Ihre Antwort einfügen, der besagt, dass Sie sie benötigen.
Mathemats
2
hstspreload.org möchte, dass der Benutzer `; includeSubDomains; Vorspannung nach dem Höchstalter. Optionen. Volle Linie wird sein: <action type="Rewrite" value="max-age=31536000 ;includeSubDomains; preload" />um einen Pass auf hstspreload.org zu bekommen
JP Hellemons
2
Die Erfassungsgruppe R: 1 mit dem Muster (. *) Stimmt mit der gesamten URL, dem Protokoll und allem überein. Wenn Sie versuchen, {HTTP_HOST} / {R: 1} zu verketten, https://somedomain.com/https://somedomain.com/relatedpathwird der Pfad gelöscht.
AaronLS
38

Um die Antwort von voretaq7 zu ergänzen , können Sie auch die Datei Web.config verwenden (Hinweis: Nur für SSL-Sites, da der Header für HTTP- und HTTPS-Antworten hinzugefügt wird, was der RFC 6797-Spezifikation entspricht. Bitte beachten Sie die Erklärung unten) - fügen Sie einen Block wie folgt hinzu:

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

Offensichtlich haben Sie möglicherweise bereits einen system.webServerBlock in Ihrer Web.config, fügen Sie diesen also hinzu, falls dies der Fall ist. Wir ziehen es vor, die Dinge in der Web.config zu behandeln, anstatt in der GUI, da dies bedeutet, dass die Konfigurationsänderungen in unser Git-Repository übernommen werden können.

Wenn Sie die HTTP-zu-SSL-Umleitung wie von Greg Askew erwähnt durchführen möchten , ist dies möglicherweise einfacher, wenn Sie eine separate Website in IIS verwenden. So gehen wir mit der Anforderung von SSL für einige Client-Sites um. Diese Site enthält nur eine HTTP-Umleitung und einige Korrekturen zur Offenlegung von Informationen in der Datei "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>

Dies ist aus mehreren Gründen unsere bevorzugte Lösung. Wir können umgeleiteten Datenverkehr problemlos separat protokollieren (da er sich in einem anderen IIS-Protokoll befindet). In Global.asax.cs ist kein weiterer Code enthalten (wir haben keinen Code) drin, was für eine Umbraco-Site etwas praktischer ist) und vor allem bedeutet dies, dass sich die gesamte Konfiguration noch in unserem GIT-Repo befindet.

Bearbeitet, um hinzuzufügen: Um RFC 6797 zu erfüllen , darf der Strict-Transport-Securitybenutzerdefinierte Header NICHT zu Anforderungen hinzugefügt werden, die über unverschlüsseltes HTTP erfolgen. Um RFC6797-kompatibel zu sein, MÜSSEN Sie zwei Standorte in IIS haben, wie ich nach dem ersten Codeblock beschrieben habe. Wie Chris betont, enthält RFC 6797:

Ein HSTS-Host DARF das STS-Headerfeld NICHT in HTTP-Antworten enthalten, die über einen nicht sicheren Transport übertragen werden.

Daher würde das Senden des Strict-Transport-SecurityKunden-Headers als Antwort auf eine Nicht-SSL-Anforderung nicht der Spezifikation entsprechen.

Owen Blacker
quelle
1
Um Owen Blacker Antwort hinzuzufügen, verwende ich für IIS URLScan 3.1 und lasse es den SERVER global aus der Antwort entfernen, indem RemoveServerHeader = 1 gesetzt wird. Die restlichen Einstellungen müssen in jeder web.config-Datei der Site vorhanden sein. Ich ziehe es vor, den Wert einfach auszublenden.
KeyOfJ
URLScan ist eine sehr verbreitete und meiner Meinung nach bessere Lösung als die, die ich vorschlage. Aber es ist nicht immer die bequemste Lösung: o)
Owen Blacker
Es ist wichtig zu beachten, dass das Hinzufügen zu einer Site mit aktiviertem HTTPS und HTTP (so dass eine Umleitung möglich ist) die Site UNTERBRECHEN wird! Sie erhalten eine informationslose 500, auch wenn CustomErrors Mode = "Off", ohne Fehler in den Protokollen.
Chris Moschini
@ChrisMoschini Mir hätte klarer sein müssen, dass die erste Web.config-Zeile nur für eine SSL-Site bestimmt ist.
Owen Blacker
1
@Lenne Scott Hanselman hat genauer beschrieben, warum STS bei Verwendung von HTTP nicht in den Header gehört. Lesen Sie hier
David Yates
8

Ich würde das Beispiel aus dem Wikipedia-Link verwenden, auf den Sie verwiesen haben, und die Aktivität in global.asax für die Site ausführen. Dies ermöglicht es, die Anforderung zu einer HTTPS - URL umgeleitet, und dann den Header in die Antwort einzufügen.

Dies liegt daran, dass der HSTS-Header ignoriert werden muss, wenn er nicht in einer https-Antwort enthalten ist.

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
quelle
3

Dies scheint eine ziemlich ausfallsichere Methode zu sein. Fügen Sie diesen Code in Global.asax hinzu - das Application_BeginRequest-Ereignis wird zuerst im Asp.net-Anforderungslebenszyklus ausgelöst: http://msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs. 110) .aspx

Laut Spezifikation dürfen http-Anforderungen nicht mit dem Header antworten, sodass dieser Code ihn nur für https-Anforderungen hinzufügt. Das Höchstalter ist in Sekunden angegeben, und es ist normalerweise eine gute Idee, hier einen großen Wert anzugeben (IE - 31536000 gibt an, dass auf der Site SSL nur für die nächsten 365 Tage ausgeführt wird).

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
quelle
2

Anhand des von Doug Wilson bereitgestellten Beispiels habe ich die folgenden beiden PowerShell-Funktionen erstellt, um Regeln zum Umleiten von URLs zu HTTPS und zum Hinzufügen von HSTS-Headern hinzuzufügen.

Diese wurden unter Windows 2012 und Windows 2012 R2 getestet.

Sie müssen lediglich den Namen der Website angeben. Sie können den Regeln optional einen anderen Namen geben, wenn Sie die Standardeinstellungen nicht mögen.

Beachten Sie, dass die Servervariablen aus meinen Tests zur Zulassungsliste hinzugefügt werden müssen, bevor sie in den Antwortköpfen angezeigt werden. Die Funktionen erledigen das für Sie.

BEARBEITEN: Siehe Verweis auf Url Rewrite für HTTP-Header hier: 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
quelle
1

Laut den Herstellern des IIS-Moduls für strenge HTTP-Transportsicherheit entspricht das Hinzufügen des benutzerdefinierten Headers nicht dem Entwurf der Spezifikation (RFC 6797).

Sie müssten dieses IIS-Modul tatsächlich installieren , um HSTS auf IIS 7 zu aktivieren.

Update 26. Oktober 2014 : Dank des Kommentars unten habe ich die Modulseite noch einmal gelesen und speziell den Teil, der die Verwendung des Moduls durch das Hinzufügen von benutzerdefinierten Headern rechtfertigt.

Ein HSTS-Host DARF das STS-Header-Feld NICHT in HTTP-Antworten enthalten, die über einen nicht sicheren Transport übertragen werden.

Wenn Sie sicherstellen, dass die Header nur in HTTPS und NICHT in HTTP hinzugefügt werden, benötigen Sie dieses Modul nicht und können die Antwort von Doug Wilson verwenden. Verwenden Sie die Antwort von Owen Blacker nicht, da die https-Bedingung nicht erfüllt ist.

Chris
quelle
1
Lösen einige der anderen Antworten, die nur den Header an HTTPS-Anforderungen senden, auch dieses Problem? Oder macht Ihr Modul etwas anderes / zusätzliches als die anderen Lösungen?
Slolife
@slolife Ich habe meine Antwort aktualisiert. Sie können den Code in der Antwort von Doug Wilson verwenden. Sie brauchen dieses Modul nicht. Ich sehe jetzt, dass dies auch in den Kommentaren der akzeptierten Antwort diskutiert wird. Mir ist nicht bewusst, dass dieses Modul etwas anderes macht als die anderen Lösungen. Aber ich habe den Quellcode auch nicht vollständig überprüft .
Chris
Ich hätte klarer sein sollen, dass die erste Web.config auf einer Nur-SSL-Site implementiert werden sollte. Ich werde meine Antwort bearbeiten, um das zu klären.
Owen Blacker
1

Dies kann durch Hinzufügen des folgenden Blocks in Web.Config erfolgen:

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

Wir müssen auf IIS konfigurieren, das die Möglichkeit hat, benutzerdefinierte Header für die Antwort festzulegen:

  • Wechseln Sie zu Internetinformationsdienste-Manager.
  • Konfigurieren Sie Antwortheader, die zur Antwort vom Server hinzugefügt werden.
  • Fügen Sie nun Ihren benutzerdefinierten Headernamen und Wert hinzu (Name und Wert des benutzerdefinierten Headers sollten mit denen in Web.Config identisch sein). Sie können auf Blog finden
Vinit
quelle
0

Um es hinzuzufügen, ich sehe in den Kommentaren 2 Leute, die über 500 Fehler sprechen, wenn Sie dies tun. Ich hatte das

Wenn in IIS ein Fehler von 500 angezeigt wird, liegt dies möglicherweise daran, dass Sie die Regel sowohl auf der obersten Ebene als auch auf der Websiteebene als geerbt festgelegt haben.

z.B

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

IIS / Der Browser scheint Ihnen keine Informationen darüber zu geben, dass Sie dies getan haben, unabhängig von Ihren Einstellungen für die Fehlerbehandlung

Tony
quelle