隨著大家上網安全意識的增強,以及各大主要網路公司對Https普及工作的推動,HTTPS SSL現在基本上成了建站的標配了。得益於Let’s Encrypt、Digicert、TrustAsia、Symantec等提供的免費SSL證書,現在不管是個人建站還是企業建站,上Https的成本可以忽略不計了。

為了安全,我們要上Https,但開啟 SSL 會增加記憶體、CPU、網路頻寬的開銷。相對於http,使用TCP 三次握手建立連接,客戶端和伺服器需要交換3個包,https除了 TCP 的三個包,還要加上 ssl握手需要的9個包,一共是12個包。所以,HTTPS優化得不少反而容易出現效能慢的問題。

當然,有人可能為會認為HTTPS與SS​​L增加的伺服器開銷基本上沒有感覺到,這是因為網站的流量比較少,加上伺服器的效能配置足以支撐起當前的流量。但對於大型的網站,例如百度、Google以及熱門APP,優化Https效能,減少資源消耗還是非常有用的。

八個HTTPS和SSL優化使用心得-減少等待時間降低Https性能損耗加大SSL緩存

本篇文章就來分享HTTPS和SSL優化使用幾點心得體會,更多的有關於SSL憑證和Https經驗教學還有:

  1. 免費SSL憑證收集整理匯總-免費給網站添加Https安全加密訪問
  2. 十個你可能不知道的CloudFlare免費CDN加速技巧-SSLDDOSCache
  3. 啟用HSTS並加入HSTS Preload List讓網站Https存取更加安全-附刪除HSTS方法

PS:2018年9月6日更新,如果想要使用付費的DNS解析服務,這裡有兩個比較便宜的比較適合個人的DNS服務:兩款適合個人使用的DNS產品:ClouDNS和DNS Made Easy域名解析。

PS:2019年1月15日更新,想要SSL訪問獲得更快的速度以及更高的性能,可以試試TLSV1.3和Brotli壓縮:網站優化加速-開啟TLSV1.3和Brotli壓縮-Oneinstack,LNMP,寶塔面板。

一、如何選擇免費SSL憑證?

建議選擇Let’s Encrypt。 Let’s Encrypt免費SSL憑證雖然只有90天,但是可以無限期續期,並且支援手動和自動續期。 Let’s Encrypt SSL在各大瀏覽器上都得到認可,是免費SSL憑證的首選。教學:Let’s Encrypt Wildcard 免費泛域名SSL憑證一鍵申請與SSL使用教學。

Let’s Encrypt適用於VPS等有獨立IP的主機上,否則只能使用一些利用Let’s Encrypt API開發的線上SSL憑證申請。當然,有一定的經濟實力的話自然選擇付費的SSL證書更為可行,更多SSL證書見:免費SSL證書收集整理匯總。

二、伺服器開啟HSTS

採用 HSTS 協議的網站將保證瀏覽器始終連接到網站的HTTPS版本,而不需要使用者手動在URL網址列中輸入包含https://的加密位址。我用的是Nginx 伺服器,只需要編輯 Nginx 設定檔(如:/usr/local/nginx/conf/nginx.conf)將下面行新增到 HTTPS 設定的 server 區塊中即可:

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

Apache、Lighttpd等啟用HSTS詳細的方法請見:伺服器啟用HSTS。

三、網域加入HSTS preload list計劃

上面雖然是啟用了HSTS 協議保證了用戶訪問的始終是Https連接,但是一般地首次訪問網站用戶都會習慣性地輸入非https域名,這就導致了第一次訪問網站容易出現http劫持的問題。 HSTS preload list計畫就是為了解決這個問題的,它是chromeFirefoxEdge等瀏覽器內建的清單。

加入HSTS Preload List的方法:啟用HSTS並加入HSTS Preload List讓網站Https存取更加安全-附刪除HSTS方法。目前wzfou.com已經成功加入了HSTS preload list,如果你用的是Chrome或Firefox,第一次造訪本站就是預設用Https連線的。

Nginx 中開啟 OCSP Stapling。 (如果 ssl_certificate 指令指定了完整的憑證鏈,則 ssl_trusted_certificate 可省略)

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/certs/chained.pem;

Apache 中開啟 OCSP Stapling

<VirtualHost></VirtualHost> 中加入:

SSLUseStapling on

<VirtualHost></VirtualHost> 外加入:

SSLStaplingCache shmcb:/tmp/stapling_cache(128000)

五、使用ECC和RSA雙證書

預設的我們都會使用RSA證書,因為RSA證書的相容性最為廣泛。但ECC 憑證擁有體積小、運算速度快、安全性高(256位元ECC key就能起到相當於3072位的RSA key的安全性)等特點,可以在一定程度上提供Https性能。

Let’s Encrypt已經支援生成ECC 證書了,使用 acme.sh 簽發SSL證書, 指定 --keylength ec-256 就可以將證書類型改為 ECC:

acme.sh --issue -w /data/wwwroot/wzfou.com -d wzfou.com -d www.wzfou.com --keylength ec-256

要注意的是ECC在Windows XP上不相容,這時候我們就會想到用雙憑證了,也就是不支援ECC憑證時Nginx自動將RSA憑證展示給使用者。如果nginx 的版本大於1.11,直接就可以在設定檔中寫上ECC和RSA雙憑證的路徑了,wzfou.com示範如下:

#ECC
ssl_certificate /root/.acme.sh/wzfou.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/wzfou.com_ecc/wzfou.com.key;
#RSA
ssl_certificate /usr/local/nginx/conf/ssl/wzfou.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/wzfou.com.key;

重啟Nginx,當XP等不支援ECC憑證的使用者造訪網站時,顯示的是RSA憑證。

而其它的使用者則優先使用ECC憑證。

如果你發現ECC沒有優先顯示,檢查一下ssl_prefer_server_ciphers是否開啟,同時ssl_ciphers有沒有配置好,以下是wzfou.com當用的設定:

ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;

另外,以下三個任選其一即可(僅供測試):

ssl_ciphers 'EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5';

ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';

六、 開啟DNS CAA

DNS CAA的作用是只允許在記錄中列出的CA 機構頒發針對該網域(或子網域)的證書,以防止有人偽造SSL證書,同時CAA 記錄可以控制單網域SS L證書的發行,也可以控制通配符證書。詳細方法請見:京東雲DNS設定CAA。

問題:開啟DNS CAA導致錯誤:Verify error:CAA record for *.wzfou.comprevents issuance。解決的方法就是增加 issuewild 記錄: 0 issuewild "letsencrypt.org" 。 另外提供兩個檢測CAA配置是否正確的網站:

  1. HTTPS://CAA test.co.UK/
  2. HTTPS://大年三十好友.IO/labs/CAA-validator

七、定期自動更新SSL證書

想手動更新方法:

# RSA
$ acme.sh --renew -d wzfou.com –d www.wzfou.com --force

# ECC
acme.sh --renew -d wzfou.com –d www.wzfou.com --force --ecc

一般地acme.sh已經自動添加了定時任務了,定期更新Let’s Encrypt證書,如果你發現沒有定期更新證書,檢查一下你的Cron任務是否正確,也可以試試強制更新:

"/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" --force

八、檢測SSL憑證配置

常用的檢測網站有:

  1. HTTPS://嗚嗚嗚.SSL labs.com/SSL test/analyze.HTML
  2. HTTPS://沒有殺傷力.com/

重點推薦用ssllabs.com,檢測的結果還是非常準確,如下:

九、綜合

綜合以上最佳化策略,Nginx的設定檔具體的最佳化如下:

server {

listen 443 ssl http2;
#使用HTTP/2,需要Nginx1.9.7以上版本

add_header Strict-Transport-Security "max-age=6307200; includeSubdomains; preload";
#开启HSTS,并设置有效期为“6307200秒”(6个月),包括子域名(根据情况可删掉),预加载到浏览器缓存(根据情况可删掉)

add_header X-Frame-Options DENY;
#禁止被嵌入框架

add_header X-Content-Type-Options nosniff;
#防止在IE9、Chrome和Safari中的MIME类型混淆攻击

ssl_certificate /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.key;
#SSL证书文件位置

ssl_trusted_certificate /usr/local/nginx/conf/vhost/sslkey/chaine.pem;
#OCSP Stapling的证书位置

ssl_dhparam /usr/local/nginx/conf/vhost/sslkey/dhparam.pem;
#DH-Key交换密钥文件位置

#SSL优化配置

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#只允许TLS协议

ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
#加密套件,这里用了CloudFlare's Internet facing SSL cipher configuration

ssl_prefer_server_ciphers on;
#由服务器协商最佳的加密算法

ssl_session_cache builtin:1000 shared:SSL:10m;
#Session Cache,将Session缓存到服务器,这可能会占用更多的服务器资源

ssl_session_tickets on;
#开启浏览器的Session Ticket缓存

ssl_session_timeout 10m; 
#SSL session过期时间

ssl_stapling on; 
#OCSP Stapling开启,OCSP是用于在线查询证书吊销情况的服务,使用OCSP Stapling能将证书有效状态的信息缓存到服务器,提高TLS握手速度

ssl_stapling_verify on;
#OCSP Stapling验证开启

resolver 8.8.8.8 8.8.4.4 valid=300s;
#用于查询OCSP服务器的DNS

resolver_timeout 5s;
#查询域名超时时间

···

}

實際使用過程中發現個別的「最佳化」還得根據自身的需要來確定,以下是wzfou.com正在用的Nginx配置,僅供參考:

listen 80; 
listen 443 ssl http2;
#ECC
ssl_certificate /root/.acme.sh/wzfou.com_ecc/fullchain.cer;
ssl_certificate_key /root/.acme.sh/wzfou.com_ecc/wzfou.com.key;  
#RSA 
ssl_certificate /usr/local/nginx/conf/ssl/wzfou.com.crt;
ssl_certificate_key /usr/local/nginx/conf/ssl/wzfou.com.key; 
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+ECDSA+AES128:EECDH+aRSA+AES128:RSA+AES128:EECDH+ECDSA+AES256:EECDH+aRSA+AES256:RSA+AES256:EECDH+ECDSA+3DES:EECDH+aRSA+3DES:RSA+3DES:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_buffer_size 1400;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
ssl_stapling on; 
ssl_stapling_verify on;

PS:2018年8月5日更新,感謝xiaoz的提醒,這裡有一個線上產生SSL配置的網站,出自Mozilla,參考性非常高:

  1. HTTPS://Mozilla.GitHub.IO/server-死的-托雷斯/收視率-config-generator/

發表評論