在IIS 7 Web服务器上打开HTTP Strict Transport Security的最佳方法是什么?

我可以仅通过GUI并添加正确的HTTP响应标头,还是应该使用appcmd?开关?

评论

这在很大程度上取决于您如何生成IIS服务的内容(例如,您可以在应用程序中的PHP或ASP.NET页面中设置标头)。您能告诉我们更多有关您的用例的信息吗?

#1 楼

IIS可以向响应中添加自定义标头。这似乎是解决问题的最简单方法。

根据IIS.net上的文档,您可以通过IIS管理器添加以下标头:



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



评论


您也可以在Web.config中执行此操作。我将这些细节作为新的答案发布,因为如果没有注释中没有的源代码格式,它们真的很难阅读。

–欧文·布莱克(Owen Blacker)
13年3月20日在15:07

根据HTTP Strict Transport Security IIS模块制造商的说法,仅添加自定义标头不符合规范草案(RFC 6797)。您实际上需要安装此IIS模块。

–克里斯
2014-02-25 19:16



@克里斯他们错了。与规范无关-它们在那里绝对是正确的-但除了模块之外,没有“简单”的遵从性事实:只需创建2个站点,一个站点用于SSL(带有标头),另一个站点用于非SSL(没有标题)。当然,该模块稍微优雅一点,但不是必需的(如果您的站点仅是https且您不提供简单的HTTP响应,则完全不需要保证)。

–voretaq7
2014-2-25在19:55

@Chris您应该添加引用该模块的答案-免费投票! (我不知道它的存在,而且对于很多人来说,这可能比自定义标题更容易/更好)

–voretaq7
2014年2月25日在19:57

#2 楼


这使我们既可以处理HTTP重定向,又可以通过单个IIS站点(必须安装URL重写模块)将Strict-Transport-Security标头添加到HTTPS响应中:

 <?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>
 


评论


谢谢,这是最好的答案!与程序化方法不同,也将标头添加到静态HTML文件中。并且不添加到HTTP,因此符合标准。

–朱Li欢
2014年11月7日,11:36

@Mathemats您是否在IIS中安装了URL Rewrite?

–道格·威尔逊(Doug Wilson)
16年2月14日在1:33

不,经过更多研究,我发现重写标签由扩展名(d'oh)提供。我能找到的所有答案都没有将扩展名作为依赖项提及,也许您可​​以在答案中添加一行以表示您需要它。

–数学
16年2月14日在1:50

hstspreload.org希望用户添加`; includeSubDomains;在最大年龄值之后预载。选项。全行将是:以通过hstspreload.org

–JP Hellemons
18-2-27在13:25

具有模式(。*)的捕获组R:1匹配整个URL,协议和所有URL,尝试连接{HTTP_HOST} / {R:1}意味着您将获得https://somedomain.com/https:// somedomain.com/relatedpath,结果是路径被丢弃。

– AaronLS
18年9月11日在22:46

#3 楼


要补充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存储库。

如果您想处理HTTP到SSL重定向, Greg Askew提到,在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请求将不符合规范。

评论


要添加到Owen Blacker响应中,对于IIS,我使用URLScan 3.1,并通过设置RemoveServerHeader = 1使它从响应中全局删除SERVER,其余设置必须位于每个站点web.config文件中。我更喜欢这样做,而不是消隐价值。

– KeyOfJ
2014年1月14日20:50

URLScan是一种非常常见的解决方案,我建议比我建议的解决方案更好。但这并不总是最方便的解决方案:o)

–欧文·布莱克(Owen Blacker)
2014年1月16日13:35

重要的是要注意,将其添加到启用了HTTPS和HTTP(以便可以重定向)的网站上会使网站崩溃!即使使用CustomErrors Mode =“ Off”,您也将获得无信息的500,日志中没有错误。

–克里斯·莫斯基尼(Chris Moschini)
2014年8月17日,1:11

@ChrisMoschini我应该更清楚地知道第一行Web.config行应该用于仅SSL站点。

–欧文·布莱克(Owen Blacker)
15年3月4日在11:01

@Lenne Scott Hanselman对使用HTTP时为什么STS不属于标题的问题进行了更为详尽的描述。在这里阅读更多

–大卫·耶茨(David Yates)
19-6-28在15:27



#4 楼

我将使用您引用的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;
    }
}
 


#5 楼

这似乎是一种相当安全的方法。将此代码添加到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;
  }
}
 


#6 楼

使用道格·威尔逊(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"

}


#7 楼

根据HTTP Strict Transport Security IIS IIS模块的制造商的说法,仅添加自定义标头不符合规范草案(RFC 6797)。

您实际上需要安装此IIS模块才能打开HSTS。在IIS 7上。

2014年10月26日更新:感谢下面的注释程序,我再次阅读了模块页面,尤其是通过添加自定义标头证明使用模块合理性的部分。
<

如果您确保仅在HTTPS中添加标头,而不在HTTP中添加标头,则HSTS主机务必在非安全传输所传递的HTTP响应中不包含STS标头字段。不需要此模块,您可以使用道格·威尔逊(Doug Wilson)的答案。不要使用Owen Blacker的答案,因为它没有https条件。

评论


那么其他仅将标头发送到HTTPS请求的其他答案也可以解决此问题吗?还是您的模块做了其他解决方案没有做的其他事情?

–生活
2014年10月24日18:04

@slolife我更新了答案。您可以在Doug Wilson的答案中使用该代码。您不需要此模块。我现在看到在接受的答案的注释中也对此进行了讨论。我不知道此模块会做其他解决方案没有做的任何其他事情。但是我也没有对源代码进行详尽的检查。

–克里斯
14-10-26在20:41

我应该更加清楚,第一个Web.config应该在仅SSL的站点中实现。我将编辑我的答案以澄清这一点。

–欧文·布莱克(Owen Blacker)
15年3月4日在11:01

#8 楼

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

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


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


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



#9 楼

补充一下,我在评论中看到2个人在执行此操作时谈论500个错误。我有这个。

如果您在IIS中遇到500错误,可能是因为您同时在顶级,设置为继承和站点级别添加了规则。

eg

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


IIS /浏览器似乎不提供您执行此操作的任何信息,无论您的错误处理设置如何