题 在IIS 7中启用HTTP严格传输安全性(HSTS)


什么是打开的最佳方式 HTTP严格传输安全性 在IIS 7 Web服务器上?

我可以通过GUI并添加正确的HTTP响应标头,还是应该使用appcmd,如果是,那么切换什么?


69
2017-08-13 21:23




很多这取决于 怎么样 您正在生成IIS正在服务的东西(例如,您可以在应用程序中的PHP或ASP.NET页面中设置标头)。你能告诉我们你的用例吗? - voretaq7


答案:


IIS有 能够为响应添加自定义标头。这似乎是最简单的方法。

根据文件 IIS.net 您可以通过IIS管理器添加这些标头:

  • 在“连接”窗格中,转到要为其设置自定义HTTP标头的站点,应用程序或目录。
  • 在“主页”窗格中,双击“HTTP响应标头”。
  • 在“HTTP响应标头”窗格中,单击“操作”窗格中的“添加...”。
  • 在“添加自定义HTTP响应标头”对话框中,设置自定义标头的名称和值,然后单击“确定”。

17
2017-08-13 21:37



也可以在Web.config中执行此操作,您可能更喜欢这样做。我已将这些细节发布为新的答案,因为如果没有评论中没有的源代码格式,它们将很难阅读。 - Owen Blacker
根据制造商的说法 HTTP严格传输安全IIS模块,只是添加自定义标头不符合草案规范(RFC 6797)。您实际上需要安装此IIS模块。 - Chris
@Chris他们(有点)错了。不是关于规范 - 它们在那里是绝对正确的 - 但是除了模块之外没有“简单”的方式来遵守:只创建2个站点,一个用于SSL(带有标头),一个用于非SSL(没有标题)。当然这个模块还多一点 优雅,但事实并非如此 必要 (如果您的站点仅为https且您不提供纯HTTP响应,则根本不保证)。 - voretaq7
@Chris你应该添加一个引用该模块的答案 - 免费upvotes! (我不知道它的存在,对于很多人来说,它可能比自定义标题更容易/更好的选择) - voretaq7


这允许我们处理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}/{R:1}"
                        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" />
                </rule>
            </outboundRules>
        </rewrite>
    </system.webServer>
</configuration>

102
2017-09-18 17:05



谢谢,这是最好的答案!与程序方法不同,标题也添加到静态HTML文件中。并且不添加到HTTP,因此符合标准。 - Jeow Li Huan
当我将它添加到web.config的<system.webServer>部分时,我的asp.net页面上出现500错误。此节点似乎没有<rewrite>子节点(msdn.microsoft.com/en-us/library/ms689429.aspx)。 - Mathemats
@Mathemats您是否在IIS中安装了URL Rewrite? - Doug Wilson
不,经过更多的研究,我发现重写标签是由扩展(d'oh)提供的。我能找到的所有答案都没有提到扩展作为依赖,也许你可以在你的答案中抛出一个单行说你需要它。 - Mathemats
hstspreload.org 希望用户添加`; includeSubDomains;在max-age值之后预加载。选项。全线将是: <action type="Rewrite" value="max-age=31536000 ;includeSubDomains; preload" /> 得到一个 通过 在hstspreload.org上 - JP Hellemons


为补充 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重定向,请执行 Greg Askew 提到,你可能会发现在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 6797Strict-Transport-Security 自定义标题 一定不 被添加到由未加密的HTTP发出的请求中。要符合RFC6797,你必须在IIS中有两个站点,正如我在第一个代码块之后所描述的那样。如 克里斯 指出,RFC 6797包括:

HSTS主机 一定不 包括通过非安全传输传送的HTTP响应中的STS头字段。

所以发送 Strict-Transport-Security 响应非SSL请求的客户标头不符合规范。


36
2018-03-20 15:06



要添加到Owen Blacker响应,对于IIS,我使用URLScan 3.1并通过设置RemoveServerHeader = 1使其全局从响应中删除SERVER,其余设置已强制要在每个站点web.config文件中。我更喜欢这个只是消除价值。 - KeyOfJ
URLScan是一个非常常见的解决方案,我建议,它比我建议的更好。但它并不总是最方便的解决方案:o) - Owen Blacker
需要注意的是,将此添加到启用了HTTPS和HTTP的网站(因此可以重定向)将会破坏网站!即使CustomErrors Mode =“Off”,您也将获得无信息500,日志中没有错误。 - Chris Moschini
@ChrisMoschini我应该更清楚的是,第一个Web.config行应该是一个只有SSL的站点。 - Owen Blacker
为什么非SSL中不允许严格传输安全性?这将是浏览器更改为https的指示器。规范中的错误,还是有特定的原因? - Lenne


我将使用您引用的Wikipedia链接中的示例,并在该站点的global.asax中执行活动。这样可以将请求重定向到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;
    }
}

8
2017-08-13 23:40





这似乎是一种非常安全的方法。在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表示该网站将在接下来的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;
  }
}

3
2018-03-20 03:20





根据HTTP严格传输安全IIS模块的制造商,只是添加自定义标头不符合草案规范(RFC 6797)。

你真的需要安装它 IIS模块 在IIS 7上打开HSTS。

更新26 okt 2014:感谢下面的评论者,我再次阅读了模块页面,特别是那些证明使用模块而非添加自定义标题的部分。

HSTS主机不得在通过非安全传输传输的HTTP响应中包含STS头字段。

如果您确保仅在HTTPS中而不是在HTTP中添加标题,则不需要此模块,您可以使用Doug Wilson的答案。不要使用Owen Blacker的答案,因为它没有https条件。


1
2018-03-03 21:14



那么,只有将标头发送到HTTPS请求的其他一些答案也解决了这个问题吗?或者您的模块是否做了与其他解决方案不同的/额外的事情? - slolife
@slolife我更新了我的答案。您可以使用Doug Wilson的答案中的代码。你不需要这个模块。我现在看到,这也在接受的答案的评论中讨论。我不知道这个模块做了什么不同/额外的其他解决方案没有。但我还没有详尽检查过 源代码 无论是。 - Chris
我应该更清楚的是,第一个Web.config应该在一个只有SSL的站点中实现。我会编辑我的答案以澄清这一点。 - Owen Blacker


使用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"

}

1
2018-02-04 16:51





这可以通过在Web.Config中添加以下块来完成:                                 

我们必须在IIS上配置能够自定义标头以响应:

  • 转到Internet信息服务(IIS)管理器。
  • 配置添加到服务器响应的响应标头。
  • 现在添加自定义标题名称和自定义值(自定义标题名称和值应与Web.Config中的相同)。 你可以找到 博客

0
2017-12-15 13:39