HTTPS 站中的幾大難題 性能,包括: 其次,相容性及周邊,如: 如何解決 採用了統一接入層的架構,並配備管控平臺。這樣的設計解決了很多問題,比如證書分散且落地不安全、軟體版本難以維護、配置過多、難以標準和自動化、VIP 過多等; 以功能變數名稱收斂的方式減少建連; 採用 HSTS 技術去掉 80 到 4 ...
HTTPS 站中的幾大難題
性能,包括:
- HTTPS需要多次握手,因此網路耗時變長,用戶從HTTP跳轉到HTTPS需要一些時間;
- HTTPS要做RSA校驗,這會影響到設備性能;
- 所有CDN節點要支持HTTPS,而且需要有極其複雜的解決方案來面對DDoS的挑戰。
其次,相容性及周邊,如:
- 頁面里所有嵌入的資源都要改成HTTPS的,這些資源可能會來自不同的部門甚至不同的公司,包括圖片、視頻、表單等等,否則瀏覽器就會報警。
如何解決
- 採用了統一接入層的架構,並配備管控平臺。這樣的設計解決了很多問題,比如證書分散且落地不安全、軟體版本難以維護、配置過多、難以標準和自動化、VIP 過多等;
- 以功能變數名稱收斂的方式減少建連;
- 採用 HSTS 技術去掉 80 到 443 的 302 跳轉;
- 通過 Session 復用來提高建連速度和降低伺服器壓力;
- 對證書鏈進行優化以減少證書的傳輸量;
- 摒棄傳統的 RSA 演算法,轉而使用了最新的 ECDH 密鑰交換演算法,極大地提升了服務端的性能。
關註安全與相容性
- 採用了雙證書模式,即SHA-1和SHA-256,最大限度地保證安全和相容性;
- 使用的是相容性最寬泛的 OV 證書,全面支持單功能變數名稱、多功能變數名稱和泛功能變數名稱,滿足多種瀏覽器訪問,保證最好的用戶體驗,當然代價也是費用較為昂貴;
- 引入泛功能變數名稱 SAN 證書。
其次是一篇關於 Nginx 中 SSL 性能優化的文章《Nginx SSL 性能優化》。
密鑰交換演算法
常見的密鑰交換演算法有 RSA,ECDHE,DH,DHE 等演算法。它們的特性如下:
- RSA:演算法實現簡單,誕生於 1977 年,歷史悠久,經過了長時間的破解測試,安全性高。缺點就是需要比較大的素數(目前常用的是 2048 位)來保證安全強度,很消耗 CPU 運算資源。RSA 是目前唯一一個既能用於密鑰交換又能用於證書簽名的演算法。
- DH:diffie-hellman 密鑰交換演算法,誕生時間比較早(1977 年),但是 1999 年才公開。缺點是比較消耗 CPU 性能。
- ECDHE:使用橢圓曲線(ECC)的 DH 演算法,優點是能用較小的素數(256 位)實現 RSA 相同的安全等級。缺點是演算法實現複雜,用於密鑰交換的歷史不長,沒有經過長時間的安全攻擊測試。
- ECDH:不支持 PFS,安全性低,同時無法實現 false start。
- DHE:不支持 ECC。非常消耗 CPU 資源 。
建議優先支持 RSA 和 ECDH_RSA 密鑰交換演算法。原因是:
- ECDHE 支持 ECC 加速,計算速度更快。支持 PFS,更加安全。支持 false start,用戶訪問速度更快。
- 目前還有至少 20% 以上的客戶端不支持 ECDHE,我們推薦使用 RSA 而不是 DH 或者 DHE,因為 DH 系列演算法非常消耗 CPU(相當於要做兩次 RSA 計算)。
更改其配置如下(參照 Nginx Performance Tuning for SSL( http://dojo.techsamurais.com/?p=1384 ):
1 2 3 4 5 |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
|
或者
1 |
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-RC4-SHA:!ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-RSA-AES256-SHA:!RC4-SHA:HIGH:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!CBC:!EDH:!kEDH:!PSK:!SRP:!kECDH;
|
(禁用了RC4,sha1,MD5等演算法)
輔助加速
啟用SPDY
SPDY 是 Google 推出的優化 HTTP 傳輸效率的協議( https://www.chromium.org/spdy ), 它基本上沿用了 HTTP 協議的語義, 但是通過使用幀控制實現了多個特性,顯著提升了 HTTP 協議的傳輸效率。
SPDY 最大的特性就是多路復用,能將多個 HTTP 請求在同一個連接上一起發出去,不像目前的 HTTP 協議一樣,只能串列地逐個發送請求。
可以在編譯Nginx帶上參數 –with-http_spdy_module 支持 SPDY 協議,然後可在配置中啟用:
1 |
listen 443 ssl spdy;
|
檢測是否使用SPDY的網址( https://spdycheck.org/ )
HSTS
HSTS(HTTP Strict Transport Security)。服務端返回一個 HSTS 的 http header,瀏覽器獲取到 HSTS 頭部之後,在一段時間內,不管用戶輸入 www.baidu.com 還是 http://www.baidu.com ,都會預設將請求內部跳轉成 https://www.baidu.com;
將下述行添加到你的 HTTPS 配置的 server 塊中:
1 |
add_header Strict-Transport-Security "max-age=31536000";
|
Session cache
Session cache 的原理是使用 client hello 中的 session id 查詢服務端的 session cache, 如果服務端有對應的緩存,則直接使用已有的 session 信息提前完成握手,稱為簡化握手。
Session cache 有兩個缺點:
- 需要消耗服務端記憶體來存儲 session 內容。
- 目前的開源軟體包括 nginx,apache 只支持單機多進程間共用緩存,不支持多機間分散式緩存,對於百度或者其他大型互聯網公司而言,單機 session cache 幾乎沒有作用。
Session cache 也有一個非常大的優點:session id 是 TLS 協議的標準欄位,市面上的瀏覽器全部都支持 session cache。
1 2 |
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 20m;
|
參照 Nginx 的官方文檔 1MB 記憶體大約可以存儲 4000 個 session,按例配置 20M 大約可以存儲 80000。根據需求合理設置。
Ocsp stapling
Ocsp 全稱線上證書狀態檢查協議 (rfc6960),用來向 CA 站點查詢證書狀態,比如是否撤銷。通常情況下,瀏覽器使用 OCSP 協議發起查詢請求,CA 返回證書狀態內容,然後瀏覽器接受證書是否可信的狀態。 將證書保存下來,瀏覽器請求時候直接通過自己的伺服器發送回去,防止驗證伺服器出問題,還能加快訪問速度。
查看OSCP驗證伺服器地址:
1 |
openssl x509 -in 1_test.qupeiyin.net_bundle.crt -text
|
在輸出的文字中找到 OCSP - URI: ,後面的 URL 就是 OSCP 的驗證伺服器地址。
請求 OSCP 證書
1 2 3 4 |
openssl ocsp -noverify \
-issuer /certificate-path/trustchain.crt \
-cert /certificate-path/trustchain.crt \
-url http://ocsp1.wosign.com/ca6/server1
|
不出意外會收到如下的結果
1 2 3 |
trustchain.crt: good
This Update: Oct 18 17:59:10 2014 GMT
Next Update: Oct 18 23:59:10 2014 GMT
|
如果出現 403 錯誤,那就需要在 Header 請求頭加上功能變數名稱參數如 -header “HOST” “ocsp2.globalsign.com” ,沒問題後就可以直接保存下來證書文件,完整的命令如下:
1 2 3 4 |
openssl
ocsp -noverify -issuer 1_root_bundle.crt
-cert 1_root_bundle.crt -url http://ocsp1.wosign.com/ca6/server1 -header "HOST"
"ocsp1.wosign.com" -text -respout ./stapling_file.ocsp
|
將保存下來的 stapling_file.ocsp 證書添加到 nginx 的配置中,如下,Nginx 中配置變成了這樣子:
1 2 3 4 |
ssl_stapling on;
ssl_stapling_verify on;
ssl_stapling_file /stapling_file.ocsp;
ssl_trusted_certificate /certificate-path/trustchain.crt;
|
這樣子重啟 Nginx 後就會生效,可以使用下麵的命令測試生效結果:
1 |
echo QUIT | openssl s_client -connect blog.alphatr.com:443 -status 2> /dev/null | grep -A 17 'OCSP response:' | grep -B 17 'Next Update'
|
看到 OCSP Response Status: successful 這樣的字樣就是成功了。
ocsp證書有效期很短,大概不到一個月,所以過段時間要更新 ocsp 證書,不然還是會驗證失敗。需要用腳本定時更新OCSP證書。
總結:(全部優化參數)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
ssl on;
ssl_certificate /data/www/ssl/ssl.crt;
ssl_certificate_key /data/www/ssl/ssl.key;
ssl_trusted_certificate /data/www/ssl/trustchain.crt;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=31536000";
resolver 223.5.5.5 223.6.6.6 valid=300s;
resolver_timeout 10s;
error_page 497 https://$host$request_uri;
|
參數詳解:
ssl on 開啟SSL
ssl_certificate 對應單張證書
ssl_certificate_key 對應私鑰
ssl_trusted_certificate 對應信任鏈(即Startcom SSL或者Positive SSL中需要附加到單張證書後面的那兩張證書,可以獨立出來)
ssl_protocols 支持的SSL協議標準(nginx預設參數為:ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;)
ssl_ciphers (nginx預設參數為:ssl_ciphers HIGH:!aNULL:!MD5;)
ssl_prefer_server_ciphers On; 指定伺服器密碼演算法在優先於客戶端密碼演算法時,使用SSLv3和TLS協議。
error_page 497 https://$host$request_uri; 通過497錯誤將http轉跳到https