nginx 響應頭中添加HSTS

從 HTTP 到 HTTPS 再到 HSTS

近些年,隨着域名劫持、信息泄漏等網絡安全事件的頻繁發生,網站安全也變得越來越重要,也促成了網絡傳輸協議從 HTTP 到 HTTPS 再到 HSTS 的轉變。

HTTP

HTTP(超文本傳輸協議) 是一種用於分佈式、協作式和超媒體信息系統的應用層協議。HTTP 是互聯網數據通信的基礎。它是由萬維網協會(W3C)和互聯網工程任務組(IETF)進行協調製定了 HTTP 的標準,最終發佈了一系列的 RFC,並且在1999年6月公佈的 RFC 2616,定義了 HTTP 協議中現今廣泛使用的一個版本——HTTP 1.1。

HTTP 訪問過程

HTTP 屬於 TCP/IP 模型中的應用層協議,當瀏覽器與服務器進行互相通信時,需要先建立TCP 連接,之後服務器纔會接收瀏覽器的請求信息,當接收到信息之後,服務器返回相應的信息。最後瀏覽器接受對服務器的信息應答後,對這些數據進行解釋執行。

△http 1.0 請求模式

HTTP 1.0 時,瀏覽器每次訪問都要單獨建立連接,這會造成資源的浪費。

後來HTTP 1.1可以在一次連接中處理多個請求,並且將多個請求重疊進行

△http 1.1 請求模式

HTTP 協議特點

1. 簡單、快速、靈活:當用戶想服務器發送請求時,只需傳送請求方法和路徑即可,HTTP 允許傳輸任意類型的數據對象。並且HTTP協議簡單易用,HTTP 服務器規模小,保證了網絡通信的速度;

2. 無連接、無狀態:HTTP協議限制每次連接只處理單個請求,當服務器收到用戶請求後就會斷開連接,保證了傳輸時間的節省。同時HTTP協議對事務處理沒有記憶能力,如果後續的請求需要使用前面的信息就必須重傳數據;

3. 管線化和內容編碼:隨着管線化技術的出現,HTTP 請求比持久性連接速度更快,並且當某些報文的內容過大時,爲了減少傳輸的時間,HTTP 會採取壓縮文件的方式;

4. HTTP支持客戶/服務器模式

從HTTP到HTTPS

HTTP 協議由於其簡單快速、佔用資源少,一直被用於網站服務器和瀏覽器之間進行數據傳輸。但是在數據傳輸的過程中也存在很明顯的問題,由於 HTTP 是明文協議,不會對數據進行任何方式的加密。當黑客攻擊竊取了網站服務器和瀏覽器之間的傳輸報文的時,可以直接讀取傳輸的信息,造成網站、用戶資料的泄密。因此 HTTP 不適用于敏感信息的傳播,這個時候需要引入 HTTPS(超文本傳輸安全協議)。

HTTPS

HTTPS(Hypertext Transfer Protocol Secure )是一種以計算機網絡安全通信爲目的的傳輸協議。在HTTP下加入了SSL層,從而具有了保護交換數據隱私和完整性和提供對網站服務器身份認證的功能,簡單來說它就是安全版的 HTTP 。

△ HTTP、HTTPS 差異

 

HTTPS 訪問過程

HTTPS在進行數據傳輸之前會與網站服務器和Web瀏覽器進行一次握手,在握手時確定雙方的加密密碼信息。

具體過程如下:

1. Web 瀏覽器將支持的加密信息發送給網站服務器;

2. 網站服務器會選擇出一套加密算法和哈希算法,將驗證身份的信息以證書(證書發佈CA機構、證書有效期、公鑰、證書所有者、簽名等)的形式發送給Web瀏覽器;

3. 當 Web 瀏覽器收到證書之後首先需要驗證證書的合法性,如果證書受到瀏覽器信任則在瀏覽器地址欄會有標誌顯示,否則就會顯示不受信的標識。當證書受信之後,Web 瀏覽器會隨機生成一串密碼,並使用證書中的公鑰加密。之後就是使用約定好的哈希算法握手消息,並生成隨機數對消息進行加密,再將之前生成的信息發送給網站;

△ Chrome 瀏覽器 HTTPS安全標識

4. 當網站服務器接收到瀏覽器發送過來的數據後,會使用網站本身的私鑰將信息解密確定密碼,然後通過密碼解密Web瀏覽器發送過來的握手信息,並驗證哈希是否與Web瀏覽器一致。然後服務器會使用密碼加密新的握手信息,發送給瀏覽器;

5. 最後瀏覽器解密並計算經過哈希算法加密的握手消息,如果與服務發送過來的哈希一致,則此握手過程結束後,服務器與瀏覽器會使用之前瀏覽器生成的隨機密碼和對稱加密算法進行加密交換數據。

△ HTTPS 握手過程

HTTPS 加密算法

爲了保護數據的安全,HTTPS 運用了諸多加密算法:

1.對稱加密:有流式、分組兩種,加密和解密都是使用的同一個密鑰。

例如:DES、AES-GCM、ChaCha20-Poly1305 等。

2.非對稱加密:加密使用的密鑰和解密使用的密鑰是不相同的,分別稱爲:公鑰、私鑰,公鑰和算法都是公開的,私鑰是保密的。非對稱加密算法性能較低,但是安全性超強,由於其加密特性,非對稱加密算法能加密的數據長度也是有限的。

例如:RSA、DSA、ECDSA、 DH、ECDHE 等。

3. 哈希算法:將任意長度的信息轉換爲較短的固定長度的值,通常其長度要比信息小得多,且算法不可逆。

例如:MD5、SHA-1、SHA-2、SHA-256 等。

4. 數字簽名:簽名就是在信息的後面再加上一段內容(信息經過 hash 後的值),可以證明信息沒有被修改過。hash 值一般都會加密後(也就是簽名)再和信息一起發送,以保證這個 hash 值不被修改。

從 HTTPS 到 HSTS

但是當網站傳輸協議從 HTTP 到 HTTPS 之後,數據傳輸真的安全了嗎?

由於用戶習慣,通常準備訪問某個網站時,在瀏覽器中只會輸入一個域名,而不會在域名前面加上 http:// 或者 https://,而是由瀏覽器自動填充,當前所有瀏覽器默認填充的都是http://。一般情況網站管理員會採用了 301/302 跳轉的方式由 HTTP 跳轉到 HTTPS,但是這個過程總使用到 HTTP 因此容易發生劫持,受到第三方的攻擊。

這個時候就需要用到 HSTS(HTTP 嚴格安全傳輸)。

△ HTTP 請求劫持

HSTS

HSTS是國際互聯網工程組織 IETF 正在推行一種新的 Web 安全協議,網站採用 HSTS 後,用戶訪問時無需手動在地址欄中輸入 HTTPS,瀏覽器會自動採用 HTTPS 訪問網站地址,從而保證用戶始終訪問到網站的加密鏈接,保護數據傳輸安全。

HSTS原理

HSTS 主要是通過服務器發送響應頭的方式來控制瀏覽器操作:

1. 首先在服務器響應頭中添加 HSTS 響應頭:

Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]

此響應頭只有在 https 訪問返回時才生效,其中[ ]中的參數表示可選;

2. 設置 max-age 參數,時間設置不宜過長,建議設置時間爲 6 個月;

3. 當用戶下次使用 HTTP 訪問,客戶端就會進行內部跳轉,並且能夠看到 307 Redirect Internel 的響應碼;

4. 網站服務器變成了 HTTPS 訪問源服務器。

開啓 HSTS 後網站可以有效防範中間人的攻擊,同時也會省去網站 301/302 跳轉花費的時間,大大提升安全係數和用戶體驗。

開啓 HSTS 後網站安全係數檢測測評

開啓 HSTS 以後,可以到 ssllabs 進行測試,網站的安全等級會進一步提升。

開啓前等級爲:A

開啓後等級變爲:A+

上面的文字大概講述了HSTS的前世今生,下面我們就說說怎麼在nginx HTTPS站點中使用

HSTS
302 跳轉是由瀏覽器觸發的,服務器無法完全控制,這個需求導致了 HSTS(HTTP Strict Transport Security)的誕生。HTSP 就是添加 header 頭(add_header Strict-Transport-Security max-age=15768000;includeSubDomains),告訴瀏覽器網站使用 HTTPS 訪問,支持HSTS的瀏覽器就會在後面的請求中直接切換到 HTTPS。在 Chrome 中會看到瀏覽器自己會有個 307 Internal Redirect 的內部重定向。在一段時間內也就是max-age定義的時間,不管用戶輸入 www.liberalman.cn 還是 http://www.liberalman.cn ,都會默認將請求內部跳轉到https://www.liberalman.cn 。

採用HSTS協議的網站將保證瀏覽器始終連接到該網站的HTTPS加密版本,不需要用戶手動在URL地址欄中輸入加密地址。

該協議將幫助網站採用全局加密,用戶看到的就是該網站的安全版本。

HSTS的作用是強制客戶端(如瀏覽器)使用HTTPS與服務器創建連接。服務器開啓HSTS的方法是,當客戶端通過HTTPS發出請求時,在服務器返回的超文本傳輸協議響應頭中包含Strict-Transport-Security字段。非加密傳輸時設置的HSTS字段無效。

比如,https://www.liberalman.cn 的響應頭含有Strict-Transport-Security: max-age=31536000; includeSubDomains。這意味着兩點:
在接下來的一年(即31536000秒)中,瀏覽器只要向xxx或其子域名發送HTTP請求時,必須採用HTTPS來發起連接。比如,用戶點擊超鏈接或在地址欄輸入 http://www.liberalman.cn/ ,瀏覽器應當自動將 http 轉寫成 https,然後直接向 https://www.liberalman.cn/ 發送請求。

在接下來的一年中,如果 www.liberalman.cn 服務器發送的TLS證書無效,用戶不能忽略瀏覽器警告繼續訪問網站。

服務器端配置HSTS,減少302跳轉,其實HSTS的最大作用是防止302 HTTP劫持。HSTS的缺點是瀏覽器支持率不高,另外配置HSTS後HTTPS很難實時降級成HTTP。同時,也建議啓用SPDY來提高性能,不累述。

nginx如何配置HSTS
在nginx的配置中,在https的server站點添加如下頭部:

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

這樣當第一次以https方式訪問我的網站,nginx則會告知客戶端的瀏覽器,以後即便地址欄輸入http,也要瀏覽器改成https來訪問我的nginx服務器。是不是很爽,服務器再也不管http轉發到https這檔子事了,由瀏覽器自己把http改名字爲https再來請求服務器,這不就減少了訪問服務器的次數了嗎,節省了不少資源。

實測效果,重啓nginx後,第一次訪問用了http,發現沒有跳轉。當然不跳了,人家HSTS生效是要你訪問https才生效的。然後輸入了https的網址,下來再重新輸入http,神奇了,真的瀏覽器自己替換成了https,再試試依然會替換,看我的配置,大概會維持63072000s吧,哈哈。

如果用戶第一次訪問是http,以後還是http,就是不用一次https,那我們豈不是一直不能是的HSTS生效了?所以這裏再加個配置,在http站點的server下,添加配置

return 301 https://$host;


這樣當客戶端訪問http的時候,nginx就給他轉到https上去,那訪問了一次https後,以後瀏覽器自己就往https上轉了,發到nginx的也就是https的請求了!

另外如果爲了避免點擊劫持,還要添加 X-Frame-Options 頭部,確保不會嵌入到frame 或 iframe,使得網站的內容不會嵌入到其他網站。

add_header X-Frame-Options "DENY";

瀏覽器支持
Chromium和Google Chrome從4.0.211.0版本開始支持HSTS

Firefox 4及以上版本

Opera 12及以上版本

Safari從OS X Mavericks起

Internet Explorer從Windows 10技術預覽版開始支持,之後微軟又向IE11用戶推送了支持HSTS的更新。

缺點
HSTS並不是HTTP會話劫持的完美解決方案。用戶首次訪問某網站是不受HSTS保護的。這是因爲首次訪問時,瀏覽器還未收到HSTS,所以仍有可能通過明文HTTP來訪問。如果他們通過HTTP訪問HSTS保護的網站時:

以前從未訪問過該網站
最近重新安裝了其操作系統
最近重新安裝了其瀏覽器
切換到新的瀏覽器
切換到一個新的設備如移動電話
刪除瀏覽器的緩存
最近沒訪問過該站並且max-age過期了
解決這個不足目前有兩種方案

一是瀏覽器預置HSTS域名列表,Google Chrome、Firefox、Internet Explorer和Spartan實現了這一方案。google堅持維護了一個“HSTS preload list”的站點域名和子域名,並通過https://hstspreload.appspot.com/提交其域名。該域名列表被分發和硬編碼到主流的web瀏覽器。客戶端訪問此列表中的域名將主動的使用HTTPS,並拒絕使用HTTP訪問該站點。
一旦設置了STS頭部或者提交了你的域名到HSTS預加載列表,這是不可能將其刪除的。這是一個單向的決定使你的域名通過HTTPS可用的。

二是將HSTS信息加入到域名系統記錄中。但這需要保證DNS的安全性,也就是需要部署域名系統安全擴展。截至2014年這一方案沒有大規模部署。

由於HSTS會在一定時間後失效(有效期由max-age指定),所以瀏覽器是否強制HSTS策略取決於當前系統時間。部分操作系統經常通過網絡時間協議更新系統時間,如Ubuntu每次連接網絡時,OS X Lion每隔9分鐘會自動連接時間服務器。攻擊者可以通過僞造NTP信息,設置錯誤時間來繞過HSTS。解決方法是認證NTP信息,或者禁止NTP大幅度增減時間。比如Windows 8每7天更新一次時間,並且要求每次NTP設置的時間與當前時間不得超過15小時。
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章