Увімкніть сувору безпеку транспорту HTTP (HSTS) у IIS 7


75

Який найкращий спосіб увімкнути жорстку безпеку транспорту HTTP на веб-сервері IIS 7?

Чи можу я просто через графічний інтерфейс і додати належний заголовок відповіді HTTP або я повинен використовувати appcmd і якщо так, то що перемикається?


1
Багато цього залежить від того, як ви генеруєте матеріал, який IIS обслуговує (наприклад, ви можете встановити заголовок на сторінках PHP або ASP.NET з вашої програми). Чи можете ви розповісти більше про ваш випадок використання?
voretaq7

Відповіді:


18

IIS має можливість додавати власні заголовки до відповідей . Це, мабуть, буде найпростішим шляхом для цього.

Згідно з документацією по IIS.net ви можете додати ці заголовки через Диспетчер IIS:

  • На панелі «Підключення» перейдіть на сайт, додаток або каталог, для якого потрібно встановити спеціальний заголовк HTTP.
  • На панелі "Домашня сторінка" двічі клацніть заголовки відповідей HTTP.
  • На панелі заголовків відповідей HTTP натисніть кнопку Додати ... на панелі "Дії".
  • У діалоговому вікні Додати спеціальний заголовок відповіді HTTP встановіть ім’я та значення для власного заголовка та натисніть кнопку ОК.

5
Це також можна зробити в Web.config, який, можливо, ви віддасте перевагу. Я опублікував деталі як нову відповідь, оскільки їх було б дуже важко прочитати без форматування вихідного коду, який недоступний у коментарях.
Оуен Блекер

3
На думку виробників модуля IIS Strict Transport Security IIS , просто додавання користувацького заголовка не відповідає проекту специфікації (RFC 6797). Вам фактично потрібно було б встановити цей модуль IIS.
Кріс,

@Chris Вони помилувалися. Не про специфікації - вони там абсолютно правильні - а про те, що немає "простого" способу дотримуватися сторону від їх модуля: Просто створіть 2 сайти, один для SSL (із заголовком) та один для не-SSL ( без заголовка). Безумовно, модуль трохи елегантніший , але це не обов'язково (і зовсім не гарантовано, якщо ваш сайт є лише https, і ви не обслуговуєте звичайні відповіді HTTP).
voretaq7

1
@Chris Вам слід додати відповідь, що посилається на цей модуль - безкоштовні нагороди! (Я не знав про його існування, і для багатьох людей це, мабуть, простіший / кращий варіант, ніж спеціальні речі заголовка)
voretaq7

112

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

<?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
Дякую, це найкраща відповідь! Також додає заголовок до статичних файлів HTML, на відміну від програмного підходу. І не додає до HTTP, таким чином, відповідає стандарту.
Джоу Лі Хуан

4
@Mathemats У вас встановлено перезапис URL-адрес у IIS?
Дуг Вілсон

3
Ні, після додаткових досліджень я з'ясував, що тег перезапису надається розширенням (d'oh). Усі відповіді, які я міг знайти, не згадують про розширення як про залежність, можливо, ви можете кинути один лайнер у своїй відповіді, сказавши, що вам це потрібно.
Математики

2
hstspreload.org хоче, щоб користувач додав `; includeSubDomains; preload` після значення максимального віку. варіанти. Повна лінія буде: <action type="Rewrite" value="max-age=31536000 ;includeSubDomains; preload" />отримати пропуск на hstspreload.org
JP Hellemons

2
Група захоплення R: 1 з малюнком (. *) Відповідає всій URL-адресі, протоколу та всім, а спроба об'єднати {HTTP_HOST} / {R: 1} означає, що ви отримуєте, https://somedomain.com/https://somedomain.com/relatedpathа результат - шлях випадає.
AaronLS

38

Щоб доповнити відповідь voretaq7 , ви можете також зробити це за допомогою файлу Web.config (Примітка. Для використання лише для SSL-сайтів, оскільки він додасть заголовок для HTTP та HTTPS-відповідей, що суперечить специфікації RFC 6797, будь ласка, дивіться пояснення нижче) - додайте блок наступним чином:

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

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

Якщо ви хочете обробляти перенаправлення HTTP на 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-запит не буде відповідати специфікації.


1
Щоб додати відповідь Owen Blacker, для IIS я використовую URLScan 3.1 та його глобально видалити СЕРВЕР з відповіді, встановивши RemoveServerHeader = 1, решта налаштувань зобов'язані бути у кожному веб-файлі web.config. Я вважаю за краще це просто викреслювати значення.
KeyOfJ

URLScan - це дуже поширене рішення і, я б сказав, краще, ніж те, що я пропоную. Але це не завжди найзручніше рішення: o)
Оуен Блекер

Важливо зауважити, що додавання цього на сайт із увімкненими HTTPS та HTTP (щоб він міг переспрямовуватись) БЕЗПЕЧИТИ сайт! Ви отримаєте 500 інформацій навіть у режимі CustomErrors = "Вимкнено", без помилок у журналах.
Кріс Москіні

@ChrisMoschini Мені повинно було бути зрозуміліше, що перший рядок Web.config повинен бути призначений лише для SSL-сайту.
Оуен Блекер

1
@Lenne Скотт Хензельман написав більш вдалий опис того, чому STS не належить до заголовка під час використання HTTP. Детальніше читайте тут
Девід Йейтс

8

Я б використав приклад із посилання на Wikipedia, на яке ви посилаєтесь, і виконує діяльність на сайті 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;
    }
}

3

Це, здається, досить невдалий безпечний спосіб зробити це. Додайте цей код у 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;
  }
}

2

Використовуючи приклад Дуга Вілсона, я створив дві наступні функції PowerShell, щоб додати правила перезапису URL для перенаправлення до HTTPS та для додавання заголовків HSTS.

Вони перевірені на Windows 2012 та Windows 2012 R2.

Все, що вам потрібно зробити - це вказати ім’я веб-сайту. Ви можете необов’язково дати правилам інше ім'я, якщо ти не подобається за замовчуванням.

Слід зазначити, що після мого тестування, змінні сервери потрібно додати до списку дозволів, перш ніж потрапити в заголовки відповідей. Функції роблять це за вас.

EDIT: Див. Посилання на перезапис 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"

}

1

На думку виробників модуля IIS Strict Transport Security IIS, просто додавання користувацького заголовка не відповідає проекту специфікації (RFC 6797).

Вам потрібно було б встановити цей модуль IIS, щоб увімкнути HSTS на IIS 7.

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

Хост HSTS НЕ повинен включати поле заголовка STS у відповіді HTTP, що передаються через незахищений транспорт.

Якщо ви обов'язково додаєте заголовки лише в HTTPS, а НЕ в HTTP, цей модуль вам не потрібен, і ви можете використовувати відповідь Дугом Вілсоном. Не використовуйте відповідь Оуена Блекдера, тому що в ньому немає умови https.


1
Тож чи вирішують цю проблему деякі інші відповіді, які лише надсилають заголовок на запити HTTPS? Або ваш модуль робить щось інше / додаткове, ніж інші рішення?
slolife

@slolife Я оновив свою відповідь. Ви можете використовувати код у відповіді Дуга Вілсона. Вам не потрібен цей модуль. Зараз я бачу, що це також обговорюється в коментарях до прийнятої відповіді. Мені не відомо, що цей модуль робить щось інше / додаткове, ніж інші рішення. Але я також не зробив вичерпної перевірки вихідного коду .
Кріс

Мені повинно було бути зрозуміліше, що перший Web.config повинен бути реалізований на веб-сайті, що відповідає лише SSL. Я відредагую свою відповідь, щоб уточнити це.
Оуен Блекер

1

Це можна зробити, додавши наступний блок у Web.Config:

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

Ми повинні налаштувати на IIS, який має можливість користувацьких заголовків відповідати:

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

0

Просто додам, я бачу в коментарях 2 людини, які говорять про 500 помилок, коли ви це робите. У мене це було.

Якщо ви отримаєте помилку 500 в IIS, це може бути тому, що ви додали правило як на верхньому рівні, встановленому у спадок, так і на рівні сайту.

напр

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

IIS / Браузер, здається, не дає вам ніякої інформації, що ви зробили це, незалежно від налаштувань обробки помилок

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.