知識庫 / Spring / Spring Boot RSS 訂閱

從HashiCorp Vault為Spring Boot重新加載SSL證書

Security,Spring Boot
HongKong
6
10:52 AM · Dec 06 ,2025

1. 概述

應用程序和設備使用 SSL 證書來安全連接。它們有助於保護服務器與客户端之間的通信。這些證書具有到期時間,需要更換。

手動進行此更換耗時且可能導致停機或糟糕的用户體驗。在本文中,我們將學習如何熱加載它們。我們將使用 HashiCorp Vault 在 Spring Boot 應用程序中使用此方法。

2. 關鍵概念

在本節中,我們將學習一些在後續章節中也很有幫助的基本概念。

2.1. SSL 證書

SSL(Secure Sockets Layer)是一種安全協議,它在 Web 服務器和 Web 瀏覽器之間創建一個加密連接。

SSL 證書是一種數字證書,用於驗證網站或服務器的身份,並建立加密連接。該證書包含諸如頒發機構名稱、接收者、公鑰、到期日期和其他詳細信息,以驗證網站或服務器的真實性。

在本文中,當我們使用“證書”一詞時,我們指的是 SSL 證書。

2.2. X.509 證書

X.509 是定義數字證書的標準之一。它是互聯網上最常用的標準。它包含網站或服務器的身份信息以及公鑰,並且要麼由證書頒發機構(CA)簽名,要麼是自簽名證書。

2.3. 根證書頒發機構 (Root CA)

在 SSL 領域,有少數被廣泛信任並頒發證書的權威機構。這些機構被稱為根證書頒發機構 (Root CA),例如 GeoTrust、DigiCert 等。由他們頒發的證書被稱為根證書。操作系統和瀏覽器認識這些受信任的根證書頒發機構,從而能夠驗證其他證書。該系統確保用户能夠安全地連接到網站並驗證其身份。

2.4. 中間級 CA

直接暴露根 CA 證書可能存在某些安全問題。為了緩解這種情況,我們創建了一個 中間級 CA(證書頒發機構),它作為根 CA 和用户證書之間的橋樑。我們可以根據需要創建多箇中間級 CA。每個中間級 CA 代表其父 CA 頒發證書,從而建立信任鏈,而無需直接暴露根 CA 的私鑰。

這種配置通過保持根 CA 安全,同時允許中間級 CA 驗證和頒發證書來增強安全性。瀏覽器和設備依賴這種信任鏈以確保與網站和服務的安全連接。

2.5. HashiCorp Vault

Vault 是一個用於安全存儲和訪問敏感信息(如令牌、密碼、密鑰、數字證書等)的工具。HashiCorp 是一家擁有眾多產品的公司,Vault 就是其中之一。它存儲密鑰、輪換密鑰、加密數據,並可頒發證書。

2.6. PKI 密鑰引擎

在 HashiCorp Vault 中,我們使用 PKI 密鑰引擎生成動態 X.509 證書。藉助此密鑰引擎,服務無需通過常規的生成私鑰和 CSR、提交至 CA 以及等待驗證和簽名流程來獲取證書。

2.7. 密鑰保管器代理 (Vault Agent)

它是一個與密鑰保管器服務器通信並請求證書籤發的客户端守護進程。我們可以配置它在特定目錄下以定期間隔生成證書。 藉助密鑰保管器代理,我們就能實現證書的熱加載。

到目前為止,我們已經瞭解了一些與 SSL 世界相關的基本概念以及 HashiCorp Vault。現在,讓我們瞭解這些組件將如何協同工作,使我們的 Spring Boot 應用程序能夠熱加載 HashiCorp Vault 簽發的證書。

簡而言之,我們將使我們的應用程序能夠在證書過期時,從配置的目錄中重新加載證書。密鑰保管器代理是一個獨立的進程,它向 Vault 服務器請求證書,然後以定期間隔將它們寫入目錄。

3. 配置 Vault 服務器

我們已經瞭解到使用中間 CA 比使用根 CA 更好。 在本節中,我們將設置 Vault 服務器,配置根 CA,然後配置中間 CA。

3.1. 在 Vault 服務器中配置根證書頒發機構

首先,請按照本指南安裝 Vault 並通過運行命令 vault -v 驗證其版本。

然後,逐一運行以下命令來設置根證書頒發機構:

vault server -dev -dev-root-token-id=root
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN=root

vault secrets enable pki

vault secrets tune -max-lease-ttl=24h pki

vault write -field=certificate pki/root/generate/internal common_name="localhost" \ 
  issuer_name="root-2024" ttl=24h

vault write pki/config/urls issuing_certificates="${VAULT_ADDR}/v1/pki/ca" \
  crl_distribution_points="${VAULT_ADDR}/v1/pki/crl”

vault write pki/roles/localhost-12 allow_any_name=true max_ttl=12h

我們現在啓動 Vault 服務器,處於開發模式。默認情況下,它運行在 localhost:8200。我們已將 root 設置為令牌。 還可以從瀏覽器訪問 Vault Server 的 GUI,地址為 localhost:8200

我們正在導出 addresstoken ,這些信息將在後續命令中使用。我們已啓用 PKI 密鑰引擎,路徑為 /pki ,以頒發具有最多 24 小時過期時間的證書。

我們還指定了 CRL 位置和頒發證書的位置。最後,創建一個名為 localhost-12 的角色,該角色可以頒發具有最多 12 小時過期時間的根證書。

3.2. 配置中間CA在Vault服務器上

與上一節相同,我們將運行一些命令來設置中間CA:

vault secrets enable -path=pki-int pki  

vault secrets tune -max-lease-ttl=12h pki-int 

vault write -format=json pki-int/intermediate/generate/internal common_name="localhost \
  Intermediate Authority" issuer_name="localhost-intermediate" \
  | jq -r '.data.csr' > pki-intermediate.csr

vault write -format=json pki/root/sign-intermediate issuer_ref="root-2024" \
  [email protected] format=pem_bundle ttl="12h" \
  | jq -r '.data.certificate' > intermediate.cert.pem

vault write pki-int/intermediate/set-signed [email protected]

vault write pki-int/roles/localhost-3 allow_any_name=true max_ttl=3h
<p>這裏我們啓用了另一個 PKI 腳本引擎,路徑為 <em>/pki-int&nbsp;</em>,最大過期時間為 12 小時。</p>
<p>然後,我們生成中間證書籤名請求並保存到文件 <em>pki-intermediate.csr</em>。 使用此簽名請求,我們使用我們的根 CA 進行簽名。 之後,我們將中間證書頒發機構的簽名證書設置為根 CA 簽名證書。</p>
<p>最後,我們創建了一個角色 <em>localhost-3&nbsp;</em>,用於頒發將在 3 小時後過期的證書。</p>
<p>現在,我們的中間證書頒發機構已配置完成。我們可以使用以下命令進行測試:</p>
<p><code class="language-bash">vault write pki-int/issue/localhost-3 common_name="localhost" ttl=1h</code></p>
<p>此命令應在終端上生成具有 1 小時過期時間的證書。</p>
<p>這是手動生成證書的方式。要從中間 CA 自動生成證書,我們將使用 Vault Agent。</p>

4. 配置 Vault Agent

為了使用中間 CA,我們將創建一個策略並將其與角色 localhost-3 關聯,以便該角色可以使用 PKI 密鑰引擎:

path "pki-int/issue/localhost-3" {
 capabilities = ["update"]
}

將上面的片段保存為名為 policy.hcl 的文件,然後運行以下命令以創建此策略:

vault policy write vault-agent-policy path/to/policy.hcl

現在,我們將啓用一種身份驗證方法,例如 AppRole

vault auth enable approle

vault write auth/approle/role/localhost-3 \                           
  token_policies="vault-agent-policy" \
  secret_id_ttl="24h" \
  token_ttl="1h" \
  token_max_ttl="4h"

上述命令會將角色 localhost-3 綁定到 vault-agent-policy

將角色 ID 和密鑰 ID 寫入文件。

vault read auth/approle/role/localhost/role-id

echo “role-id-from-above-command" > role-id

vault write -f auth/approle/role/localhost/secret-id

echo “secret-id-from-above-command" > secret-id

現在我們將配置一個模板並將其保存到名為 template.tpl 的文件中:

{{- with pkiCert "pki-int/issue/localhost-3" "common_name=localhost" "alt_names=localhost" "ttl=5m" -}}
{{ .Cert }}{{ .CA }}{{ .Key }}
{{ .Key | trimSpace | writeToFile "/path/to/private_key.key" "" "" "0400" }}
{{ .CA | trimSpace | writeToFile "/path/to/ca.pem" "" "" "0644" }}
{{ .Cert | trimSpace | writeToFile "/path/to/certificate.crt" "" "" "0644" }}
{{- end -}}

在本項目中,我們將使用一個名為 localhost-3 的角色,該角色先前已創建,它會生成有效期為 5 分鐘的證書並將其保存到文件中。每次證書即將過期時,它都會向 Vault 服務器發出請求,生成證書並將它們保存到這些文件中。

最後,我們需要一個 Vault Agent 的配置文件。

pid_file = "/paht/to/pidfile.pid"
 
vault {
 address = "http://localhost:8200"
}
 
auto_auth {
 method {
   type = "approle"
   config = {
     role_id_file_path                   = "/path/to/role-id"
     secret_id_file_path                 = "/path/to/secret-id"
     remove_secret_id_file_after_reading = false
   }
 }
}
 
template {
 source       = "/path/to/template.tpl"
 destination  = "/path/to/all-certs"
}

將此配置保存到一個名為 vault_agent.hcl 的文件中。 在該文件中,我們指定了 Vault 服務器地址、身份驗證方法、template.tpl 文件的位置以及 Vault Agent 將所有證書和密鑰寫入的目標文件 all-certs。 然後,創建一個名為 pidfile.pid 的文件,Vault Agent 使用它來寫入進程 ID。

現在,請運行以下命令以啓動 Vault Agent:

sudo vault agent -config=/path/to/vault_agent.hcl

我們的 Vault Agent 已啓動。我們可以通過驗證證書在 private_key.key, ca.pem, certificate.crt, 和 all-certs 文件中的生成。我們使用 sudo 命令運行,以避免任何權限問題。

因此,我們已配置 Vault 服務器和 Vault Agent。現在,讓我們配置我們的 Spring Boot 應用。

5. 配置 Spring Boot 應用

首先,我們使用 spring-boot-starter-webspring-cloud-starter-vault-config 創建一個 Spring Boot 應用。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.4.0</version>
</dependency>
<div>
</div>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-vault-config</artifactId>
    <version>4.2.0</version>
</dependency>

第二,我們在 application.properties文件中添加了以下 Spring Boot 屬性,以便讀取和熱加載證書:

server.ssl.bundle=demo
spring.ssl.bundle.pem.demo.reload-on-update=true
spring.ssl.bundle.pem.demo.keystore.certificate=file:/path/to/certificate.crt
spring.ssl.bundle.pem.demo.keystore.private-key=file:/path/to/private_key.key
上述屬性指明瞭 private_key.keycertificate.crt 文件的位置,這些文件在 template.tpl 文件中被提及。Spring Boot 在內容發生變化時,會自動讀取並重新加載這些證書。

應用程序只有在證書有效時才會成功啓動。我們還可以通過查看日誌進行驗證。如果我們在日誌中監控超過五分鐘,那麼我們將會看到以下類型的日誌:

Connector [https-jsse-nio-8080], TLS virtual host [_default_], certificate type [UNDEFINED] configured from keystore [/Users/$HOME/.keystore] using alias [tomcat] with trust store [null]

當證書重新加載時,上述日誌仍然會持續出現。

6. 結論

在本文中,我們做了很多事情。我們首先學習了與 SSL 和 HashiCorp Vault 相關的基本概念。我們瞭解了 Root CA 和 Intermediate CA,並理解了 Intermediate CA 證書的重要性。

接下來,我們進行了幾個配置。我們學習瞭如何運行 Vault 服務器、配置 Root CA 以及設置 Intermediate CA。然後,我們探索了 Vault Agent 的重要性以及如何配置和運行它以頒發證書。

最後,我們創建了一個 Spring Boot 應用並配置它以熱加載證書。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.