HTTPS 在 HTTP 的基礎上增長了SSL/TLS加密,提供了更加安全的傳輸協議。儼然已經屬於各大網站的標配。有贊做爲一個 SaaS 平臺,涉及到用戶的商品,交易,支付等關鍵性流程。支持全站 HTTPS,提升網站安全是咱們的基礎保障。本文關注的事情包括: 瞭解 HTTPS 基礎原理,切換 HTTPS 須要切換的內容,如何監控和實際操做,以及遇到的一些難點。javascript
在原有 HTTP 握手的基礎上,增長了證書的驗證,進行了加密,這樣咱們傳輸數據就有安全的保證。解決的問題包括運營商劫持
、中間人攻擊
、釣魚網站
、提高SEO
等。具體流程以下:css
當你開始着手切換成 HTTPS 的工做時,首先你須要明確你要處理的內容有什麼? 通常來講你須要梳理如下內容:html
關於第1點,靜態資源基本會收斂於少數域名,服務也基本會由第三方 cdn 服務商提供。 對應的服務提供商處開啓 HTTPS 支持。前端
<link rel="stylesheet" href="${loadStaticContent(www/css/main.min.css)}">
<script type="text/javascript" src="${loadStaticContent(www/js/main.min.js)}"></script>
複製代碼
在早期全站加載靜態資源過程當中, 應該自定義前端模板方法去動態加載 js,css。 防止寫死域名狀況。後期在全站切 cdn 域名時,就能夠直接使用新的 HTTPS 域名,一刀切,修改模板方法引入域名和路徑。java
關於第2點,圖片來源通常分爲兩種,站內圖片和站外圖片。站內圖片,基本會使用第三方 cdn 服務。能夠統一開啓 HTTPS。而站外圖片通常的來源可能包括:開發寫死,對接第三方服務(相似淘寶導購),連接型圖片上傳未存儲到本身的服務。jquery
.loading {
background-image: image-cdn('/logo_loading.png');
}
複製代碼
假設使用了 sass 等工具,站內圖片能夠在 css 中引入 cdn 域名加載方法。統一替換。nginx
對於老的 HTTP 數據圖片數據,業務訪問可知的狀況下,須要跑腳本從新上傳。對於上傳圖片組件若傳入的是 HTTP 圖片,應該考慮從新上傳支持。web
關於第3點,主域及其次級域名,能夠經過統計 nginx 日誌上 HTTP 的流量(awk日誌)。獲取現有站點 HTTP 流量的 pv 訪問表。獲得須要HTTPS的域名的數量。確認切換 HTTPS 順序和工期,考慮因素包括:請求量的大小
、業務的輕重緩急
、業務切換 HTTPS 難度
、各域名功能
等方面。在肯定站點基本狀況後,須要和各業務方交流以上方面問題。得出各域名切換的時間節點。算法
關於第4點,第三方資源引入問題。後端
原則上第三方資源應該是 HTTPS 的,若是不是,咱們可能就須要存儲到本身的服務上或者經過服務端轉發。不然必然是 HTTPS 的環境下,引入 HTTP 的狀況
關於第5點,屬於業務範疇,前端走 api 方式的調用,返回值中針對頭像、展現圖片等圖片方式,若是通過模板層能夠考慮加模板方式統一替換成 HTTPS,直接拼裝成的字符串。能夠提供統一方法替換。
關於第6點 ,好比你有 api 等對外服務。早期開放了 HTTP 調用的口子,那麼很遺憾。咱們能作的事情是經過公告、郵件等方式告知第三方,咱們在特定時間後就不在支持 HTTP 服務,但願第三方支持 HTTPS 調用。或者若是安全性不重要的話,那麼就同時支持HTTP/HTTPS調用。蘋果 HTTPS 的公告 App Transport Security就是很好的例子,而實際上 app 內部仍是留了開啓 HTTP 請求的設置。
以上是須要咱們處理的大部份內容。在推動全站 HTTPS 問題以前,作好這步梳理準備。包括了調研
、確認切換範圍
、瞭解業務切換難易程度
、肯定工做的時間安排和參與人員
。注:各部分工做設定好 deadline,會對你有很是大的幫助。
站內 HTTPS 資源準備完畢後,就能夠考慮將各站點切換成HTTPS。操做層面須要注意如下幾點:
代碼層面對明顯寫死的 HTTP 協議進行修改。修改爲相對協議
是不錯的選擇
<img src="//domain.com/img/logo.png">
<script src="//www/js/libs/jquery/1.4.2/jquery.js"></script>
複製代碼
相對協議下,當你訪問 HTTPS 網站時,請求 HTTPS 資源。不然 HTTP。這樣方案上更具備靈活性,能夠考慮內網先進行 HTTPS 的測試,對外網使用 HTTP。 假設 HTTPS 方案出現問題時,可退回到 HTTP。
當頁面全部資源都切換成 HTTPS,迴歸測試後。可考慮 HTTP 訪問網站時, nginx 302
重定向到 HTTPS。強制切換。上線後可通過幾天到一週的觀察。(流量大和複雜業務須要更久)業務穩定, 無異常及用戶反饋狀況。能夠強制301
切換。
302和301的區別就在於:302重定向是臨時的,下次瀏覽器訪問一樣是訪問原連接。而301重定向是持久的。下次瀏覽器會直接訪問新連接。因此當肯定某域名下已經實現了 HTTPS,可採用301重定向。
當某站點已經切換成了 HTTPS 。假設後期仍是有開發人員引入 HTTP 的狀況。咱們應該採用哪一種 CSP 策略防止呢?
block-all-mixed-content
, 強制阻止頁面內HTTP加載
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
複製代碼
可是實際上,阻止 HTTP 加載不是咱們的目的,後期開發中 引入 HTTP 的行爲多是疏漏形成的,咱們能夠理解成實際上資源已經能夠支持 HTTPS 的。 因此能夠採用另外一種CSP策略: upgrade-insecure-requests
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
複製代碼
該策略下會產生如下兩種效果
這種策略顯然更加友好。當網站已經確認強制使用了 HTTPS,就能夠加入該方法。
從測試便利性角度,測試環境能夠提供 Http。但實際上爲了和正式環境一致應該用 HTTPS 測試更合理。由於上述推薦使用相對協議,因此測試環境自己是能夠提供 Http/HTTPS 兩種方案的。
全站 HTTPS 因爲域名和業務等因素影響,切換過程當中必然會遇到許多難點。 主要表如今業務方來源和用戶訪問來源:
referer
,referer 對於前端定位流量來源可以提供很是大的幫助。可是有一些頁面的 Http 訪問不存在 referer,這種狀況可能因爲用戶保存該頁面連接或者從其餘來源進入網站頁面丟失等形成。假設頁面通過 HTTPS 測試經過,能夠經過強制切換成 HTTPS 解決。除了以上的幾個顯性難點外,其實還有些隱性難點,好比須要與業務方約定明確強制切換的 deadline,接口升級、服務改造遷移、老接口複雜性等各類問題都會拖延各實施方的進度。只有強制的 deadline 切換才保住全站 HTTPS 的推動進度。
寫在最後,本文主要是圍繞推進公司全站 HTTPS 的一些心得。更多的是以一個項目推進方的角度考慮如何推進事情的落地。原理,內容,執行,難點。這幾個核心流程把握住。咱們才能作到更加有條理的實施。同時全站流量切換成 HTTPS,其實只是工做的開始。以後的 HTTPS 性能優化、異常 HTTP 流量監控、HTTPS 可用性監控等都是接下來應該去不斷推動的工做。
本文首發於有贊技術博客。