HTTPS基礎原理和配置-2

東風微鳴發表於2023-02-14

〇、概述

作為概述,以下是本文要講的內容。HTTPS 是什麼? 每個人都可能從瀏覽器上認出 HTTPS,並對它有好感。然後再講一遍基礎知識,再詳細講一下協議版本,密碼套件(Cipher Suites),本文的重點會落在如何配置 NGINX,讓你的網站使用 HTTPS 服務。

除此之外,還有一個使用 HTTPS 作為代理的問題; 所以,如果你的 NGINX 在另一個應用程式的前面,你如何設定NGINX 作為 HTTPS 客戶端。

在這裡,我會介紹一些方法,用以檢查你的 HTTPS 配置,以看到它是最安全的和最新的,以及一些額外主題,幫助你得到你需要的 A+ 級別的安全。

本文涉及以下內容:

  1. 什麼是 HTTPS
  2. 協議版本
  3. 密碼套件
  4. 證書

下一篇的內容將包括:

  1. 配置 NGINX
  2. 後端 HTTPS
  3. 檢查配置
  4. 配置 HSTS
  5. OCSP Stapling

一、什麼是 HTTPS

你可能猜到了,HTTPS 就是 HTTPS, S 代表安全(Security)。就網路而言,有兩種協議,分別叫做 SSL 和 TLS。它們可以互換使用。但是,「安全協議」(a security protocol)是位於通訊之上的安全層。如果你想一下OSI 七層網路模型,那麼它位於第 7 層的下面即第 6 層,叫做表示層。

OSI 七層模型

在客戶端和伺服器之間,它向您提供的是資料的保密性。因此,所有從客戶端傳送到伺服器的資訊都是完全加密的,所以只有兩個人知道如何讀取資訊,那就是客戶端和伺服器。它還提供了一種形式的身份驗證,在這種身份驗證中,客戶機可以知道伺服器到底是誰。這些都交織在握手(handshake)的概念中。

1.1 SSL 握手 (Diffie‑Hellman)

SSL 握手

  1. 客戶端:客戶端傳送 hello、客戶端隨機(client random)和受支援的密碼套件(cipher suites)給伺服器;
  2. 第二步
    1. 2a:伺服器傳送伺服器隨機(server random)和公鑰證書(public key certificate)(也會傳送一個用於會話複用的session ID)給客戶端。
    2. 2b:客戶端隨機、伺服器隨機和公鑰證書的金鑰簽名。
  3. 伺服器傳送伺服器 DH (Diffie‑Hellman) 引數和金鑰簽名(signature)給客戶端。
  4. 客戶端傳送客戶端 DH 引數給伺服器。
  5. 客戶端和伺服器都從伺服器 DH 引數和客戶端 DH 引數中獲得相同的 premaster secret。
  6. 客戶端和伺服器都從客戶端隨機、伺服器隨機和 premaster secret 中獲得相同的會話金鑰(session keys)。客戶端可以從伺服器請求內容,並且請求將被加密。(也傳送了會話複用的會話票據(session ticket))

上圖是 SSL/TLS 握手流程。這有點複雜; 有很多可移動的部分,但本質上,如果你退一步看,它是在客戶端和傳送加密資訊的伺服器之間額外的一到兩次往返。在這種情況下,你有幾個選項——有伺服器隨機,有客戶端隨機; 這些都是你不需要知道的深奧的東西。

您只需要知道伺服器本身傳送一個公鑰,客戶端和伺服器建立一個共享 secret,它們可以使用這個 secret 來加密通訊。因此,訪問者和伺服器之間的所有通訊都使用對稱金鑰加密,這意味著雙方都有相同的金鑰。還有一個完整性金鑰,在本例中是 HMAC,但我暫時先跳過這個圖,轉而討論更重要的問題: 「為什麼需要設定HTTPS?」

1.2 為什麼需要設定 HTTPS

  • 使用者隱私
  • SEO 加成
  • 放在「沒有 HTTPS 能力的服務」的前面
  • 通用最佳實踐

主要原因是使用者隱私。在服務通訊的情況下,這是資訊的隱私 - 你有多信任你正在使用的傳輸資訊的網路? 你相信這些網路不會向你的流量中注入資訊,並且能夠讀取傳輸的資訊嗎? 另外 2015 年之後,如果你在你的網站上使用 https,它提供了一個搜尋引擎最佳化的優勢,谷歌排名(以及國內的百度)將會比那些不支援 HTTPS 的網站排名更高。

另一件你可以為 HTTPS 做的事情(這是 NGINX 的主要用例之一)是把它放在那些不支援 HTTPS 或不支援最現代、最新版本的 SSL 和 TLS 的服務前面。因此,你可以從 NGINX 得到的是所有加密演算法的最好、最先進的實現,你不需要真的去思考 HTTPS 的複雜性,總的來說,這是一個很好的實踐。

另外,如果有人去訪問一個網站,他們喜歡看到那個快樂的小鎖圖示。在本例中是 nginx.com,它啟用了 HTTPS 和 HSTS (我將在後面討論這個特性)。你不能再使用普通的 HTTP 版本訪問了; 瀏覽器知道總是使用 HTTPS。你在這裡看到的另一件事是,有一個漂亮的 NGINX, Inc[US] 顯示這是一個擴充套件驗證證書 —— 本質上,這個證書表明NGINX 是哪家公司的。他們為此多付了一點錢,做了一些調查並在證書上展示出來。

https 綠鎖

1.3 HTTPS 帶來的缺點有哪些?

  • 操作運維的複雜性
  • 額外的延遲(首次連線多了 2 次往返)
  • CPU 消耗

但 HTTPS 不是十全十美; 也有一些缺點。具體來說,有一點操作運維上的複雜性。你必須管理證書,你必須確保它們持續更新。您需要有受信任的管理員來儲存私鑰資料。

當你透過 HTTPS 連線到一個網站時,第一次可能會慢一些; 如果您的物理距離不一定很近,那麼除了 TCP 握手之外,還有 SSL 握手,正如我提到的,它至少增加了兩次往返。因此,延遲會受到輕微的影響,但這可以透過 SSL 的一些更高階的特性(如 SPDY 和 HTTP/2 )來緩解,本文不會詳細介紹這些特性。

最終 HTTPS 可以和 HTTP 一樣快,但有時不是。你的伺服器上也有加密的成本; 這是一個很長時間不使用 HTTPS 的原因,但它越來越不適用。最新一代英特爾伺服器可以非常快速地完成 HTTPS 所需的加密,而且幾乎沒有成本。所以,在現代硬體中,加密傳輸中的資料基本上是免費的。

1.4 你需要為 HTTPS 做哪些事情?

  • 支援的一系列 SSL/TLS 協議
  • 傾向使用的一系列的密碼套件
  • 由受信任的證書機構(CA)簽名的私鑰和證書

如果你想為你的服務或網站設定 HTTPS,你需要做一些選擇並獲得一些東西。第一個「決定」是您想要支援的協議,第二個「決定」是您想要支援的密碼(後面將詳細說明這意味著什麼),還有「您需要獲得」證書和相應的私鑰。這是一個重要的部分,由客戶信任的第三方證書頒發機構「頒發」。我稍後會講到,但首先讓我們談談協議版本(protocol versions)。

二、協議版本(Protocol Versions)

回顧一下前文,HTTPS 是 HTTP 加上 S,S一直在變化; 它是隨著時間而進化的。最初,SSL v1.0 是 Netscape(網景) 發明的協議。有一個著名的軼事是,馬克·安德森(Marc Andreessen)在麻省理工學院做演講時觀眾席上有人用鉛筆描述瞭如何破解密碼演算法。

所以,SSL TLS 加密協議其實並沒有很長的歷史,1995 年 網景 釋出了 SSL v2.0,這也是 web 加密的開始。這使得電子商務領域,人們可以線上提交密碼和信用卡,並且至少是相當安全的。

2.1 HTTPS 歷史背景

接下來請參見加密協議歷史概要 - HTTPS 基礎原理和配置 - 1 - 東風微鳴技術部落格 (ewhisper.cn)

?被破解歷史概要 - HTTPS 基礎原理和配置 - 1 - 東風微鳴技術部落格 (ewhisper.cn)

2.2 客戶端相容性

請參見:客戶端相容性 - HTTPS 基礎原理和配置 - 1 - 東風微鳴技術部落格 (ewhisper.cn)

2.3 配置選項及得分

請參見:配置建議 - HTTPS 基礎原理和配置 - 1 - 東風微鳴技術部落格 (ewhisper.cn)

三、密碼套件(Cipher Suites)

現在讓我們進入密碼套件。什麼是密碼套件? SSL、TLS 和 HTTPS 使用各種加密演算法來建立連線,這實際上是一個字母池。它們是什麼意思?

密碼套件就是描述使用的加密型別的複雜字串,它是由 openssl 定義的(可以透過 openssl ciphers 檢視你的密碼套件)。

示例如下:

TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:RSA-PSK-AES256-GCM-SHA384:DHE-PSK-AES256-GCM-SHA384:RSA-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:AES256-GCM-SHA384:PSK-AES256-GCM-SHA384:PSK-CHACHA20-POLY1305:RSA-PSK-AES128-GCM-SHA256:DHE-PSK-AES128-GCM-SHA256:AES128-GCM-SHA256:PSK-AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:ECDHE-PSK-AES256-CBC-SHA384:ECDHE-PSK-AES256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:RSA-PSK-AES256-CBC-SHA384:DHE-PSK-AES256-CBC-SHA384:RSA-PSK-AES256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:AES256-SHA:PSK-AES256-CBC-SHA384:PSK-AES256-CBC-SHA:ECDHE-PSK-AES128-CBC-SHA256:ECDHE-PSK-AES128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:RSA-PSK-AES128-CBC-SHA256:DHE-PSK-AES128-CBC-SHA256:RSA-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:AES128-SHA:PSK-AES128-CBC-SHA256:PSK-AES128-CBC-SHA

3.1 密碼套件拆解

密碼套件拆解

從本質上講,第一個術語是金鑰交換,即雙方用來交換金鑰的演算法。在上圖這種情況下,它是基於 Diffie-Hellman演算法。

第二個術語是您的證書中的金鑰型別。因為每個證書都有一個特定型別的公鑰。這裡是RSA。

第三部分是你的傳輸密碼,用來加密所有資料的加密演算法。這裡面有很多不同的部分,但 AES-GCM 是最安全的密碼; 這實際上是英特爾處理器幾乎零成本完成的事情。所以這是一個相當便宜和可靠的密碼使用。

最後一點是完整性。正如我提到的,訊息有一個快取,以確保它們沒有被篡改,但如果它是加密的,並具有完整性,你可以從那裡校驗。

3.2 伺服器密碼套件

  • 客戶端按優先順序列出受支援的密碼套件
  • 伺服器接受:客戶端列表和伺服器支援的密碼列表的交集
  • 伺服器會選擇剩下中的更喜歡的那些

現在,並不是所有的瀏覽器和伺服器都支援相同的密碼列表。這被稱為協議靈活性,實質上伺服器所做的是: 客戶端說,“嘿,這就是我所支援的全部”。伺服器說:“好吧,我知道其中的五個。我會挑我最喜歡的”。

3.3 密碼套件商定(Cipher Suite Negotiation)

因此,如上圖所示,如果客戶端說,「左邊的這些是我依次支援的」,而伺服器端只支援兩個,然後它就會選擇自己喜歡的。

3.4 推薦的密碼套件

這並不是一個爭論的大問題,但你有很多選擇。CloudFlare 使用這個密碼套件列表,你可以在 GitHub 的這裡找到它。有一個 NGINX 配置格式,這些是 CloudFlare 推薦的。這些是 CloudFlare 上的所有網站最終都會使用的。

ssl_protocols               TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ecdh_curve              X25519:P-256:P-384:P-521;
ssl_ciphers                 '[ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES';
ssl_prefer_server_ciphers   on;

有一種很酷的新密碼叫 ChaCha 20。在主線 NGINX 它還不支援,其他的都可以用。Mozilla 在這方面也有自己的建議,你可以去訪問他們的伺服器端 TLS 站點,他們會為你生成 NGINX 或任何你可能使用的網路伺服器的 SSL 配置。這就是密碼套件。生成的示例如下:

# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

四、證書

現在我們有了協議集和密碼集; 接下來是證書。這是 HTTPS 最重要的部分。這是在客戶面前標識您作為一個站點的標誌。但是,證書裡有什麼呢?

4.1 證書裡有什麼?

  • 組織名(Organization name)
  • 公鑰(Public Key)
  • 頒發者名稱(Issuer name)
  • 許可權
    • 有效期
    • 域名(Hostnames)
  • 頒發者數字簽名(Digital signature by issuer)

其中包括你的名字(你是誰)、你的站點適用於哪些域名、證書何時有效、公鑰(客戶可以使用公鑰驗證你用它簽名的任何東西),然後是數字簽名。數字簽名是來自公共證書頒發機構的戳記,表明它是一個真實的證書: 這個人實際上擁有這個 DNS 名稱,並且在這些點上是有效的。

4.2 什麼是授信證書?

那麼,是什麼使證書可信呢? 這是目前網際網路上所有證書頒發機構(ca)的分類,大多數證書都是由這些機構簽署的。這裡有一些常見的名字。賽門鐵克已經購買了幾個這樣的證書頒發機構,包括 GeoTrust、Verisign 等。

這些都是受信任的大公司,最重要的是,它們的證書受到瀏覽器的信任。因此,如果賽門鐵克透過某人從他們那裡購買證書的過程表示該證書良好,那麼瀏覽器將顯示綠鎖。

4.3 我如何獲得一個證書?

您可以透過建立私鑰或一對金鑰來獲得證書,然後將您的公鑰傳送給證書頒發機構,透過驗證簽章將其轉換為證書。這通常會花費一些錢(有免費的方法),但本質上私鑰你必須保持私有,唯一應該得到它的實體是你的管理員和你的web伺服器本身

4.4 我如何建立一個 CSR(證書籤名申請)和私鑰?

有幾種方法可以建立這些金鑰對。CSR 本質上是將公鑰打包到證書頒發機構以建立證書的方法。有OpenSSL, CFSSL等多種方式。

使用 OpenSSL:

openssl genrsa -out key.pem 2048
openssl req -new -sha256 -key key.pem -out key.csr

4.5 如何獲得一個免費證書?

如果你想要一個免費的,目前最知名的網站是 Let's Encrypt - 免費的SSL/TLS證書 (letsencrypt.org)。他們會給你一個免費網站的證書。隨著時間的推移,獲得證書的成本似乎會更低。還有免費證書頒發機構的建議。所以現在,你可以付費使用 Comodo 或 DigiCert 等網站,也可以選擇免費路線。

4.6 證書鏈(Certificate Chain)

證書不會直接由證書頒發機構簽署; 這是一種建立起來的信任鏈。如果你有一個證書,它通常是由一箇中間證書頒發機構簽署的,而這個中間證書頒發機構是由真正的證書頒發機構簽署的。

在這種情況下,並不是所有的瀏覽器都必須知道鏈中的下一個證書是什麼,並且瀏覽器實際上只與頂部繫結(真正的離線根證書)。因此,當你獲得一個證書時,你還需要擁有整個信任鏈。

通常CA會給你這個證書鏈鏈,在 CA 沒有給你的證書鏈情況下你可以透過一些工具去建立。

三人行, 必有我師; 知識共享, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.

相關文章