基于 Nginx 的 HTTPS 性能优化实践
前言
分享一個(gè)卓見云的較多客戶遇到HTTPS優(yōu)化案例。
隨著相關(guān)瀏覽器對HTTP協(xié)議的“不安全”、紅色頁面警告等嚴(yán)格措施的出臺,以及向 iOS 應(yīng)用的 ATS 要求和微信、支付寶小程序強(qiáng)制 HTTPS 需求,以及在合規(guī)方面如等級保護(hù)對傳輸安全性的要求都在推動 HTTPS 的發(fā)展。
雖然 HTTPS 優(yōu)化了網(wǎng)站訪問體驗(yàn)(防劫持)以及讓傳輸更加安全,但是很多網(wǎng)站主趕鴨子上架式的使用了 HTTPS 后往往都會遇到諸如:頁面加載速度變慢、服務(wù)器負(fù)載過高以及證書過期不及時(shí)更新等問題。
所以本文就來探討一下 HTTPS 的優(yōu)化實(shí)踐。
選型
其實(shí)像 Apache Httpd、LigHttpd、Canddy 等 Web 服務(wù)軟件都可以設(shè)置 HTTPS,但是在相應(yīng)的擴(kuò)展生態(tài)和更新率上都不如 Nginx。 Nginx 作為大型互聯(lián)網(wǎng)網(wǎng)站的 Web 入口軟件有著廣泛的支持率,例如阿里系的 Tengine、CloudFlare 的 cloudflare-nginx、又拍云用的 OpenResty 都是基于 Nginx 而來的,Nginx 是接受過大規(guī)模訪問驗(yàn)證的。同時(shí)大家也將自己開發(fā)的組件回饋給 Nginx 社區(qū),讓 Nginx 有著非常良好的擴(kuò)展生態(tài)。
? 圖1-1 Nginx 在全網(wǎng)的使用情況
所以說 Nginx 是一款很好的 Web 服務(wù)軟件,選擇 Nginx 在提升性能的同時(shí)能極大的降低我們的擴(kuò)展成本。
新功能
圍繞 Web 服務(wù)已經(jīng)有非常多的新功能需要我們關(guān)注并應(yīng)用了,這里先羅列相關(guān)新功能。
HTTP/2
相比廉頗老矣的 HTTP/1.x,HTTP/2 在底層傳輸做了很大的改動和優(yōu)化包括有:
在 Akamai 的 HTTP/2 DEMO中,加載300張圖片,HTTP/2 的優(yōu)越性極大的顯現(xiàn)了出來,在 HTTP/1.X 需要 14.8s 的操作中,HTTP/2 僅需不到1s。
HTTP/2 現(xiàn)在已經(jīng)獲得了絕大多數(shù)的現(xiàn)代瀏覽器的支持。只要我們保證 Nginx 版本大于 1.9.5 即可。當(dāng)然建議保持最新的 Nginx 穩(wěn)定版本以便更新相關(guān)補(bǔ)丁。同時(shí) HTTP/2 在現(xiàn)代瀏覽器的支持上還需要 OpenSSL 版本大于 1.0.2。
TLS 1.3
和 HTTP/1.x 一樣,目前受到主流支持的 TLS 協(xié)議版本是 1.1 和 1.2,分別發(fā)布于 2006年和2008年,也都已經(jīng)落后于時(shí)代的需求了。在2018年8月份,IETF終于宣布TLS 1.3規(guī)范正式發(fā)布了,標(biāo)準(zhǔn)規(guī)范(Standards Track)定義在 rfc8446。
TLS 1.3 相較之前版本的優(yōu)化內(nèi)容有:
總結(jié)一下就是在更安全的基礎(chǔ)上還做到了更快,目前 TLS 1.3 的重要實(shí)現(xiàn)是 OpenSSL 1.1.1 開始支持了,并且 1.1.1 還是一個(gè) LTS 版本,未來的 RHEL8、Debian10 都將其作為主要支持版本。在 Nginx 上的實(shí)現(xiàn)需要 Nginx 1.13+。
Brotli
Brotli 是由 Google 于 2015 年 9 月推出的無損壓縮算法,它通過用變種的 LZ77 算法,Huffman 編碼和二階文本建模進(jìn)行數(shù)據(jù)壓縮,是一種壓縮比很高的壓縮方法。
根據(jù)Google 發(fā)布的研究報(bào)告,Brotli 具有如下特點(diǎn):
在兼容 GZIP 的同時(shí),相較 GZIP:
Brotli 的支持必須依賴 HTTPS,不過換句話說就是只有在 HTTPS 下才能實(shí)現(xiàn) Brotli。
ECC 證書
橢圓曲線密碼學(xué)(Elliptic curve cryptography,縮寫為ECC),一種建立公開金鑰加密的算法,基于橢圓曲線數(shù)學(xué)。橢圓曲線在密碼學(xué)中的使用是在1985年由Neal Koblitz和Victor Miller分別獨(dú)立提出的。
內(nèi)置 ECDSA 公鑰的證書一般被稱之為 ECC 證書,內(nèi)置 RSA 公鑰的證書就是 RSA 證書。由于 256 位 ECC Key 在安全性上等同于 3072 位 RSA Key,加上 ECC 運(yùn)算速度更快,ECDHE 密鑰交換 + ECDSA 數(shù)字簽名無疑是最好的選擇。由于同等安全條件下,ECC 算法所需的 Key 更短,所以 ECC 證書文件體積比 RSA 證書要小一些。
ECC 證書不僅僅可以用于 HTTPS 場景當(dāng)中,理論上可以代替所有 RSA 證書的應(yīng)用場景,如 SSH 密鑰登陸、SMTP 的 TLS 發(fā)件等。
不過使用 ECC 證書有兩個(gè)點(diǎn)需要注意:
一、 并不是每一個(gè)證書類型都支持的,一般商業(yè)證書中帶增強(qiáng)型字眼的才支持ECC證書的簽發(fā)。
二、 ECC證書在一些場景中可能還不被支持,因?yàn)橐恍┊a(chǎn)品或者軟件可能還不支持 ECC。 這時(shí)候就要虛線解決問題了,例如針對部分舊操作系統(tǒng)和瀏覽器不支持ECC,可以通過ECC+RSA雙證書模式來解決問題。
安裝
下載源碼
綜合上述我們要用到的新特性,我們整合一下需求:
HTTP/2 要求 Nginx 1.9.5+,,OpenSSL 1.0.2+
TLS 1.3 要求 Nginx 1.13+,OpenSSL 1.1.1+
Brotli 要求 HTTPS,并在 Nginx 中添加擴(kuò)展支持
ECC 雙證書 要求 Nginx 1.11+
這里 Nginx,我個(gè)人推薦 1.15+,因?yàn)?1.14 雖然已經(jīng)能支持TLS1.3了,但是一些 TLS1.3 的進(jìn)階特性還只在 1.15+ 中提供。
然后我們定義一下版本號:
# Version OpenSSLVersion='openssl-1.1.1a'; nginxVersion='nginx-1.14.1';建議去官網(wǎng)隨時(shí)關(guān)注最新版:
http://nginx.org/en/download.html
https://www.openssl.org/source/
https://github.com/eustas/ngx_brotli/releases
Nginx
cd /opt wget http://nginx.org/download/$nginxVersion.tar.gz tar xzf $nginxVersion.tar.gzOpenSSL
cd /opt wget https://www.openssl.org/source/$OpenSSLVersion.tar.gz tar xzf $OpenSSLVersion.tar.gzBrotli
cd /opt git clone https://github.com/eustas/ngx_brotli.git cd ngx_brotli git submodule update --init --recursive編譯
cd /opt/$nginxVersion/ ./configure \ --prefix=/usr/local/nginx \ ## 編譯后安裝的目錄位置 --with-openssl=/opt/$OpenSSLVersion \ ## 指定單獨(dú)編譯入 OpenSSL 的源碼位置 --with-openssl-opt=enable-tls1_3 \ ## 開啟 TLS 1.3 支持 --with-http_v2_module \ ## 開啟 HTTP/2 --with-http_ssl_module \ ## 開啟 HTTPS 支持 --with-http_gzip_static_module \ ## 開啟 GZip 壓縮 --add-module=/opt/ngx_brotli ## 編譯入 ngx_BroTli 擴(kuò)展make && make install ## 編譯并安裝后續(xù)還有相關(guān)變量設(shè)置和設(shè)置服務(wù)、開啟啟動等步驟,篇幅限制就省略了,這篇文章有介紹在 Ubuntu 下的 Nginx 編譯:https://www.mf8.biz/ubuntu-nginx/ 。
配置
接下來我們需要修改配置文件。
HTTP2
listen 443 ssl http2;只要在 server{} 下的lisen 443 ssl 后添加 http2 即可。而且從 1.15 開始,只要寫了這一句話就不需要再寫 ssl on 了,很多小伙伴可能用了 1.15+ 以后衍用原配置文件會報(bào)錯(cuò),就是因?yàn)檫@一點(diǎn)。
TLS 1.3
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;如果不打算繼續(xù)支持 IE8,或者一些合規(guī)的要求,可以去掉TLSv1。
然后我們再修改對應(yīng)的加密算法,加入TLS1.3引入的新算法:
ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256: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;如果不打算繼續(xù)支持 IE8,可以去掉包含 3DES 的 Cipher Suite。
默認(rèn)情況下 Nginx 因?yàn)榘踩?#xff0c;沒有開啟 TLS 1.3 0-RTT,可以通過添加 ssl_early_data on; 指令開啟 0-RTT的支持。
————
實(shí)驗(yàn)性嘗試
眾所周知,TLS1.3 由于更新了很久,很多瀏覽器的舊版本依舊只支持 Draft 版本,如 23 26 28 分別在 Chrome、FirFox 上有支持,反而正式版由于草案出來很久,導(dǎo)致TLS1.3在瀏覽器上兼容性不少太好。
可以使用 https://github.com/hakasenyang/openssl-patch/ 提供的 OpenSSL Patch 讓 OpenSSL 1.1.1 同時(shí)支持草案23,26,28和正式版輸出。 不過由于不是官方腳本,穩(wěn)定性和安全性有待考量。
ECC雙證書
雙證書配置的很簡單了,保證域名的證書有RSA和ECC各一份即可。
##證書部分ssl_certificate /usr/local/nginx/conf/ssl/www.mf8.biz-ecc.crt; #ECC證書ssl_certificate_key /usr/local/nginx/conf/ssl/www.mf8.biz-ecc.key; #ECC密鑰ssl_certificate /usr/local/nginx/conf/ssl/www.mf8.biz.crt; #RSA證書ssl_certificate_key /usr/local/nginx/conf/ssl/www.mf8.biz.key; #RSA密鑰Brotli
需要在對應(yīng)配置文件中,添加下面代碼即可:
brotli on;brotli_comp_level 6;brotli_min_length 1k;brotli_types text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/x-javascript application/xml application/xhtml+xml application/rss+xml application/atom+xml application/x-font-ttf application/vnd.ms-fontobject image/svg+xml image/x-icon font/opentype;為了防止大家看糊涂了,放一個(gè)完整的 server{}供大家參考:
server {listen 443 ssl http2; # 開啟 http/2server_name mf8.biz www.mf8.biz;#證書部分ssl_certificate /usr/local/nginx/conf/ssl/www.mf8.biz-ecc.crt; #ECC證書ssl_certificate_key /usr/local/nginx/conf/ssl/www.mf8.biz-ecc.key; #ECC密鑰ssl_certificate /usr/local/nginx/conf/ssl/www.mf8.biz.crt; #RSA證書sl_certificate_key /usr/local/nginx/conf/ssl/www.mf8.biz.key; #RSA密鑰#TLS 握手優(yōu)化ssl_session_cache shared:SSL:1m;ssl_session_timeout 5m;keepalive_timeout 75s;keepalive_requests 100;#TLS 版本控制ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;ssl_ciphers 'TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256: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';# 開啟 1.3 o-RTTssl_early_data on;# GZip 和 Brotligzip on;gzip_comp_level 6;gzip_min_length 1k;gzip_types text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/x-javascript application/xml application/xhtml+xml application/rss+xml application/atom+xml application/x-font-ttf application/vnd.ms-fontobject image/svg+xml image/x-icon font/opentype;brotli on;brotli_comp_level 6;brotli_min_length 1k;brotli_types text/plain text/css text/xml text/javascript text/x-component application/json application/javascript application/x-javascript application/xml application/xhtml+xml application/rss+xml application/atom+xml application/x-font-ttf application/vnd.ms-fontobject image/svg+xml image/x-icon font/opentype;location / {root html;index index.html index.htm;}}先驗(yàn)證一下配置文件是否有誤:
nginx -t如果反饋的是:
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful就可以重啟 Nginx ,然后到對應(yīng)網(wǎng)站中去查看效果了。
驗(yàn)證
HTTP/2
通過瀏覽器的開發(fā)者工具,我們可以在 Network 欄目中看到 Protocol 中顯示 h2 有無來判斷。
TLS 1.3
老地方,我們可以通過瀏覽器的開發(fā)者工具 中的 Security 欄目看到 Connection 欄目下是否有顯示 TLS 1.3
ECC 雙證書
ECC 雙證書配置了以后無非就是在舊瀏覽器設(shè)別上的驗(yàn)證了。這里用足夠老的上古XP虛擬機(jī)來給大家證明一波。
XP系統(tǒng)上:
現(xiàn)代操作系統(tǒng)上的:
Brotli
通過瀏覽器的開發(fā)者工具,我們可以在 Network 欄目中,打開具體頁面的頭信息,看到 accept-encoding 中有 br 字眼就行。
總結(jié)
通過上述手段應(yīng)該可以讓 HTTPS 訪問的體驗(yàn)優(yōu)化不少,而且會比沒做 HTTPS 的網(wǎng)站訪問可能更快。
這樣的模式比較適合云服務(wù)器單機(jī)或者簡單集群上搭建,如果有應(yīng)用 SLB 七層代理、WAF、CDN 這樣的產(chǎn)品可能會讓我們的這些操作都白費(fèi)。 我們的這幾項(xiàng)操作都是自建的 Web 七層服務(wù),如果有設(shè)置 SLB 七層代理、WAF、CDN 這樣設(shè)置在云服務(wù)器之前就會被覆蓋掉。
由于 SLB 七層和CDN這樣的產(chǎn)品會更加追求廣泛的兼容性和穩(wěn)定性并不會第一時(shí)間就用上上述的這些新特性(HTTP/2 是普遍有的),但是他們都配備了阿里云的 Tengine 的外部專用算法加速硬件如 Intel? QuickAssist Technology(QAT) 加速器可以顯著提高SSL/TLS握手階段性能。 所有 HTTPS 的加密解密都在 SLB 或 CDN 上完成,而不會落到ECS上,可以顯著降低 ECS 的負(fù)載壓力,并且提升訪問體驗(yàn)。
目前云上的網(wǎng)絡(luò)產(chǎn)品中能支持四層的都是可以繼續(xù)兼容我們這套設(shè)計(jì)的,例如:SLB 的四層轉(zhuǎn)發(fā)(TCP UDP)、DDOS高防的四層轉(zhuǎn)發(fā)。
也歡迎大家有問題來找卓見云,聊騷也可以呀~。 我的釘釘號:huicute , 以及我的博客:https://www.mf8.biz
總結(jié)
以上是生活随笔為你收集整理的基于 Nginx 的 HTTPS 性能优化实践的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 量子计算机到底多强大?从量子运算看清楚它
- 下一篇: promehteus 监控超时_05 .