Назад | Перейти на главную страницу

Включение строгой безопасности транспорта HTTP (HSTS) в IIS 7

Как лучше всего включить Строгая безопасность транспорта HTTP на веб-сервере IIS 7?

Могу ли я просто через графический интерфейс добавить правильный заголовок HTTP-ответа или мне следует использовать appcmd, и если да, то какие переключатели?

Это позволяет нам обрабатывать как перенаправление HTTP, так и добавлять заголовок Strict-Transport-Security к ответам HTTPS с одним сайтом IIS (должен быть установлен модуль URL Rewrite):

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

В дополнение voretaq7ответ, вы также можете сделать это с помощью файла Web.config (NB: будет использоваться только для сайтов SSL, поскольку он добавит заголовок для ответов HTTP и HTTPS, что противоречит спецификации RFC 6797, см. объяснение ниже) - добавьте блок следующим образом:

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

Очевидно, у вас уже может быть system.webServer block в вашем Web.config, поэтому добавьте это к этому, если так. Мы предпочитаем обрабатывать вещи в Web.config, а не в графическом интерфейсе, потому что это означает, что изменения конфигурации могут быть зафиксированы в нашем репозитории Git.

Если вы хотите обработать перенаправление HTTP-to-SSL, как Грег Аскью Как уже упоминалось, вам может быть проще сделать это с помощью отдельного веб-сайта в IIS. Вот как мы справляемся с требованием SSL для некоторых клиентских сайтов. Этот сайт содержит только перенаправление HTTP и некоторые раскрытие информации исправления, все в 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>

Это наше предпочтительное решение по нескольким причинам - мы можем легко регистрировать перенаправленный трафик отдельно (поскольку он находится в другом журнале IIS), это не требует дополнительного кода в Global.asax.cs (у нас нет кода там, что немного удобнее для сайта Umbraco) и, что важно, это означает, что вся конфигурация по-прежнему хранится в нашем репозитории GIT.

Отредактировано для добавления: Чтобы было ясно, чтобы соответствовать RFC 6797, то Strict-Transport-Security настраиваемый заголовок НЕ ДОЛЖЕН быть добавленными к запросам, сделанным по незашифрованному протоколу HTTP. Чтобы соответствовать RFC6797, у вас ДОЛЖНО быть два сайта в IIS, как я описал после первого блока кода. Так как Крис указывает, что RFC 6797 включает:

Хост HSTS НЕ ДОЛЖЕН включать поле заголовка STS в ответы HTTP, передаваемые по незащищенному транспорту.

так что отправив Strict-Transport-Security Заголовок клиента в ответ на запрос, отличный от SSL, не соответствует спецификации.

IIS имеет возможность добавлять собственные заголовки к ответам. Казалось бы, это самый простой способ сделать это.

Согласно документации на IIS.net вы можете добавить эти заголовки через диспетчер IIS:

  • На панели «Подключения» перейдите к сайту, приложению или каталогу, для которого вы хотите установить собственный HTTP-заголовок.
  • На домашней панели дважды щелкните Заголовки ответа HTTP.
  • На панели "Заголовки ответа HTTP" нажмите "Добавить ..." на панели "Действия".
  • В диалоговом окне «Добавить настраиваемый заголовок ответа HTTP» задайте имя и значение для настраиваемого заголовка, а затем нажмите «ОК».

Я бы использовал пример из ссылки на Википедию, на которую вы ссылались, и выполнил действие в global.asax для сайта. Это позволяет перенаправить запрос на URL-адрес https и затем вставьте заголовок в ответ.

Это связано с тем, что заголовок HSTS необходимо игнорировать, если его нет в ответе 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;
    }
}

Это кажется довольно надежным способом сделать это. Добавьте этот код в Global.asax - событие Application_BeginRequest запускается первым в жизненном цикле запроса Asp.net: http://msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs.110).aspx

Согласно спецификации, HTTP-запросы не должны отвечать заголовком, поэтому этот код добавляет его только для https-запросов. Максимальный возраст выражается в секундах, и обычно рекомендуется указывать здесь большое значение (IE - 31536000 означает, что сайт будет использовать SSL только в течение следующих 365 дней).

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

Используя пример, предоставленный Дугом Уилсоном, я создал следующие две функции PowerShell, чтобы добавить правила перезаписи URL-адресов для перенаправления на HTTPS и для добавления заголовков HSTS.

Они были протестированы в Windows 2012 и Windows 2012 R2.

Все, что вам нужно сделать, это указать название веб-сайта. При желании вы можете дать правилам другое имя, если вам не нравятся значения по умолчанию.

Следует отметить, что по результатам моего тестирования серверные переменные необходимо добавить в список разрешенных, прежде чем они будут в заголовках ответов. Функции делают это за вас.

РЕДАКТИРОВАТЬ: см. Ссылку на переопределение URL-адресов для заголовков HTTP здесь: 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"

}

По словам создателей модуля IIS HTTP Strict Transport Security, простое добавление настраиваемого заголовка не соответствует проекту спецификации (RFC 6797).

Вам действительно нужно установить это Модуль IIS чтобы включить HSTS в IIS 7.

Обновление 26 окт 2014 г.: Благодаря комментатору ниже я снова прочитал страницу модуля и, в частности, ту часть, которая оправдывает использование модуля вместо добавления пользовательских заголовков.

Хост HSTS НЕ ДОЛЖЕН включать поле заголовка STS в ответы HTTP, передаваемые по незащищенному транспорту.

Если вы убедитесь, что заголовки добавлены только в HTTPS, а НЕ в HTTP, вам не нужен этот модуль, и вы можете использовать ответ Дуга Уилсона. Не используйте ответ Оуэна Блэкера, потому что он не имеет условия https.

Это можно сделать, добавив следующий блок в Web.Config:

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

Мы должны настроить IIS, который имеет возможность настраивать заголовки для ответа:

  • Перейдите в Диспетчер информационных служб Интернета (IIS).
  • Настройте заголовки ответа, которые добавляются в ответ от сервера.
  • Теперь добавьте свое собственное имя заголовка и настраиваемое значение (имя и значение настраиваемого заголовка должны быть такими же, как в Web.Config). Вы можете найти на блог

Чтобы добавить, я вижу в комментариях 2 человека, которые говорят о 500 ошибках, когда вы это делаете. У меня было это.

Если вы получаете ошибку 500 в IIS, это может быть связано с тем, что вы добавили правило как на верхнем уровне, установленном как унаследованный, так и на уровне сайта.

например

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

IIS / браузер, похоже, не дает вам никакой информации о том, что вы это сделали, независимо от ваших настроек обработки ошибок