웹 사이트 <hsts에 대한 HSTS 설정>
개요
<hsts>
요소의 <site>
요소에는 IIS 10.0 버전 1709 이상에서 사이트에 대한 HSTS(HTTP Strict Transport Security) 설정을 구성할 수 있는 특성이 포함되어 있습니다.
참고
<hsts>
요소가 특정 사이트에 대한 섹션과 <site>
섹션 모두에서 <siteDefaults>
구성된 경우 섹션의 <site>
구성이 해당 사이트에 사용됩니다.
호환성
버전 | 참고 |
---|---|
IIS 10.0 버전 1709 | <hsts> 요소의 <site> 요소는 IIS 10.0 버전 1709에서 도입되었습니다. |
IIS 10.0 | 해당 없음 |
IIS 8.5 | 해당 없음 |
IIS 8.0 | 해당 없음 |
IIS 7.5 | 해당 없음 |
IIS 7.0 | 해당 없음 |
IIS 6.0 | 해당 없음 |
설치 프로그램
<hsts>
요소의 <site>
요소는 IIS 10.0 버전 1709 이상의 기본 설치에 포함됩니다.
방법
IIS 10.0 버전 1709에 <site>
대한 요소의 요소를 구성할 <hsts>
수 있는 사용자 인터페이스가 없습니다. 요소의 <site>
요소를 프로그래밍 방식으로 구성하는 <hsts>
방법에 대한 예제는 이 문서의 샘플 코드 섹션을 참조하세요.
구성
특성
attribute | Description |
---|---|
enabled |
선택적 부울 특성입니다. 사이트에 대해 HSTS를 사용할지(true) 또는 사용 안 함(false)인지 지정합니다. HSTS를 사용하도록 설정하면 IIS가 웹 사이트에 HTTPS 요청을 회신할 때 Strict-Transport-Security HTTP 응답 헤더가 추가됩니다. 기본값은 false 입니다. |
max-age |
선택적 uint 특성입니다. Strict-Transport-Security HTTP 응답 헤더 필드 값에 max-age 지시문을 지정합니다. 기본값은 0 입니다. |
includeSubDomains |
선택적 부울 특성입니다. includeSubDomains 지시문이 Strict-Transport-Security HTTP 응답 헤더 필드 값에 포함되는지 여부를 지정합니다. 참고: 모든 하위 도메인이 실제로 TLS/SSL을 통해 HTTP 기반 서비스를 제공하는 경우에만 이 특성을 사용하도록 설정합니다. 기본값은 false 입니다. |
preload |
선택적 부울 특성입니다. Preload 지시문이 Strict-Transport-Security HTTP 응답 헤더 필드 값에 포함되는지 여부를 지정합니다. 참고: 사이트의 도메인이 HSTS 사전 로드 목록에 포함되도록 제출된 경우에만 이 특성을 사용하도록 설정합니다. 기본값은 false 입니다. |
redirectHttpToHttps |
선택적 부울 특성입니다. 사이트에 대해 HTTP-HTTPS 리디렉션을 사용할지(true) 또는 사용 안 함(false)인지 지정합니다. 참고:redirectHttpToHttps 를 사용하도록 설정하면 사이트 수준 HTTP에서 HTTPS로 리디렉션이 적용됩니다. IIS는 HTTP 요청을 리디렉션할 때 URI 체계를 "https"로 바꾸고 포트 구성 요소를 무시합니다. 리디렉션 대상이 표준 포트 443에서 TLS/SSL을 통해 HTTP 기반 서비스를 제공하는지 확인합니다. 기본값은 false 입니다. |
자식 요소
없음
구성 샘플
다음 구성 샘플에서는 HTTP 및 HTTPS 바인딩 모두에서 HSTS를 사용하도록 설정된 Contoso라는 웹 사이트를 보여 줍니다. max-age 특성은 31536000초(1년)로 설정되므로 사용자 에이전트는 Strict-Transport-Security 헤더 필드가 수신된 후 1년 이내에 호스트를 알려진 HSTS 호스트로 간주합니다. includeSubDomains 특성은 HSTS 정책이 이 HSTS 호스트(contoso.com)와 하위 도메인(예www.contoso.com
: 또는 marketing.contoso.com
)에 적용되도록 지정하기 위해 true로 설정됩니다. 마지막으로, 사이트에 대한 모든 HTTP 요청이 HTTPS로 리디렉션되도록 redirectHttpToHttps 특성이 true 로 설정됩니다.
<site name="Contoso" id="1">
<application path="/" applicationPool="Contoso">
<virtualDirectory path="/" physicalPath="C:\Contoso\Content" />
</application>
<bindings>
<binding protocol="http" bindingInformation="*:80:contoso.com" />
<binding protocol="https" bindingInformation="*:443:contoso.com" sslFlags="0" />
</bindings>
<hsts enabled="true" max-age="31536000" includeSubDomains="true" redirectHttpToHttps="true" />
</site>
샘플 코드
다음 코드 샘플은 HTTP 및 HTTPS 바인딩을 모두 사용하여 Contoso라는 웹 사이트에 대해 HSTS를 사용하도록 설정합니다. 이 샘플에서는 max-age 특성을 31536000초(1년)로 설정하고 includeSubDomains 및 redirectHttpToHttps 특성을 모두 사용하도록 설정합니다.
AppCmd.exe
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.enabled:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.max-age:31536000" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.includeSubDomains:True" /commit:apphost
appcmd.exe set config -section:system.applicationHost/sites "/[name='Contoso'].hsts.redirectHttpToHttps:True" /commit:apphost
참고
AppCmd.exe 사용하여 이러한 설정을 구성할 때 commit 매개 변수 apphost
를 로 설정해야 합니다. 그러면 구성 설정이 applicationHost.config 파일의 적절한 위치 섹션에 커밋됩니다.
C#
using System;
using System.Text;
using Microsoft.Web.Administration;
internal static class Sample
{
private static void Main()
{
using(ServerManager serverManager = new ServerManager())
{
Configuration config = serverManager.GetApplicationHostConfiguration();
ConfigurationSection sitesSection = config.GetSection("system.applicationHost/sites");
ConfigurationElementCollection sitesCollection = sitesSection.GetCollection();
ConfigurationElement siteElement = FindElement(sitesCollection, "site", "name", @"Contoso");
if (siteElement == null) throw new InvalidOperationException("Element not found!");
ConfigurationElement hstsElement = siteElement.GetChildElement("hsts");
hstsElement["enabled"] = true;
hstsElement["max-age"] = 31536000;
hstsElement["includeSubDomains"] = true;
hstsElement["redirectHttpToHttps"] = true;
serverManager.CommitChanges();
}
}
private static ConfigurationElement FindElement(ConfigurationElementCollection collection, string elementTagName, params string[] keyValues)
{
foreach (ConfigurationElement element in collection)
{
if (String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase))
{
bool matches = true;
for (int i = 0; i < keyValues.Length; i += 2)
{
object o = element.GetAttributeValue(keyValues[i]);
string value = null;
if (o != null)
{
value = o.ToString();
}
if (!String.Equals(value, keyValues[i + 1], StringComparison.OrdinalIgnoreCase))
{
matches = false;
break;
}
}
if (matches)
{
return element;
}
}
}
return null;
}
}
VB.NET
Imports System
Imports System.Text
Imports Microsoft.Web.Administration
Module Sample
Sub Main()
Dim serverManager As ServerManager = New ServerManager
Dim config As Configuration = serverManager.GetApplicationHostConfiguration
Dim sitesSection As ConfigurationSection = config.GetSection("system.applicationHost/sites")
Dim sitesCollection As ConfigurationElementCollection = sitesSection.GetCollection
Dim siteElement As ConfigurationElement = FindElement(sitesCollection, "site", "name", "Contoso")
If (siteElement Is Nothing) Then
Throw New InvalidOperationException("Element not found!")
End If
Dim hstsElement As ConfigurationElement = siteElement.GetChildElement("hsts")
hstsElement("enabled") = True
hstsElement("max-age") = 31536000
hstsElement("includeSubDomains") = True
hstsElement("redirectHttpToHttps") = True
serverManager.CommitChanges()
End Sub
Private Function FindElement(ByVal collection As ConfigurationElementCollection, ByVal elementTagName As String, ByVal ParamArray keyValues() As String) As ConfigurationElement
For Each element As ConfigurationElement In collection
If String.Equals(element.ElementTagName, elementTagName, StringComparison.OrdinalIgnoreCase) Then
Dim matches As Boolean = True
Dim i As Integer
For i = 0 To keyValues.Length - 1 Step 2
Dim o As Object = element.GetAttributeValue(keyValues(i))
Dim value As String = Nothing
If (Not (o) Is Nothing) Then
value = o.ToString
End If
If Not String.Equals(value, keyValues((i + 1)), StringComparison.OrdinalIgnoreCase) Then
matches = False
Exit For
End If
Next
If matches Then
Return element
End If
End If
Next
Return Nothing
End Function
End Module
JavaScript
var adminManager = new ActiveXObject('Microsoft.ApplicationHost.WritableAdminManager');
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST";
var sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST");
var sitesCollection = sitesSection.Collection;
var siteElementPos = FindElement(sitesCollection, "site", ["name", "Contoso"]);
if (siteElementPos == -1) throw "Element not found!";
var siteElement = sitesCollection.Item(siteElementPos);
var hstsElement = siteElement.ChildElements.Item("hsts");
hstsElement.Properties.Item("enabled").Value = true;
hstsElement.Properties.Item("max-age").Value = 31536000;
hstsElement.Properties.Item("includeSubDomains").Value = true;
hstsElement.Properties.Item("redirectHttpToHttps").Value = true;
adminManager.CommitChanges();
function FindElement(collection, elementTagName, valuesToMatch)
{
for (var i = 0; i < collection.Count; i++)
{
var element = collection.Item(i);
if (element.Name == elementTagName)
{
var matches = true;
for (var iVal = 0; iVal < valuesToMatch.length; iVal += 2)
{
var property = element.GetPropertyByName(valuesToMatch[iVal]);
var value = property.Value;
if (value != null)
{
value = value.toString();
}
if (value != valuesToMatch[iVal + 1])
{
matches = false;
break;
}
}
if (matches)
{
return i;
}
}
}
return -1;
}
VBScript
Set adminManager = WScript.CreateObject("Microsoft.ApplicationHost.WritableAdminManager")
adminManager.CommitPath = "MACHINE/WEBROOT/APPHOST"
Set sitesSection = adminManager.GetAdminSection("system.applicationHost/sites", "MACHINE/WEBROOT/APPHOST")
Set sitesCollection = sitesSection.Collection
siteElementPos = FindElement(sitesCollection, "site", Array("name", "Contoso"))
If siteElementPos = -1 Then
WScript.Echo "Element not found!"
WScript.Quit
End If
Set siteElement = sitesCollection.Item(siteElementPos)
Set hstsElement = siteElement.ChildElements.Item("hsts")
hstsElement.Properties.Item("enabled").Value = True
hstsElement.Properties.Item("max-age").Value = 31536000
hstsElement.Properties.Item("includeSubDomains").Value = True
hstsElement.Properties.Item("redirectHttpToHttps").Value = True
adminManager.CommitChanges()
Function FindElement(collection, elementTagName, valuesToMatch)
For i = 0 To CInt(collection.Count) - 1
Set element = collection.Item(i)
If element.Name = elementTagName Then
matches = True
For iVal = 0 To UBound(valuesToMatch) Step 2
Set property = element.GetPropertyByName(valuesToMatch(iVal))
value = property.Value
If Not IsNull(value) Then
value = CStr(value)
End If
If Not value = CStr(valuesToMatch(iVal + 1)) Then
matches = False
Exit For
End If
Next
If matches Then
Exit For
End If
End If
Next
If matches Then
FindElement = i
Else
FindElement = -1
End If
End Function
IIS관리 PowerShell Cmdlet
Import-Module IISAdministration
Reset-IISServerManager -Confirm:$false
Start-IISCommitDelay
$sitesCollection = Get-IISConfigSection -SectionPath "system.applicationHost/sites" | Get-IISConfigCollection
$siteElement = Get-IISConfigCollectionElement -ConfigCollection $sitesCollection -ConfigAttribute @{"name"="Contoso"}
$hstsElement = Get-IISConfigElement -ConfigElement $siteElement -ChildElementName "hsts"
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "enabled" -AttributeValue $true
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "max-age" -AttributeValue 31536000
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "includeSubDomains" -AttributeValue $true
Set-IISConfigAttributeValue -ConfigElement $hstsElement -AttributeName "redirectHttpToHttps" -AttributeValue $true
Stop-IISCommitDelay
Remove-Module IISAdministration