從 HTTP 到 HTTPS - IIS 部署免費 HTTP

HTTP

當你在瀏覽器輸入一個網址 (例如 http://tasaid.com)的時候,瀏覽器發起一個 HTTP 請求,帶著請求信息 (參見 HTTP Headers),連接到伺服器,把請求信息遞給伺服器,伺服器收到信息之後,解析相關的信息,然後進行處理,再返回瀏覽器請求的數據。

簡單來說是這麼一個流程:

  1. 小明瀏覽器爸爸 說我想要去中關村某個店家拿一些東西 (發起請求)

  2. 瀏覽器爸爸 就把 小明 要的東西記在一張清單上 (生成HTTP協議)

  3. 然後 瀏覽器爸爸 派出一個 線程小弟,噌噌噌跑到中關村的店裡,把清單遞給 店家,說小明要這些東西 (進行傳輸)

  4. 店家線程小弟 稍等,然後去屋子裡面拿小明的這些東西 (伺服器收到請求)

    Advertisements

  5. 店家 把東西拿出來后,並且也列印了一份清單,讓 線程小弟 帶著清單和東西一起拿回去 (伺服器處理請求完畢)

  6. 然後 線程小弟 回到 瀏覽器爸爸 那邊,把伺服器給的清單和物品交給瀏覽器爸爸,瀏覽器爸爸根據清單核對物品 (瀏覽器處理響應)

  7. 然後把物品打包交給了 小明 (瀏覽器渲染並呈現界面)

看圖說話:

這其中有個問題,瀏覽器爸爸和伺服器都沒有驗證清單信息的有效性和對方的身份。萬一有人在中間把線程小哥攔下來,暴揍一頓,然後把物品清單給換了怎麼辦?或者有人把線程小哥在半路上暴揍一頓,拿了清單換了另外一個小哥怎麼辦?

這是個很嚴肅的問題:假如伺服器要把一些東西鎖在柜子里,需要小明給密碼才可以打開柜子。然後小明把密碼寫在清單上讓瀏覽器爸爸交給伺服器。這時候,如果這張清單被人攔截下來,不就得到了小明的密碼?

Advertisements

簡單來說,傳輸的信息中包含用戶密碼,被攔截了怎麼辦?

HTTPS

正因為HTTP請求有這些安全性的問題,所以HTTPS誕生了,致力於解決了這些安全性問題,我們進行一下對比:

那麼HTTPS是如何做到更安全的呢?

簡單來說,HTTPS 即是在 HTTP 下加入了一層 SSL 加密,所以被稱為HTTPS。具體的加密過程則是 公匙加密法:

  • 客戶端向伺服器索要公匙,然後使用公匙加密信息

  • 伺服器收到加密后的信息,用自己的私匙解密

公匙密碼和演算法都是公開的,而私匙則是保密的。加密使用的公匙和解碼使用的密匙都是不相同的,因此這是一個 非對稱加密 演算法。

數字證書

提及 HTTPS ,就會聽到大家說需要證書才能部署,那麼什麼是證書呢?

因為互聯網不安全,公匙也是信息的一部分,也是會有被篡改的風險的。所以引入了互聯網權威機構 - CA 機構,又稱為證書授權 (Certificate Authority) 機構,瀏覽器會內置這些"受信任的根證書頒發機構" (即 CA)。

服務端向權威的身份鑒定 CA 機構申請數字證書,CA 機構驗證了網站之後,會把網站錄入到內部列表,採用 Hash 把服務端的一些相關信息生成摘要,然後 CA 機構用自己的私匙,把服務端的公匙和相關信息一起加密,然後給申請證書的服務端頒發數字證書,用於其他客戶端 (比如瀏覽器) 認證這個網站的公匙。

客戶端通過服務端下發的證書,找到對應的 CA,然後向 CA 驗證這個證書是否有效,CA 驗證通過之後,下發服務端的公匙。

因為 CA 是權威並且可信的,所以客戶端 (瀏覽器) 信任 CA,而 CA 又信任經過認證的服務端 ,所以客戶端 (瀏覽器) 也信任這個服務端,這就是信任鏈 (Chain Of Trust)。

而 CA 頒發的數字證書,一般包含這些信息:

簡單來說:為了保證公匙是安全的,所以通過數字證書驗證公匙。

加密通信

一條完整的HTTPS請求應該是這樣的:

  1. 客戶端 (瀏覽器) 發起 HTTP 請求,請求連接服務端,發送支持的加密通信協議 (和版本),並且生成一個隨機數,後續用於生成"對話密鑰"。

  2. 服務端確認加密通信協議 (和版本),同時也生成一個隨機數,後續用於生成"對話密匙",並且將 CA 頒發的數字證書,一起發送給客戶端。

  3. 客戶端收到數字證書後,檢測內置的"受信任的根證書頒發機構",查看解開數字證書的公匙是否在。

  4. 如果解開數字證書的公匙存在,則使用它解開數字證書,得到正確的伺服器公匙,同時再次生成一個隨機數,用於伺服器公匙加密,併發送給伺服器。

  5. 此時本地和伺服器同時將三個隨機數,根據約定的加密方法進行加密,各自生成本次會話的所使用的同一把 "會話密匙" 。

  6. 到這裡,認證階段已經完畢,數據傳輸從 非對稱加密 換成了 對稱加密 (因為考慮到性能),接下來所有的數據傳輸都是使用HTTP協議進行傳輸,只不過使用了 "會話密匙" 來加密內容。

見下圖:

有哪些免費證書

這裡只介紹在 TaSaid.com 部署 HTTPS 中嘗試的免費證書方案,部署在 IIS8 上。

  • Let's Encrypt

  • 沃通 (wosign) (不推薦)

本來在 TaSaid.com 遷移中嘗試部署過沃通 (wosign) 的簽發的免費證書,但是後來發現了 Mozilla 官網( firefox/火狐 背後的開源組織 ) 里列出了 沃通的一系列可疑行為和問題,並且沃通 "秘密" 收購 StartCom(著名的免費 HTTPS 證書 StartSSL 即其旗下產品)行為可疑, Mozilla 基金會正在考慮對沃通以及 StartCom 這兩個 CA 機構一年內新簽發的所有 SSL 證書進行封殺。

我在上一篇文章 《從 HTTP 到 HTTPS - 什麼是 HTTPS》 中指出 CA 機構應該是是權威和可信的,但由於沃通當前的陷入的一系列醜聞,信任度降低,所以暫時不推薦使用沃通。並且沃通官網已暫時關閉免費 HTTPS 證書申請。

這一段內容發表於2016年10月5日,如果您在未來某天閱覽到這個內容,請即時更新了解沃通最新的動態。

所以我們這次僅推薦 Let's Encrypt。

Let's Encrypt

推薦 Let's Encrypt 理由:

  • 由 ISRG(Internet Security Research Group,互聯網安全研究小組)提供服務,而 ISRG 是來自於美國加利福尼亞州的一個公益組織。Let's Encrypt 得到了 Mozilla、Cisco、Akamai、Electronic Frontier Foundation 和 Chrome 等眾多公司和機構的支持,發展十分迅猛。

  • 極速申請 - 只要認證的網站通過驗證,當時即可頒發證書

  • 免費和訪問速度兼得

  • 對於域名所有權的驗證,支持兩種方式:放臨時文件進行驗證、查詢 whois 給域名所有人發郵件驗證

  • 無需註冊賬戶

  • 關鍵是穩定,背後的支持的組織很強大

缺點:

  • 一次只能頒發3個月有效期的證書,到期之後需要自己再續上 (仍然是免費的),這點維護起來比較麻煩,不過我們可以使用工具自動續期。

  • 不支持通配符泛域名 (*.demo.com),所以在申請認證是時候,要把域名都 301 跳轉到證書里包含的域名上,不然瀏覽器會彈證書錯誤。

流程

默認 Let's Encrypt 申請證書比較繁瑣,所以我們在 windows 下使用工具 letsencrypt-win-simple 進行部署,簡單方便快捷。

  1. 下載 letsencrypt-win-simple

  2. 在伺服器中打開CMD,運行letsencrypt-win-simple

  3. 在CMD中根據簡單的命令,輸入要認證的網站域名和網站文件夾

  4. letsencrypt-win-simple 自動驗證域名所有權

  5. 驗證通過後即時頒發證書

  6. 部署

使用 letsencrypt-win-simple 進行自動化認證和部署

下載最新版 letsencrypt-win-simple:

本人在2016年9月15日下到的最新版是:letsencrypt-win-simple.V1.9.1.zip。

自動化認證

在伺服器解壓 letsencrypt-win-simple.V1.9.1 得到文件夾,打開CMD進入到該文件夾下。

第一次運行命令會連接遠程伺服器更新,並且會讓你是否輸入郵箱訂閱認證信息,可以忽略,然後讓做個選擇(忘記什麼選擇了),選擇Y即可,選擇N則會中斷。

部署單個域名

  • 輸入以下命令letsencrypt.exe --accepttos --manualhost 你的域名 --webroot 你的網站物理路徑(wwwroot路徑)

  • letsencrypt-win-simple.V1.9.1 會自動生成臨時文件並放到網站根目錄,然後會讓 Let's Encrypt 伺服器會訪問這個文件, 用於驗證這個網站是否屬於你。

  • 如果驗證不通過,是因為 IIS 需要修改一些配置,具體參見下文的詳細說明。

  • 驗證通過後會實時頒發證書,並且 letsencrypt-win-simple.V1.9.1 會自動把證書添加到伺服器中,然後直接在 IIS 中進行HTTPS部署即可。

部署多個域名

  • 輸入命令 letsencrypt.exe --san

  • 輸入 M ,表示此次需要認證多個域名

  • 輸入網站的 host

  • 輸入要認證的多個域名,用 , 號分隔,比如tasaid.com,www.tasaid.com,m.tasaid.com

  • 輸入網站物理路徑,比如 C:\Users\linkFly\Documents\Said\SaidTemp

  • letsencrypt-win-simple.V1.9.1 會自動生成臨時文件並放到網站根目錄,然後會讓 Let's Encrypt 伺服器會訪問這個文件, 用於驗證這個網站是否屬於你。

  • 如果驗證不通過,是因為 IIS 需要修改一些配置,具體參見下文的詳細說明。

  • 驗證通過後會實時頒發證書,並且會自動把證書添加到伺服器中,然後直接在 IIS 中進行HTTPS部署即可。

自動化認證單個域名

解壓 letsencrypt-win-simple.V1.9.1 文件夾,然後點擊文件夾,按住shift,再點擊右鍵,選擇在此處打開命令窗口 (即讓控制台打開后直接定位到這個文件夾下)。

使用下面的命令:

letsencrypt.exe --accepttos --manualhost 你的域名 --webroot 你的網站路徑(wwwroot路徑)

比如 https://tasaid.com 部署的命令是這樣的:

letsencrypt.exe --accepttos --manualhost tasaid.com --webroot C:\Users\linkFly\Test

letsencrypt-win-simple 會自動生成臨時文件並放到網站根目錄 (詳情可以參考下一章節 自動化認證多個域名 ),然後會讓 Let's Encrypt 伺服器會訪問這個文件, 用於驗證這個網站是否屬於你。

如果驗證通過,直接進入本文的 部署 章節即可。如果驗證不通過,是因為需要修改 IIS 的一些配置,請參考下一章節 自動化認證多個域名

自動化認證多個域名

CMD 進入 letsencrypt-win-simple.V1.9.1 文件夾,運行如下命令:

letsencrypt.exe --san

然後會彈出一坨選項:

Let's Encrypt (Simple Windows ACME Client)

Renewal Period: 60

Certificate Store: WebHosting

ACME Server: https://acme-v01.api.letsencrypt.org/

Config Folder: C:\Users\linkFly\AppData\Roaming\letsencrypt-win-simple\htpsacme-v01.api.letsencrypt.org

Certificate Folder: C:\Users\linkFly\AppData\Roaming\letsencrypt-win-simpe\httpsacme-v01.api.letsencrypt.org

Loading Signer from C:\Users\linkFly\AppData\Roaming\letsencrypt-win-simpe\httpsacme-v01.api.letsencrypt.org\Signer

Getting AcmeServerDirectory

Loading Registration from C:\Users\linkFly\AppData\Roaming\letsencrypt-win-simple\httpsacme-v01.api.letsencrypt.org\Registration

Scanning IIS Sites

2: SAN - IIS Said (C:\Users\linkFly\Test)

3: SAN - IIS Test (C:\Users\linkFly\Demo)

W: Generate a certificate via WebDav and install it manually.

S: Generate a single San certificate for multiple sites.

F: Generate a certificate via FTP/ FTPS and install it manually.

M: Generate a certificate manually.

A: Get certificates for all hostsQ: Quit

Which host do you want to get a certificate for:

Scanning IIS Sites 列出了在 IIS 中檢測到的當前已發布的網站,然後顯示了一系列指令 (W, S, F, M, A),決定你想要的操作:

  • W - 生成一個證書並通過 WebDav 來進行安裝

  • S - 給 IIS 當前已經發布的所有網站都部署一個證書

  • F - 生成一個證書通過FTP、FTPS安裝。

  • M - 通過配置手動生成證書

  • A - 給 IIS 當前已經發布的所有網站各自部署上對應的證書

我們這次要認證手動認證多個域名,輸入命令:

M

接著出現讓你輸入host( Enter a host name )。比如 http://tasaid.com 輸入的是tasaid.com。

然後會讓你輸入要認證的多個域名 (注意這些域名要可以訪問的,因為一會兒會輪流訪問這些域名進行驗證),用,號分隔 (Enter all Alternative Names seperated by a comma:),然後我們輸入需要驗證的域名即可:

tasaid.com,www.tasaid.com,m.tasaid.com,wap.tasaid.com

接著輸入站點部署的位置 (Enter a site path ),輸入你的網站部署的位置即可:

C:\Users\linkFly\Documents\Said\SaidTemp

然後輸入是否要指定使用者 (用戶),輸入 N。( 一旦選擇了Y,會讓你輸入用戶名和密碼,證書會進行用戶認證 )。

接著會在你此次認證的項目根目錄下 (wwwroot) ,根據你剛才輸入的域名列表,生成對應的臨時認證文件, Let's Encrypt 伺服器會訪問這個文件,結構大概如下:

---- wwwroot(認證的網站根目錄)| -- .well-known

| -- acme-challenge

| -- DGz4z_A_VsgO3dilCAB8bkgurpPt-EFpLygmua3L6x8 (一個臨時文件,多個域名會有多個臨時文件)

然後 Let's Encrypt 伺服器會根據剛才輸入的域名列表,用 HTTP 輪流訪問這些文件,注意這時候可能存在這個報錯:

******************************************************************************The ACME server was probably unable to reach http://linkflys.com/.well-known/acme-challenge/DGz4z_A_VsgO3dilCAB8bkgurpPt

Check in a browser to see if the answer file is being served correctly.*****************************************************************************

出現這個錯誤表示生成的這個臨時文件訪問不到,驗證不通過。

原因是因為 .well-know 這個文件夾帶了前綴.,IIS會認為是不可識別的 MIMEType ,只需要在網站根目錄下臨時加上 mimeMap 配置即可:

<?xml version="1.0" encoding="UTF-8"?><configuration>

<system.webServer>

<staticContent>

<mimeMap fileExtension="." mimeType="text/plain" />

</staticContent>

</system.webServer></configuration>

記得驗證通過後,如果你的網站不需要這個 mimeMap 配置,要記得刪除。

如果驗證通過,會顯示下圖,這時候恭喜你驗證通過。

部署

打開 IIS,選擇對應的網站,右鍵 編輯綁定,點擊 新增, 類型 選擇https,則會彈出如下界面:

輸入要綁定的域名,然後選擇頒發的證書即可。域名 日期 上午/下午這種格式就是 Let's Encrypt 此次頒發的證書。

這個時候,使用 https 協議訪問你的域名就可以啦,比如:https://tasaid.com。

查看證書

在伺服器中查看證書

在伺服器中,Win + R 打開運行,輸入 MMC,打開 控制台 界面。

點擊頂部菜單欄 文件,然後點擊 添加/刪除管理單元

彈出的窗口中,在左側的 可用的管理單元 中點擊 證書,然後點中間的 添加,會彈出如下界面:

選擇 計算機賬戶,然後默認下一步完成,點擊 確定,即可看到證書列表。

展開 證書,再展開 中間證書頒發機構,選擇 證書,即可看到 Let's Encrypt 頒發的證書:

在chrome中查看證書

使用 HTTPS 訪問網址,點擊地址欄的小 綠鎖,然後點擊 詳細信息,這時候會彈出 chrome 調試工具,點擊 View certificate:

就會看到證書的詳細信息:

其他

IIS 配置 web.config 實現自動 HTTPS 跳轉

為了保證域名統一,將訪問 http://www.tasaid.com、http://tasaid.com、https://www.tasaid.com 的域名都跳轉到 https://tasaid.com,IIS 可以進行如下配置 (需要安裝 IIS UrlRewrite 模塊,代碼註釋是為了方便理解,部署到線上請刪除中文註釋):

<?xml version="1.0" encoding="UTF-8"?><configuration>

<system.webServer>

<rewrite>

<rules>

<rule name="HostNameRule1">

<match url="(.*)" />

<!--匹配所有條件-->

<conditions logicalGrouping="MatchAny">

<!--當不是使用https協議訪問的時候-->

<add input="{HTTPS}" pattern="^OFF$" />

<!--並且訪問的host不是tasaid.com這種,例如www.tasaid.com-->

<add input="{HTTP_HOST}" pattern="^tasaid\.com$" negate="true" />

</conditions>

<!--跳轉到https-->

<action type="Redirect" url="https://tasaid.com/{R:1}" />

</rule>

<rule name="HTTPS redirect">

<match url="(.*)" />

<conditions>

<!--當使用HTTPS協議訪問-->

<add input="{HTTPS}" pattern="^ON$" />

<!--當訪問 https://www.tasaid.com的時候 -->

<add input="{HTTP_HOST}" pattern="^tasaid\.com$" negate="true" />

</conditions>

<!--跳轉到HTTPS-->

<action type="Redirect" url="https://tasaid.com/{R:1}" redirectType="SeeOther" />

</rule>

</rules>

</rewrite>

</system.webServer></configuration>

這裡需要注意,想讓 https://www.tasaid.com 也可以跳轉到 https://tasaid.com,在申請 HTTPS 證書的時候,要把 www.tasaid.com 這種域名也給申請上,否則瀏覽器會解析不出 https://www.tasaid.com,因為在進行 HTTPS 加密握手的時候就會認證失敗。

chrome 調試中發現 HTTPS 改動不生效

HTTPS 第一次連接域名的時候會和證書頒發機構進行 HTTPS 證書認證,後續的連接會緩存起來,清緩存就好了

閱讀原文:http://www.ililei.com/post/1854.html

Advertisements

你可能會喜歡