Mengaktifkan HTTP Strict Transport Security (HSTS) di IIS 7

75

Apa cara terbaik untuk mengaktifkan Keamanan Transportasi HTTP Ketat pada server web IIS 7?

Bisakah saya hanya melalui GUI dan menambahkan header respons HTTP yang tepat atau haruskah saya menggunakan appcmd dan jika demikian apa yang beralih?

Bob
sumber
1
Banyak dari ini tergantung pada bagaimana Anda menghasilkan hal-hal yang dilayani IIS (misalnya. Anda dapat mengatur header di halaman PHP atau ASP.NET dari dalam aplikasi Anda). Bisakah Anda memberi tahu kami lebih lanjut tentang kasus penggunaan Anda?
voretaq7

Jawaban:

18

IIS memiliki kemampuan untuk menambahkan header khusus ke respons . Ini sepertinya cara termudah untuk melakukannya.

Menurut dokumentasi di IIS.net Anda dapat menambahkan header ini melalui IIS Manager:

  • Di panel Koneksi, buka situs, aplikasi, atau direktori yang ingin Anda setel tajuk HTTP khusus.
  • Di panel Beranda, klik dua kali Header Respons HTTP.
  • Di panel HTTP Response Headers, klik Add ... di panel Actions.
  • Di kotak dialog Tambahkan header respons HTTP khusus, tetapkan nama dan nilai untuk header kustom Anda, dan lalu klik OK.
voretaq7
sumber
5
Anda juga dapat melakukan ini di Web.config, yang mungkin Anda sukai. Saya telah memposting rincian sebagai jawaban baru, karena mereka akan sangat sulit dibaca tanpa pemformatan kode sumber yang tidak tersedia di komentar.
Owen Blacker
3
Menurut pembuat Modul Keamanan Transportasi Ketat HTTP Strik , hanya menambahkan tajuk khusus tidak sesuai dengan spesifikasi konsep (RFC 6797). Anda sebenarnya perlu menginstal Modul IIS ini.
Chris
@ Chris Mereka (agak) salah. Bukan tentang spec - mereka benar-benar benar di sana - tetapi tentang fakta bahwa tidak ada cara "sederhana" untuk mematuhi modul mereka: Cukup buat 2 situs, satu untuk SSL (dengan header) dan satu untuk non-SSL ( tanpa tajuk). Tentu saja modul ini sedikit lebih elegan , tetapi itu tidak perlu (dan tidak dijamin sama sekali jika situs Anda hanya https-saja dan Anda tidak melayani tanggapan HTTP biasa).
voretaq7
1
@ Chris Anda harus menambahkan jawaban yang merujuk pada modul itu - upvotes gratis! (Saya tidak mengetahui keberadaannya, dan bagi banyak orang mungkin ini adalah pilihan yang lebih mudah / lebih baik daripada custom header stuff)
voretaq7
112

Ini memungkinkan kami untuk menangani pengalihan HTTP dan menambahkan header Strict-Transport-Security ke respons HTTPS dengan satu situs IIS (modul URL Rewrite harus diinstal):

<?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>
Doug Wilson
sumber
7
Terima kasih, ini jawaban terbaik! Menambahkan header ke file HTML statis juga, tidak seperti pendekatan programatik. Dan tidak menambah HTTP, sehingga sesuai dengan standar.
Jeow Li Huan
4
@Mathemats Sudahkah Anda menginstal ulang URL di IIS?
Doug Wilson
3
Tidak, setelah penelitian lebih lanjut saya menemukan bahwa tag penulisan ulang disediakan oleh ekstensi (d'oh). Semua jawaban yang saya temukan tidak menyebutkan ekstensi sebagai dependensi, mungkin Anda bisa melempar satu kalimat dalam jawaban Anda dengan mengatakan Anda membutuhkannya.
Matematika
2
hstspreload.org ingin pengguna menambahkan `; includeSubDomains; preload` setelah nilai usia maks. pilihan. Baris penuh adalah: <action type="Rewrite" value="max-age=31536000 ;includeSubDomains; preload" />untuk mendapatkan izin pada hstspreload.org
JP Hellemons
2
Grup tangkap R: 1 dengan pola (. *) Cocok dengan seluruh URL, protokol, dan semuanya, dan mencoba untuk menyatukan {HTTP_HOST} / {R: 1} berarti Anda mendapatkan https://somedomain.com/https://somedomain.com/relatedpathdan hasilnya adalah jalan dijatuhkan.
AaronLS
38

Untuk melengkapi jawaban voretaq7 , Anda juga bisa melakukan ini menggunakan file Web.config (NB: Hanya digunakan untuk situs SSL, karena akan menambahkan header untuk respons HTTP dan HTTPS, yang bertentangan dengan spesifikasi RFC 6797, silakan lihat penjelasan di bawah ini) - tambahkan blok sebagai berikut:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Strict-Transport-Security" value="max-age=31536000"/>
        </customHeaders>
    </httpProtocol>
</system.webServer>

Jelas, Anda mungkin sudah memiliki system.webServerblok di Web.config Anda, jadi tambahkan ini ke dalamnya, jika ya. Kami lebih suka menangani hal-hal di Web.config daripada GUI, karena itu berarti perubahan konfigurasi dapat dilakukan ke repositori Git kami.

Jika Anda ingin menangani pengalihan HTTP-ke-SSL, seperti yang disebutkan Greg Askew , Anda mungkin akan lebih mudah melakukannya dengan situs web terpisah di IIS. Ini adalah cara kami menangani memerlukan SSL untuk beberapa situs klien. Situs itu hanya berisi pengalihan HTTP dan beberapa perbaikan pengungkapan informasi , semua di 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>

Ini adalah solusi pilihan kami karena beberapa alasan - kami dapat dengan mudah mencatat lalu lintas yang dialihkan secara terpisah (karena berada dalam log IIS yang berbeda), itu tidak melibatkan lebih banyak kode di Global.asax.cs (kami tidak memiliki kode apa pun di sana, yang sedikit lebih nyaman untuk situs Umbraco) dan, yang penting, itu berarti bahwa semua konfigurasi masih disimpan dalam repo GIT kami.

Diedit untuk menambahkan: Agar lebih jelas, untuk mematuhi RFC 6797 , Strict-Transport-Securityheader khusus TIDAK HARUS ditambahkan ke permintaan yang dibuat oleh HTTP yang tidak dienkripsi. Agar sesuai dengan RFC6797, Anda HARUS memiliki dua situs di IIS, seperti yang telah saya jelaskan setelah blok kode pertama. Seperti yang ditunjukkan Chris , RFC 6797 meliputi:

Host HSTS TIDAK HARUS menyertakan bidang tajuk STS dalam respons HTTP yang disampaikan melalui transportasi yang tidak aman.

jadi mengirim Strict-Transport-Securitytajuk pelanggan sebagai tanggapan atas permintaan non-SSL tidak akan memenuhi spesifikasi.

Owen Blacker
sumber
1
Untuk menambahkan respons Owen Blacker, untuk IIS saya menggunakan URLScan 3.1 dan memilikinya secara global menghapus SERVER dari respons dengan mengatur RemoveServerHeader = 1, sisa pengaturan telah diamanatkan untuk berada di setiap file situs web.config. Saya lebih suka ini daripada hanya mengosongkan nilainya.
KeyOfJ
URLScan adalah solusi yang sangat umum dan, saya sarankan, yang lebih baik daripada yang saya sarankan. Tapi itu tidak selalu merupakan solusi yang paling nyaman: o)
Owen Blacker
Penting untuk dicatat bahwa menambahkan ini ke situs dengan HTTPS dan HTTP diaktifkan (sehingga dapat mengarahkan ulang) akan BREAK situs! Anda akan mendapatkan informasi tanpa angka 500, bahkan dengan CustomErrors Mode = "Off", tanpa kesalahan dalam log.
Chris Moschini
@ChrisMoschini Saya seharusnya lebih jelas bahwa baris Web.config pertama harus untuk situs hanya SSL.
Owen Blacker
1
@Lenne Scott Hanselman menulis deskripsi yang lebih baik tentang mengapa STS tidak termasuk dalam header saat menggunakan HTTP. Baca lebih lanjut di sini
David Yates
8

Saya akan menggunakan contoh dari tautan Wikipedia yang Anda referensikan dan melakukan aktivitas di global.asax untuk situs tersebut. Ini memungkinkan pengalihan permintaan ke url https, dan kemudian masukkan header ke dalam respons.

Ini karena header HSTS harus diabaikan jika tidak ada respons 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;
    }
}
Greg Askew
sumber
3

Ini sepertinya cara gagal yang cukup aman untuk melakukan ini. Tambahkan kode ini di Global.asax - acara Application_BeginRequest pertama kali muncul dalam siklus hidup permintaan Asp.net: http://msdn.microsoft.com/en-us/library/system.web.httpapplication.beginrequest(v=vs. 110) .aspx

Sesuai spesifikasi, permintaan http tidak boleh merespons dengan tajuk - jadi kode ini hanya menambahkannya untuk permintaan https. Max-age dalam hitungan detik, dan biasanya ide yang bagus untuk menaruh nilai besar di sini (IE - 31536000 menunjukkan situs akan menjalankan SSL hanya untuk 365 hari ke depan)

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;
  }
}
erbz
sumber
2

Menggunakan contoh yang disediakan oleh Doug Wilson saya telah membuat dua fungsi PowerShell berikut untuk menambahkan aturan penulisan ulang url untuk pengalihan ke HTTPS dan untuk menambahkan header HSTS.

Ini telah diuji pada Windows 2012 dan Windows 2012 R2.

Yang perlu Anda lakukan adalah menyediakan nama situs web. Secara opsional, Anda dapat memberikan aturan nama yang berbeda jika Anda tidak menyukai pengaturan default.

Satu hal yang perlu diperhatikan adalah bahwa dari pengujian saya, Variabel Server perlu ditambahkan ke daftar izin sebelum berada di header respons. Fungsi melakukan ini untuk Anda.

EDIT: Lihat referensi pada Url Rewrite untuk HTTP Header di sini: 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"

}
CarlR
sumber
1

Menurut pembuat Modul Keamanan Transportasi Ketat HTTP Strik, hanya menambahkan tajuk khusus tidak sesuai dengan spesifikasi konsep (RFC 6797).

Anda sebenarnya perlu menginstal Modul IIS ini untuk mengaktifkan HSTS pada IIS 7.

Pembaruan 26 okt 2014 : Berkat komentator di bawah ini, saya membaca halaman modul lagi dan secara khusus bagian yang membenarkan penggunaan modul daripada menambahkan header kustom.

Host HSTS TIDAK HARUS menyertakan bidang tajuk STS dalam respons HTTP yang disampaikan melalui transportasi yang tidak aman.

Jika Anda memastikan untuk menambahkan tajuk hanya dalam HTTPS dan BUKAN dalam HTTP, Anda tidak memerlukan modul ini dan Anda dapat menggunakan jawabannya oleh Doug Wilson. Jangan gunakan jawaban Owen Blacker karena tidak memiliki kondisi https.

Chris
sumber
1
Jadi, apakah beberapa jawaban lain yang hanya mengirim header ke permintaan HTTPS menyelesaikan masalah ini juga? Atau apakah modul Anda melakukan sesuatu yang berbeda / tambahan yang tidak dilakukan solusi lain?
Slolife
@ Slife Saya memperbarui jawaban saya. Anda dapat menggunakan kode dalam jawaban Doug Wilson. Anda tidak perlu modul ini. Saya melihat sekarang bahwa ini juga dibahas dalam komentar dari jawaban yang diterima. Saya tidak mengetahui modul ini melakukan sesuatu yang berbeda / tambahan bahwa solusi lain tidak. Tapi saya belum melakukan pemeriksaan lengkap terhadap kode sumber .
Chris
Saya seharusnya lebih jelas bahwa Web.config pertama harus diimplementasikan di situs khusus SSL. Saya akan mengedit jawaban saya untuk mengklarifikasi itu.
Owen Blacker
1

Ini dapat dilakukan dengan menambahkan blok berikut di Web.Config:

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

Kita harus mengonfigurasi pada IIS yang memiliki kemampuan untuk menyesuaikan header untuk merespons:

  • Buka Manajer Layanan Informasi Internet (IIS).
  • Konfigurasikan header Respons yang ditambahkan ke respons dari server.
  • Sekarang tambahkan Nama header dan Nilai kustom Anda (Nama dan nilai header khusus harus sama dengan yang ada di Web.Config). Anda dapat menemukannya di blog
Vinit
sumber
0

Hanya untuk menambahkan, saya melihat di komentar 2 orang berbicara tentang 500 kesalahan saat Anda melakukan ini. Saya punya ini.

Jika Anda mendapatkan 500 kesalahan di IIS itu mungkin karena Anda telah menambahkan aturan di tingkat atas, diatur ke warisan, dan di tingkat situs.

misalnya

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

IIS / Browser tampaknya tidak memberi Anda informasi apa pun yang telah Anda lakukan ini, terlepas dari pengaturan penanganan kesalahan Anda

tony
sumber