國慶節前端技術棧充實計劃(1):使用Nginx配置HTTPS 伺服器
目錄
HTTPS 伺服器優化
SSL 證書鏈
單個 HTTP/HTTPS 虛擬主機
基於名稱的 HTTPS 伺服器
包含多域名的SSL證書
伺服器名稱指示
兼容性列表
要配置HTTPS NGINX 伺服器,必須在配置文件 塊中的監聽指令 後啟用 參數,並且指定伺服器證書 和私鑰 的位置:
伺服器證書是一個公共實體,它被發送給連接到伺服器的每一個客戶機。私鑰是一個安全實體,應該存儲在具有受限訪問的文件中,但它必須可被nginx主進程讀取。私鑰也可以存儲在與伺服器證書相同的文件中:
在這種情況下,這個證書文件的訪問許可權也應受到限制。雖然證書和密鑰存儲在一個文件中,但只有證書被發送到客戶端。
指令 和 可用於限制僅包括強版本和密碼的SSL/TLS連接。 默認情況下,nginx使用「sslprotocols TLSv1 TLSv1.1 TLSv1.2」版本和「sslciphers HIGH:!aNULL:!MD5」密碼,因此通常不需要顯式地配置它們。 注意,這些指令的默認值已經 好幾次了。
HTTPS 伺服器優化
SSL操作會消耗額外的CPU資源。 在多處理器系統上,應該運行不少於可用CPU內核數的多個 。最耗CPU的操作是SSL握手。有兩種方法來最小化每個客戶端執行這些操作的次數:第一是通過啟用 參數來讓這些連接在一個連接中發送多個請求,第二是重用SSL會話參數,以避免並行和後續連接的SSL握手。這些會話存儲在NGINX工作程序的共享SSL會話緩存中,並由 指令配置。 1M的高速緩存包含大約4000個會話。默認的緩存超時時間為5分鐘。它可以通過使用 指令增大。下面是針對具有10M共享緩存的多核心系統的優化示例配置:
SSL 證書鏈
有些瀏覽器可能警示由知名證書頒發機構簽名的證書,而其他瀏覽器卻能無問題的接受這些證書。這是因為這些證書頒發機構使用了中間證書來簽署伺服器證書,所簽署的證書不存在於特定瀏覽器發行時內置的可信證書頒發機構頒發的證書庫中。在這種情況下,頒發機構提供一組與頒發的伺服器證書(根證書)串接的捆綁證書,並讓伺服器證書(根證書)出現在合併後文件(證書鏈)的捆綁證書之前:
生成的證書鏈文件應該放在 指令之後:
如果根證書和捆綁證書使用了錯誤的鏈接順序,nginx將會啟動失敗並顯示如下錯誤信息:
因為nginx嘗試去使用私鑰與捆綁後證書的第一個證書驗證而不是它本該去驗證的伺服器證書。
瀏覽器通常會存儲他們接收到的由可信證書頒發機構簽發的中間證書,因此被活躍使用的瀏覽器可能已經擁有所需的中間證書,並且可能不會抱怨沒有包含捆綁證書的證書。為了確保伺服器發送的是完整的證書鏈,可以使用 命令行通用程序,例如:
在本示例中, 證書鏈中的#0號證書的證書請求者("s")由簽發者("i")簽發,而簽發者("i")本身又是#1號證書的請求者("s"),它的證書籤發者是#2號證書的請求者,它請求的證書由知名發布者ValiCert,Inc.簽發,其證書存儲在瀏覽器的內置證書庫中(如同英國童謠 The House That Jack Built 講述的一樣)。
如果捆綁證書沒有被添加到證書鏈,那只有#0號證書會被展示出來。
單個 HTTP/HTTPS 虛擬主機
現在,在單個nginx虛擬主上可以配置同時處理 HTTP 和 HTTPS 請求:
在0.7.14之前的版本無法向上面那樣為單個偵聽套接字選擇性啟用SSL,而只能使用 指令為整個伺服器啟用SSL,從而無法設置單個HTTP / HTTPS虛擬主機伺服器,所以在 指令後增加了 參數來解決此問題。因此不建議在現代版本中使用 這個指令。
基於名稱的 HTTPS 伺服器
當配置兩個或多個HTTPS虛擬主機伺服器偵聽單個IP地址時會出現常見問題:
解決此問題最古老和最可靠的方法是為每個HTTPS虛擬主機伺服器指定一個單獨的IP地址:
包含多個名稱的 SSL 證書
還有其他方法允許在幾個HTTPS虛擬主機伺服器之間共享單個IP地址。然而,他們都有自己的缺點。其中一種方法是在證書的 欄位中使用多個名稱,例如 和 。 但是, 欄位長度有限。
另一種方法是使用帶有通配符名稱的證書,例如 。 通配符證書能保護指定域的所有子域,但只限一個級別。此證書與 匹配,但不匹配 和 。這兩種方法也可以結合。證書可以在 欄位中包含完全匹配和通配符名稱,例如 和 。
It is better to place a certificate file with several names and its private key file at thehttplevel of configuration to inherit their single memory copy in all servers:最好在配置文件的 區塊中放置具有多個名稱的證書文件及其私鑰文件,以在所有其下的虛擬主機伺服器中繼承其單個內存副本:
伺服器名稱指示
單個IP地址上運行多個HTTPS虛擬伺服器的更通用的解決方案是 (SNI,RFC 6066),其允許瀏覽器在SSL握手期間同時發送請求的伺服器名稱,因此,伺服器就知道它應該給這個連接使用哪個證書。然而,SNI限制了它支持的瀏覽器。目前支持從以下瀏覽器版本及其後:
Opera 8.0;
IE 7.0 (Windows Vista及更高版本);
Firefox 2.0 及其他使用 Mozilla Platform rv:1.8.1 的瀏覽器;
Safari 3.2.1 (Windows版本支持Windows Vista及更高版本);
Chrome (Windows版本支持Windows Vista及更高版本).
只有域名可以在SNI中傳遞,然而如果請求包含IP地址,一些瀏覽器可能錯誤地把伺服器的IP地址作為其名稱進行傳遞,我們不能依賴於這個。
為了在nginx中使用SNI,必須在構建nginx的OpenSSL庫以及運行時的動態鏈接庫中支持它。OpenSSL從0.9.8f版本支持SNI,如果在編譯時給 增加了 選項;從OpenSSL 0.9.8j版本開始默認啟用此選項。如果nginx是以支持SNI方式構建的,當使用「-V」參數運行時,nginx會顯示這一信息:
但是,如果啟用SNI的nginx與沒有SNI支持的OpenSSL庫動態鏈接,nginx將顯示警告:
兼容性列表
從 0.8.21 和 0.7.62 開始使用 "-V" 參數可以查看SNI支持狀態;
從 0.7.14 版本開始支持 指令的 參數;更早版本到 0.8.21 只能使用"default 參數指定;
從 0.5.23 版本開始支持SNI;
從 0.5.6 版本開始支持共享SSL會話緩存;
從 1.9.1 及其後版本,默認的SSL協議是:TLSv1, TLSv1.1, TLSv1.2(如果OpenSSL庫支持)
從 0.7.65, 0.8.19 及其後版本開始,默認的SSL協議是:SSLv3, TLSv1, TLSv1.1, TLSv1.2(如果OpenSSL庫支持)
0.7.64, 0.8.18 及更早版本,默認的SSL協議是:SSLv2, SSLv3, and TLSv1
從 1.0.5 及其後版本,默認的SSL密碼是:
從 0.7.65, 0.8.20 及其後版本,默認的SSL密碼是:
0.8.19 版本,其默認的SSL密碼是:
0.7.64, 0.8.18 及更早版本,默認的SSL密碼是:
※React與Preact PWA 性能分析報告
※如何管理好10萬行代碼的前端單頁面應用
※使用 Node.js和Express.js 搭建簡易 HTTP/2 伺服器
※使用 Node.js 進行 HTTP/2 Server Push
※Nodejs進階:服務端字元編解碼
TAG:京程一燈 |