從 HTTP 到 HTTPS - IIS 部署免費 HTTP
HTTP
當你在瀏覽器輸入一個網址 (例如 http://tasaid.com)的時候,瀏覽器發起一個 HTTP 請求,帶著請求信息 (參見 HTTP Headers),連接到伺服器,把請求信息遞給伺服器,伺服器收到信息之後,解析相關的信息,然後進行處理,再返回瀏覽器請求的數據。
簡單來說是這麼一個流程:
小明 跟 瀏覽器爸爸 說我想要去中關村某個店家拿一些東西 (發起請求)
瀏覽器爸爸 就把 小明 要的東西記在一張清單上 (生成HTTP協議)
然後 瀏覽器爸爸 派出一個 線程小弟,噌噌噌跑到中關村的店裡,把清單遞給 店家,說小明要這些東西 (進行傳輸)
店家 讓 線程小弟 稍等,然後去屋子裡面拿小明的這些東西 (伺服器收到請求)
Advertisements
店家 把東西拿出來后,並且也列印了一份清單,讓 線程小弟 帶著清單和東西一起拿回去 (伺服器處理請求完畢)
然後 線程小弟 回到 瀏覽器爸爸 那邊,把伺服器給的清單和物品交給瀏覽器爸爸,瀏覽器爸爸根據清單核對物品 (瀏覽器處理響應)
然後把物品打包交給了 小明 (瀏覽器渲染並呈現界面)
看圖說話:
這其中有個問題,瀏覽器爸爸和伺服器都沒有驗證清單信息的有效性和對方的身份。萬一有人在中間把線程小哥攔下來,暴揍一頓,然後把物品清單給換了怎麼辦?或者有人把線程小哥在半路上暴揍一頓,拿了清單換了另外一個小哥怎麼辦?
這是個很嚴肅的問題:假如伺服器要把一些東西鎖在柜子里,需要小明給密碼才可以打開柜子。然後小明把密碼寫在清單上讓瀏覽器爸爸交給伺服器。這時候,如果這張清單被人攔截下來,不就得到了小明的密碼?
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請求應該是這樣的:
客戶端 (瀏覽器) 發起 HTTP 請求,請求連接服務端,發送支持的加密通信協議 (和版本),並且生成一個隨機數,後續用於生成"對話密鑰"。
服務端確認加密通信協議 (和版本),同時也生成一個隨機數,後續用於生成"對話密匙",並且將 CA 頒發的數字證書,一起發送給客戶端。
客戶端收到數字證書後,檢測內置的"受信任的根證書頒發機構",查看解開數字證書的公匙是否在。
如果解開數字證書的公匙存在,則使用它解開數字證書,得到正確的伺服器公匙,同時再次生成一個隨機數,用於伺服器公匙加密,併發送給伺服器。
此時本地和伺服器同時將三個隨機數,根據約定的加密方法進行加密,各自生成本次會話的所使用的同一把 "會話密匙" 。
到這裡,認證階段已經完畢,數據傳輸從 非對稱加密 換成了 對稱加密 (因為考慮到性能),接下來所有的數據傳輸都是使用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 進行部署,簡單方便快捷。
下載 letsencrypt-win-simple
在伺服器中打開CMD,運行letsencrypt-win-simple
在CMD中根據簡單的命令,輸入要認證的網站域名和網站文件夾
letsencrypt-win-simple 自動驗證域名所有權
驗證通過後即時頒發證書
部署
使用 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