在IIS 7 Web服务器上打开HTTP Strict Transport Security的最佳方法是什么?
我可以仅通过GUI并添加正确的HTTP响应标头,还是应该使用appcmd?
在IIS 7 Web服务器上打开HTTP Strict Transport Security的最佳方法是什么?
我可以仅通过GUI并添加正确的HTTP响应标头,还是应该使用appcmd?
Answers:
IIS可以向响应中添加自定义标头。这似乎是最简单的方法。
根据IIS.net上的文档,您可以通过IIS管理器添加以下标头:
- 在“连接”窗格中,转到要为其设置自定义HTTP标头的站点,应用程序或目录。
- 在“主页”窗格中,双击“ HTTP响应头”。
- 在“ HTTP响应标题”窗格中,单击“操作”窗格中的“添加...”。
- 在“添加自定义HTTP响应标头”对话框中,设置自定义标头的名称和值,然后单击“确定”。
这使我们既可以处理HTTP重定向,又可以通过单个IIS站点将Strict-Transport-Security标头添加到HTTPS响应(必须安装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中而不是在GUI中处理内容,因为这意味着可以将配置更改提交到我们的Git存储库。
如Greg Askew所述,如果您想处理HTTP到SSL的重定向,则可能会发现在IIS中使用单独的网站更容易做到这一点。这就是我们处理某些客户端站点要求SSL的方式。该站点仅在Web.config中包含HTTP重定向和一些信息泄露修复程序:
<?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主机必须不包括在传送非安全传输的HTTP响应的STS头字段。
因此,发送Strict-Transport-Security
客户标头以响应非SSL请求将不符合规范。
我将使用您引用的Wikipedia链接中的示例,并在global.asax中为该网站执行活动。这样可以将请求重定向到https url,然后将标头插入响应中。
这是因为如果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中-在Asp.net请求生命周期中,首先触发Application_BeginRequest事件:http : //msdn.microsoft.com/zh-cn/library/system.web.httpapplication.beginrequest( v= vs。 110).aspx
根据规范,http请求不得以标头响应-因此此代码仅将其添加到https请求中。最大寿命以秒为单位,通常最好在此处输入较大的值(IE 31536000表示该站点仅在接下来的365天运行SSL)
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;
}
}
使用Doug Wilson提供的示例,我创建了以下两个PowerShell函数,以添加URL重写规则以重定向到HTTPS和添加HSTS标头。
这些已在Windows 2012和Windows 2012 R2上进行了测试。
您需要做的就是提供网站名称。如果您不喜欢默认值,则可以选择为规则指定其他名称。
需要注意的一件事是,根据我的测试,需要将服务器变量添加到允许列表中,然后才能放入响应头中。函数为您完成此操作。
编辑:请参阅有关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"
}
根据HTTP Strict Transport Security IIS模块的制造商的说法,仅添加自定义标头不符合规范草案(RFC 6797)。
实际上,您实际上需要安装此IIS模块才能在IIS 7上打开HSTS。
2014年10月26日更新:多亏了以下评论者,我再次阅读了模块页面,尤其是通过添加自定义标头来证明该模块合理使用的部分。
HSTS主机不得在通过非安全传输传递的HTTP响应中不包含STS头字段。
如果确保仅在HTTPS中添加标头,而不在HTTP中添加标头,则不需要此模块,可以使用Doug Wilson的答案。不要使用Owen Blacker的答案,因为它没有https条件。
这可以通过在Web.Config中添加以下代码块来完成:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name ="CustomName" value="MyCustomValue"/>
</customHeaders>
</httpProtocol>
</system.webServer>
我们必须在IIS上进行配置,该IIS能够自定义标头以进行响应: