วิธีที่ดีที่สุดในการเปิดHTTP Strict Transport Securityบนเว็บเซิร์ฟเวอร์ IIS 7 คืออะไร
ฉันสามารถผ่าน GUI และเพิ่มส่วนหัวการตอบกลับ HTTP ที่เหมาะสมหรือฉันควรใช้ appcmd และหากสวิตช์ประเภทใด
วิธีที่ดีที่สุดในการเปิดHTTP Strict Transport Securityบนเว็บเซิร์ฟเวอร์ IIS 7 คืออะไร
ฉันสามารถผ่าน GUI และเพิ่มส่วนหัวการตอบกลับ HTTP ที่เหมาะสมหรือฉันควรใช้ appcmd และหากสวิตช์ประเภทใด
คำตอบ:
IIS มีความสามารถในการเพิ่มส่วนหัวที่กำหนดเองเพื่อตอบสนอง นี่จะเป็นวิธีที่ง่ายที่สุดในการดำเนินการ
ตามเอกสารประกอบบนIIS.netคุณสามารถเพิ่มส่วนหัวเหล่านี้ผ่านตัวจัดการ IIS:
- ในบานหน้าต่างการเชื่อมต่อไปที่ไซต์แอปพลิเคชันหรือไดเรกทอรีที่คุณต้องการตั้งค่าส่วนหัว HTTP ที่กำหนดเอง
- ในบานหน้าต่างบ้านคลิกสองครั้งที่ส่วนตอบสนอง HTTP
- ในบานหน้าต่างส่วนตอบสนอง HTTP คลิกเพิ่ม ... ในบานหน้าต่างการกระทำ
- ในกล่องโต้ตอบเพิ่มส่วนหัวการตอบสนอง HTTP กำหนดเองตั้งชื่อและค่าสำหรับส่วนหัวที่กำหนดเองของคุณแล้วคลิกตกลง
สิ่งนี้ทำให้เราสามารถจัดการกับการเปลี่ยนเส้นทาง HTTP และเพิ่มส่วนหัว Strict-Transport-Security ลงในการตอบสนอง HTTPS ด้วยไซต์ IIS เดียว (ต้องติดตั้งโมดูล URL Rewrite):
<?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 ของเรา
หากคุณต้องการจัดการการเปลี่ยนเส้นทาง 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) และที่สำคัญหมายความว่าการตั้งค่าทั้งหมดยังคงอยู่ใน repo GIT ของเรา
แก้ไขเพิ่ม:ต้องมีความชัดเจนในการสั่งซื้อเพื่อให้สอดคล้องกับRFC 6797ที่Strict-Transport-Security
ส่วนหัวที่กำหนดเองจะต้องไม่ได้รับการเพิ่มการร้องขอที่ทำโดย HTTP ที่ไม่ได้เข้ารหัส เพื่อให้สอดคล้องกับ RFC6797 คุณต้องมีสองไซต์ใน IIS ดังที่ฉันได้อธิบายไว้หลังจากบล็อกรหัสแรก ดังที่Chrisชี้ให้เห็น RFC 6797 ประกอบด้วย:
โฮสต์ HSTS ต้องไม่รวมฟิลด์ส่วนหัวของ STS ในการตอบกลับ HTTP ที่ถ่ายทอดผ่านการขนส่งที่ไม่ปลอดภัย
ดังนั้นการส่งStrict-Transport-Security
ส่วนหัวของลูกค้าเพื่อตอบสนองต่อคำขอที่ไม่ใช่ SSL จะไม่เป็นไปตามข้อกำหนด
ฉันจะใช้ตัวอย่างจากลิงค์ Wikipedia ที่คุณอ้างถึงและดำเนินกิจกรรมใน global.asax สำหรับเว็บไซต์ สิ่งนี้เปิดใช้งานการเปลี่ยนเส้นทางการร้องขอไปยัง URL 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 - เหตุการณ์ Application_BeginRequest เริ่มก่อนใน Aspec รอบการร้องขอ Asp.net: http://msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs 110) .aspx
ตามข้อมูลจำเพาะคำขอ HTTP ต้องไม่ตอบกลับด้วยส่วนหัว - ดังนั้นรหัสนี้จะเพิ่มเฉพาะสำหรับคำขอ https Max-age นั้นมีหน่วยเป็นวินาทีและโดยทั่วไปแล้วควรจะใส่ค่ามาก ๆ (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;
}
}
การใช้ตัวอย่างที่จัดทำโดย Doug Wilson ฉันได้สร้างสองฟังก์ชัน PowerShell ต่อไปนี้เพื่อเพิ่มกฎการเขียน url ใหม่สำหรับการเปลี่ยนเส้นทางไปยัง HTTPS และสำหรับการเพิ่มส่วนหัว HSTS
สิ่งเหล่านี้ได้รับการทดสอบบน Windows 2012 และ Windows 2012 R2
สิ่งที่คุณต้องทำคือใส่ชื่อเว็บไซต์ คุณสามารถเลือกให้ชื่ออื่นเป็นกฎได้หากคุณไม่ชอบค่าเริ่มต้น
สิ่งหนึ่งที่ควรทราบคือจากการทดสอบของฉันตัวแปรเซิร์ฟเวอร์ต้องถูกเพิ่มลงในรายการอนุญาตก่อนที่จะอยู่ในส่วนหัวการตอบสนอง ฟังก์ชั่นทำสิ่งนี้เพื่อคุณ
แก้ไข: ดูการอ้างอิงเกี่ยวกับ Url Rewrite สำหรับส่วนหัว 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 Module เข้มงวดความปลอดภัยการขนส่ง IIS โมดูลเพียงแค่เพิ่มส่วนหัวที่กำหนดเองไม่เป็นไปตามข้อกำหนดร่าง (RFC 6797)
คุณจะต้องติดตั้งโมดูล IISนี้เพื่อเปิด HSTS บน IIS 7
อัปเดต 26 ตุลาคม 2557 : ขอบคุณผู้แสดงความคิดเห็นด้านล่างฉันอ่านหน้าโมดูลอีกครั้งและโดยเฉพาะส่วนที่แสดงให้เห็นถึงการใช้โมดูลมากกว่าการเพิ่มส่วนหัวที่กำหนดเอง
โฮสต์ HSTS ต้องไม่รวมฟิลด์ส่วนหัวของ STS ในการตอบกลับ HTTP ที่ถ่ายทอดผ่านการขนส่งที่ไม่ปลอดภัย
หากคุณแน่ใจว่าจะเพิ่มส่วนหัวใน HTTPS เท่านั้นและไม่ได้อยู่ใน HTTP คุณไม่จำเป็นต้องใช้โมดูลนี้และคุณสามารถใช้คำตอบโดย Doug Wilson อย่าใช้คำตอบของ Owen Blacker เพราะไม่มีเงื่อนไข https
สามารถทำได้โดยการเพิ่มบล็อกต่อไปนี้ใน Web.Config:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name ="CustomName" value="MyCustomValue"/>
</customHeaders>
</httpProtocol>
</system.webServer>
เราต้องกำหนดค่าบน IIS ที่มีความสามารถในการกำหนดส่วนหัวที่กำหนดเองเพื่อตอบสนอง:
เพียงเพิ่มฉันเห็นในความคิดเห็น 2 คนพูดคุยเกี่ยวกับ 500 ข้อผิดพลาดเมื่อคุณทำเช่นนี้ ฉันมีสิ่งนี้
หากคุณได้รับข้อผิดพลาด 500 ใน IIS อาจเป็นเพราะคุณได้เพิ่มกฎทั้งสองที่ระดับบนสุดให้ตั้งค่าเป็นสืบทอดและที่ระดับไซต์
เช่น
Default Web Site <- here
Some Web Site <- here
IIS / เบราว์เซอร์ดูเหมือนจะไม่ให้ข้อมูลใด ๆ ที่คุณได้ทำไป