HSTS VS 301 redirect

以前基於nginx爲網站配置了HTTPS服務,配置過程當中涉及到兩個知識點:php

  • 301 永久重定向
  • HTST(HTTP Transport Security Protocol)

本文主要是經過梳理一下相關概念,理清這兩種配置的目的。html

HTTPS

HTTPS,也稱做HTTP over TLS,TLS的前身是SSL。HTTPS 相比 HTTP 提供了數據完整性、 數據隱私性和身份認證的功能。nginx

SSL通訊過程 web

  • 客戶端發起一個HTTPS請求,提供客戶端支持的加密算法和一個客戶端隨機數 client_random 給服務器
  • 服務器返回給客戶端配置好公鑰的證書和服務器隨機數 server_random
  • 客戶端驗證公鑰證書、好比是否在有效期內、域名是否匹配等;若是證書有效,客戶端使用服務器提供的公鑰加密加密隨機數 premaster secret,發送給服務器
  • 服務器使用本身的私鑰解密 premaster secret
  • 客戶端和服務器將前面階段的三個隨機數,使用協商好的算法進行加密生成 master secret,後面雙方通訊使用這個對稱密鑰進行加密;

在nginx中的配置方法算法

  • 申請證書
  • 在nginx.conf中配置
    server {
        listen 443;
        server_name www.example.com; #填寫綁定證書的域名
        ssl on;
        ssl_certificate /etc/nginx/sslconfig/1_www.example.com_bundle.crt;
        ssl_certificate_key /etc/nginx/sslconfig/2_www.example.com.key;
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers on;
        location / {
            root   html; #站點目錄
            index  index.html index.htm;
            # proxy_pass http://$server_name:8920;
    }
    複製代碼

中間人攻擊(MitM)

中間人攻擊(Man-in-the-middle attack,縮寫:MITM)是指攻擊者與通信的兩端分別創建獨立的聯繫,並交換其所收到的數據,使通信的兩端認爲他們正在經過一個私密的鏈接與對方直接對話,但事實上整個會話都被攻擊者徹底控制並進行數據篡改和嗅探。瀏覽器

  • 代理服務器(mitmproxy):代理服務器 在HTTP和HTTPS通訊中擔任中間人的角色,在和客戶端通訊時它假裝成服務器,在和服務器通訊時假裝成客戶端,對兩邊的通訊內容進行解碼。代理服務器會生成僞造證書欺騙客戶端,要使客戶端信任僞造證書而不發出警告,須要在客戶端手動將代理服務器註冊爲受信任的 CA。
  • SSL剝離(SSLsplit):SSL剝離中,攻擊者 SSLStrip 也是擔任中間人的角色,中間人和服務器之間維持HTTPS鏈接,而和客戶端維持HTTP鏈接,也就是將 HTTPS 降級爲 HTTP。因爲 HTTP 是明文傳輸的,所以攻擊者能夠竊取通訊內容。
  • 會話劫持(Session Hijacking):攻擊者經過竊取或預測有效的會話令牌來破壞會話令牌,以得到對Web服務器的未受權訪問。經常使用的竊取Cookie/會話令牌的方法有會話嗅探和跨站點腳本攻擊等。
  • 防護:對於實際生活中的信件溝通和線上的信息交流來講,中間人攻擊都是很難防範的,一些小建議:
    • 不要忽視瀏覽器彈出的證書警告!你可能訪問的是釣魚網站或者假冒的服務器
    • 公共網絡環境下(例如公共WiFi),沒有HTTPS加密的敏感網站不要隨便登陸,通常不可信
    • 在任何網站上登陸本身的帳號前確保網址是走的HTTPS加密協議

HSTS

HSTS,即HTTP Strict-Transport-Security。 當站點經過 HTTPS 運行的時候,服務器經過返回一個響應頭部 Strict-Transport-Security ,強制瀏覽器之後使用 HTTPS 進行通訊。緩存

Strict-Transport-Security: max-age=<expire-time>
Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
Strict-Transport-Security: max-age=<expire-time>; preload
複製代碼

一個網站接受一個 HTTP 的請求,而後跳轉到 HTTPS ,用戶可能在開始跳轉前,經過沒有加密的方式和服務器對話,這樣存在中間人攻擊潛在威脅,跳轉過程可能被惡意網站利用來直接接觸用戶信息,而不是原來的加密信息。
HTST 是在初次經過訪問 HTTPS 鏈接並返回安全頭以後,瀏覽器記錄下這些信息。有效期內,當瀏覽器再次試圖經過 HTTP 與服務器創建鏈接只會返回307 Temporary Redirect ,瀏覽器禁止加載 HTTP 信息,並將鏈接重定向到 HTTPS 。一個測試的結果以下:安全

在nginx中配置響應信息bash

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
複製代碼

瀏覽器返回結果 服務器

307
200
注意 HTST 是經過 HTTPS 響應頭設置的,若是使用 HTTP 則會被忽略。一種解決的策略是 preload HTST。HSTS預加載是把你的網站和或域名放在一個被承認的hsts列表上,這個列表其實是內置在瀏覽器中的。Google提供了這個列表服務,並由Chrome、Firefox、Opera、Safari、IE11和Edge使用,能夠將你的站點提交到官方的HSTS預加載列表。

301 redirect

HTTP 301 永久重定向說明請求的資源已經被移動到了由 Location 頭部指定的url上,是固定的不會再改變,搜索引擎會根據該響應修正,在 SEO 中301跳轉對網站的權重會產生影響。
咱們注意到,咱們已經在nginx中已經配置了return 301 https://$server_name$request_uri,將HTTP請求重定向到HTTPS。可是,在前面的瀏覽器測試結果中,經過HTTP訪問並無顯示301永久重定向,而是307臨時重定向。實際上,301 仍然是發生的,301是服務器層面上的重定向,而307是瀏覽器層面上的重定向。咱們經過 httpstatus 進行測試,能夠看到直觀的結果:

咱們已經說明了HSTS和301的做用,可是咱們可能仍然有些困惑:

  • 爲何已經使用 301重定向,還要使用 HSTS ?
  • 爲何大多數網站使用301重定向,而不用預加載HSTS替代?

區別與聯繫

  • HSTS覆蓋域名,而301 redirect針對特定的URL Path;
  • HSTS設計的意義是爲了解決安全問題,而301更可能是爲了解決重定向問題,後來被普遍用在從 HTTP 升級到 HTTPS 的過程當中,並對網站搜索權重形成影響;
  • HSTS起做用是在至少訪問過一次HTTPS且證書驗證成功的狀況下,在安全性要求較高的狀況下咱們強制使用 HTTPS,這須要進行預加載或者強制重定向;若是攻擊者一直阻止網站創建HTTPS鏈接,HTST將不起做用;
  • 目前大多數網站使用HSTS時是結合301 redirect使用的而不是預加載,這多是出於兼容考慮;
  • HSTS相比301 redirect,在性能和安全上可能有一些優點。301緩存和其餘請求同樣都是保存在瀏覽器緩存中,重定向會消耗性能;而HSTS保留在另外一個單獨的緩存列表中,能夠保留更長時間而不被瀏覽器清除;
  • 中間人攻擊可能利用重定向的時機進行介入,而HSTS 能夠有效應對SSL剝離(HTTPS降級)致使的安全問題,可是對於其餘類型的中間人攻擊可能不起做用。
  • HSTS 常和 HPKP(HTTP Public Key Pinning) 結合使用, HPKP 容許 HTTPS 網站指定其信任的證書,並指示瀏覽器不容許任何鏈接到由任何其餘證書保護的站點。

總之,中間人攻擊不可能簡單地經過某一種策略來徹底阻止,可是聊勝於無,HSTS 仍然是個可行的安全策略。


參考了一些博客和討論,若有錯誤歡迎指正。

參考資料

相關文章
相關標籤/搜索