[小菜一碟] 躲在 Load Balancing 後面的 IIS 站台如何將 HTTP 的要求強制重新導向到 HTTPS?

  • 1307
  • 0
  • IIS
  • 2018-01-06

之前有介紹過 SSL 憑證只要放在 Load Balancing 就可以了,不必在每台 Load Balancing 後面的機器都去放置 SSL 憑證,假設我們原有 http://xxx.yyy.com 的網址,在我們打通了 https 之後想要將 http 都強制重新導向到 https,很直覺地我們想到的解決方案就是檢查打進來的 Request URL 如果是 http:// 開頭的就回應重新導向到 https:// 開頭的就行了,但死亡導向之門也就此被打開了。

無論我們是用 URL Rewrite Module 或是寫程式在每個 Request 進來的時候去檢查,都免不了檢查 URL 的開頭是否為 http:// 開頭或是 Request.Url.Scheme 是否為 http?

但問題來了,請看下圖,明明網址列是 https:// 開頭,怎麼到了後端變 http 了?!

如果我們不信邪,還是硬要弄會發生什麼事情? 就開啟了死亡導向之門!

關鍵在於 Load Balancing 大都用代理的方式轉發 Request 到後端服務,服務本身只需提供 http 端口接收來自 Load Balancing 轉發的 Request,即便是 Request 本身是走 https 也都由 Load Balancing 解密完後轉發到後端服務,因此後端服務解析出來的 Request.Url.Scheme 為 http 是正常的。

那該怎麼辦?

Load Balancing 代理轉發的 Request 會在標頭加入代理資訊,其中 HTTP_X_FORWARDED_PROTO 標頭就可以讓我們知道 Load Balancing 代理轉發的 Request 是走 http 還是 https。

在 URL Rewrite 新增規則

我選擇用 URL Rewrite 來解決這樣的問題,檢查進來的 Request 是否符合下面兩個條件,是的話就強制重新導向到 https://xxx.yyy.com/...。

  1. HTTP_Host 是否是 xxx.yyy.com?
  2. HTTP_X_FORWARDED_PROTO 是否非 https?

這樣設定之後,躲在 Load Balancing 的後端服務就可以正確地判斷 Request 有沒有走 https 進來。

參考資料

C# 指南 ASP.NET 教學 ASP.NET MVC 指引
Azure SQL Database 教學 SQL Server 教學 Xamarin.Forms 教學