Bob Asked: 2012-08-14 13:23:46 +0800 CST2012-08-14 13:23:46 +0800 CST 2012-08-14 13:23:46 +0800 CST 在 IIS 7 中启用 HTTP 严格传输安全 (HSTS) 772 在 IIS 7 Web 服务器上打开HTTP 严格传输安全的最佳方法是什么? 我可以只通过 GUI 并添加正确的 HTTP 响应标头,还是应该使用 appcmd,如果是的话,切换什么? iis-7 9 个回答 Voted Doug Wilson 2014-09-19T09:05:06+08:002014-09-19T09:05:06+08:00 这使我们能够处理 HTTP 重定向并将 Strict-Transport-Security 标头添加到具有单个 IIS 站点的 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> Owen Blacker 2013-03-21T07:06:32+08:002013-03-21T07:06:32+08:00 为了补充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> 显然,您的 Web.config 中可能已经有一个system.webServer块,如果是的话,将其添加到那个块中。我们更喜欢在 Web.config 而不是 GUI 中处理事情,因为这意味着配置更改可以提交到我们的 Git 存储库。 如果您想像Greg Askew提到的那样处理 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 主机不得在通过非安全传输传输的 HTTP 响应中包含 STS 标头字段。 因此发送Strict-Transport-Security客户标头以响应非 SSL 请求不符合规范。 Best Answer voretaq7 2012-08-14T13:37:12+08:002012-08-14T13:37:12+08:00 IIS能够将自定义标头添加到响应中。这似乎是最简单的方法。 根据IIS.net上的文档,您可以通过 IIS 管理器添加这些标头: 在“连接”窗格中,转到要为其设置自定义 HTTP 标头的站点、应用程序或目录。 在主页窗格中,双击 HTTP 响应标头。 在 HTTP Response Headers 窗格中,单击 Actions 窗格中的 Add...。 在“添加自定义 HTTP 响应标头”对话框中,设置自定义标头的名称和值,然后单击“确定”。 Greg Askew 2012-08-14T15:40:21+08:002012-08-14T15:40:21+08:00 我会使用您引用的维基百科链接中的示例,并在该站点的 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; } } erbz 2014-03-20T19:20:38+08:002014-03-20T19:20:38+08:00 这似乎是一种非常安全的方法。在 Global.asax 中添加此代码 - Application_BeginRequest 事件在 Asp.net 请求生命周期中首先触发:http: //msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs. 110).aspx 根据规范,http 请求不得使用标头进行响应 - 因此此代码仅为 https 请求添加它。Max-age 以秒为单位,在这里输入较大的值通常是个好主意(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; } } CarlR 2015-02-05T08:51:28+08:002015-02-05T08:51:28+08:00 使用 Doug Wilson 提供的示例,我创建了以下两个 PowerShell 函数来添加 url 重写规则以重定向到 HTTPS 和添加 HSTS 标头。 这些已在 Windows 2012 和 Windows 2012 R2 上进行了测试。 您需要做的就是提供网站名称。如果您不喜欢默认值,您可以选择为规则指定一个不同的名称。 需要注意的一件事是,根据我的测试,服务器变量需要先添加到允许列表,然后才能添加到响应标头中。这些功能会为你做这件事。 编辑:请参阅此处有关 HTTP 标头的 Url Rewrite 的参考资料: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" } Chris 2014-03-04T13:14:43+08:002014-03-04T13:14:43+08:00 根据 HTTP Strict Transport Security IIS Module 的制造商的说法,仅添加自定义标头不符合规范草案 (RFC 6797)。 您实际上需要安装此IIS 模块才能在 IIS 7 上打开 HSTS。 2014 年 10 月 26 日更新:感谢下面的评论者,我再次阅读了模块页面,特别是证明使用模块而不是添加自定义标头的部分。 HSTS 主机不得在通过非安全传输传输的 HTTP 响应中包含 STS 标头字段。 如果您确保仅在 HTTPS 而不是在 HTTP 中添加标头,则不需要此模块,您可以使用 Doug Wilson 的答案。不要使用 Owen Blacker 的答案,因为它没有 https 条件。 Vinit 2015-12-16T05:39:08+08:002015-12-16T05:39:08+08:00 这可以通过在 Web.Config 中添加以下块来完成: <system.webServer> <httpProtocol> <customHeaders> <add name ="CustomName" value="MyCustomValue"/> </customHeaders> </httpProtocol> </system.webServer> 我们必须在能够自定义标头响应的 IIS 上进行配置: 转到 Internet 信息服务 (IIS) 管理器。 配置添加到服务器响应的响应标头。 现在添加您的自定义标头名称和自定义值(自定义标头名称和值应与 Web.Config 中的相同)。你可以在博客上找到 tony 2019-06-01T06:57:36+08:002019-06-01T06:57:36+08:00 补充一下,我在评论中看到有 2 个人在谈论执行此操作时出现 500 个错误。我有这个。 如果您在 IIS 中遇到 500 错误,可能是因为您在顶层(设置为继承)和站点级别都添加了规则。 例如 Default Web Site <- here Some Web Site <- here 无论您的错误处理设置如何,IIS/浏览器似乎都不会向您提供您已执行此操作的任何信息
这使我们能够处理 HTTP 重定向并将 Strict-Transport-Security 标头添加到具有单个 IIS 站点的 HTTPS 响应(必须安装 URL 重写模块):
为了补充voretaq7的答案,您还可以使用 Web.config 文件执行此操作(注意:仅用于 SSL 站点,因为它将为 HTTP 和 HTTPS 响应添加标头,这违反了 RFC 6797 规范,请看下面的解释)——添加一个块如下:
显然,您的 Web.config 中可能已经有一个
system.webServer
块,如果是的话,将其添加到那个块中。我们更喜欢在 Web.config 而不是 GUI 中处理事情,因为这意味着配置更改可以提交到我们的 Git 存储库。如果您想像Greg Askew提到的那样处理 HTTP 到 SSL 重定向,您可能会发现在 IIS 中使用单独的网站更容易做到这一点。这就是我们处理某些客户端站点需要 SSL 的方式。该站点仅包含一个 HTTP 重定向和一些信息泄露修复程序,所有这些都在 Web.config 中:
这是我们的首选解决方案,原因有几个——我们可以轻松地单独记录重定向的流量(因为它在不同的 IIS 日志中),它不涉及 Global.asax.cs 中的更多代码(我们没有任何代码在那里,这对于 Umbraco 站点来说更方便一些)而且重要的是,这意味着所有配置仍然保存在我们的 GIT 存储库中。
编辑添加:明确地说,为了符合RFC 6797,
Strict-Transport-Security
自定义标头不得添加到由未加密的 HTTP 发出的请求中。要符合 RFC6797,您必须在 IIS 中有两个站点,正如我在第一个代码块之后所描述的那样。正如克里斯指出的那样,RFC 6797 包括:因此发送
Strict-Transport-Security
客户标头以响应非 SSL 请求不符合规范。IIS能够将自定义标头添加到响应中。这似乎是最简单的方法。
根据IIS.net上的文档,您可以通过 IIS 管理器添加这些标头:
我会使用您引用的维基百科链接中的示例,并在该站点的 global.asax 中执行活动。这允许将请求重定向到 https url,然后将标头插入到响应中。
这是因为如果 HSTS 标头不在 https 响应中,则必须忽略它。
这似乎是一种非常安全的方法。在 Global.asax 中添加此代码 - Application_BeginRequest 事件在 Asp.net 请求生命周期中首先触发:http: //msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs. 110).aspx
根据规范,http 请求不得使用标头进行响应 - 因此此代码仅为 https 请求添加它。Max-age 以秒为单位,在这里输入较大的值通常是个好主意(IE - 31536000 表示站点将仅在接下来的 365 天内运行 SSL)
使用 Doug Wilson 提供的示例,我创建了以下两个 PowerShell 函数来添加 url 重写规则以重定向到 HTTPS 和添加 HSTS 标头。
这些已在 Windows 2012 和 Windows 2012 R2 上进行了测试。
您需要做的就是提供网站名称。如果您不喜欢默认值,您可以选择为规则指定一个不同的名称。
需要注意的一件事是,根据我的测试,服务器变量需要先添加到允许列表,然后才能添加到响应标头中。这些功能会为你做这件事。
编辑:请参阅此处有关 HTTP 标头的 Url Rewrite 的参考资料:http ://www.iis.net/learn/extensions/url-rewrite-module/setting-http-request-headers-and-iis-server-variables
根据 HTTP Strict Transport Security IIS Module 的制造商的说法,仅添加自定义标头不符合规范草案 (RFC 6797)。
您实际上需要安装此IIS 模块才能在 IIS 7 上打开 HSTS。
2014 年 10 月 26 日更新:感谢下面的评论者,我再次阅读了模块页面,特别是证明使用模块而不是添加自定义标头的部分。
HSTS 主机不得在通过非安全传输传输的 HTTP 响应中包含 STS 标头字段。
如果您确保仅在 HTTPS 而不是在 HTTP 中添加标头,则不需要此模块,您可以使用 Doug Wilson 的答案。不要使用 Owen Blacker 的答案,因为它没有 https 条件。
这可以通过在 Web.Config 中添加以下块来完成:
我们必须在能够自定义标头响应的 IIS 上进行配置:
补充一下,我在评论中看到有 2 个人在谈论执行此操作时出现 500 个错误。我有这个。
如果您在 IIS 中遇到 500 错误,可能是因为您在顶层(设置为继承)和站点级别都添加了规则。
例如
无论您的错误处理设置如何,IIS/浏览器似乎都不会向您提供您已执行此操作的任何信息