Каков наилучший способ включить HTTP Strict Transport Security на веб-сервере IIS 7?
Могу ли я просто через графический интерфейс и добавить правильный заголовок ответа HTTP или я должен использовать appcmd, и если да, то что переключается?
Каков наилучший способ включить HTTP Strict Transport Security на веб-сервере IIS 7?
Могу ли я просто через графический интерфейс и добавить правильный заголовок ответа HTTP или я должен использовать appcmd, и если да, то что переключается?
Ответы:
IIS имеет возможность добавлять пользовательские заголовки к ответам . Казалось бы, это самый простой способ сделать это.
Согласно документации на IIS.net вы можете добавить эти заголовки через IIS Manager:
- На панели «Подключения» перейдите на сайт, приложение или каталог, для которого вы хотите установить настраиваемый заголовок HTTP.
- На главной странице дважды щелкните заголовки ответа HTTP.
- На панели заголовков ответа HTTP нажмите кнопку Добавить ... на панели действий.
- В диалоговом окне «Добавление настраиваемого заголовка ответа HTTP» задайте имя и значение для настраиваемого заголовка и нажмите кнопку «ОК».
Это позволяет нам обрабатывать как перенаправление 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>
<action type="Rewrite" value="max-age=31536000 ;includeSubDomains; preload" />
чтобы получить пропуск на hstspreload.org
https://somedomain.com/https://somedomain.com/relatedpath
и в результате путь отбрасывается.
Чтобы дополнить ответ 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, а не в графическом интерфейсе, потому что это означает, что изменения конфигурации могут быть зафиксированы в нашем 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 не будет соответствовать спецификации.
Я бы использовал пример из ссылки на Википедию, на которую вы ссылались, и выполнил действие в 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, который может настраивать заголовки для ответа:
Просто чтобы добавить, я вижу в комментариях 2 человека, говорящих о 500 ошибках, когда вы делаете это. У меня было это.
Если в IIS появляется ошибка 500, это может быть связано с тем, что вы добавили правило как на верхнем уровне, для наследуемого, так и на уровне сайта.
например
Default Web Site <- here
Some Web Site <- here
IIS / Браузер, кажется, не дает вам никакой информации, что вы сделали это, независимо от ваших настроек обработки ошибок