從 HashiCorp Vault 重新載入 SSL 憑證以用於 Spring Boot
1. 概述
應用程式和裝置使用 SSL 憑證來保護連線。它們有助於保護伺服器和客戶端之間的通訊。這些證書都有有效期限,需要更換。
手動執行此替換非常耗時,並且可能會導致停機或糟糕的用戶體驗。在本文中,我們將學習如何熱重載它們。我們將使用 HashiCorp Vault 在 Spring Boot 應用程式中執行此操作。
2. 關鍵概念
在本節中,我們將了解一些在後面的部分有用的基本概念。
2.1. SSL憑證
SSL 代表安全通訊端層,是一種在 Web 伺服器和 Web 瀏覽器之間建立加密連結的安全協定。
SSL 證書是一種數位證書,用於驗證網站或伺服器的身份並建立加密連接。此憑證包含頒發者機構名稱、收件者、公鑰、到期日以及用於驗證網站或伺服器真實性的其他詳細資訊等資訊。
在本文中,當我們使用「憑證」一詞時,我們指的是 SSL 憑證。
2.2. X.509證書
X.509 是定義數位憑證的標準之一。這是網路上最常用的一種。它包含網站或伺服器的身份以及公鑰,並由憑證授權單位簽署或自簽署。
2.3.根CA
在 SSL 領域,有少數受到廣泛信任的機構頒發憑證。這些稱為根CA (憑證授權單位),例如GeoTrust、DigiCert 等。作業系統和瀏覽器可以識別這些受信任的根 CA,從而允許它們驗證其他憑證。該系統確保用戶可以安全地連接到網站並驗證其身份。
2.4.中級CA
直接公開根 CA 憑證可能會帶來某些安全性問題。為了緩解這種情況,我們創建了一個中間 CA (憑證授權單位),充當根 CA 和最終使用者憑證之間的連結。我們可以根據需要建立任意數量的中間 CA。每個中間 CA 代表其父 CA 頒發證書,從而創建信任鏈,而無需直接公開根 CA 的私鑰。
此設定透過保持根 CA 的安全性同時允許中間 CA 驗證和頒發憑證來增強安全性。瀏覽器和裝置依靠此信任鏈來確保與網站和服務的安全連接。
2.5. HashiCorp 金庫
Vault 是一種安全儲存和存取敏感資訊(如令牌、密碼、金鑰、數位憑證等)的工具。它儲存秘密、輪換秘密、加密資料並頒發證書。
2.6。 PKI秘密引擎
在 HashiCorp Vault 中,我們使用 PKI 秘密引擎來產生動態 X.509 憑證。有了這個秘密引擎,服務就可以獲得證書,而無需經歷生成私鑰和 CSR、提交給 CA 以及等待驗證和簽署過程完成的常規手動程序。
2.7.保險庫代理
它是一個客戶端守護程序,與 Vault 伺服器通訊並要求頒發憑證。我們可以將其配置為在特定目錄中定期產生憑證。在Vault Agent的幫助下,我們將實作憑證的熱重載。
到目前為止,我們已經了解了與 SSL 世界和 HashiCorp Vault 相關的一些基本概念。現在,讓我們了解這些元件如何協同工作,使我們的 Spring Boot 應用程式能夠熱重載 HashiCorp Vault 頒發的憑證。
簡而言之,我們將使我們的應用程式能夠在憑證過期時從配置的目錄重新載入憑證。 Vault 代理程式是一個單獨的進程,它要求 Vault 伺服器頒發證書,然後定期將它們寫入目錄。
3.配置Vault伺服器
我們已經看到,使用中間 CA 比使用根 CA 更好。在本節中,我們將設定 Vault 伺服器,設定根 CA,然後設定中間 CA。
3.1.在 Vault Server 中配置根 CA
首先,請按照本指南安裝 Vault 並透過執行vault -v
命令驗證其版本。
現在一一執行這些指令來設定根 CA:
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
設定為令牌。我們也可以從瀏覽器存取localhost:8200
上 Vault Server 的 GUI。
我們正在匯出address
和token
,它將在後續命令中使用。我們正在啟用 PKI 秘密引擎 在路徑/pki
處頒發有效期最長為 24 小時的憑證。
我們也分配 CRL 位置和頒發證書的位置。最後,建立一個名為localhost-12
角色,該角色可以頒發最長到期時間為 12 小時的根憑證。
3.2.**在Vault Server中配置**中間 CA
就像上面的部分一樣,我們將運行一些命令來設定中間 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
在這裡,我們在路徑/pki-int
處啟用了另一個 PKI 腳本引擎,最大到期時間為 12 小時。
然後,我們產生中間憑證簽署請求並保存在檔案pki-intermediate.csr
中。透過此簽名請求,
使用我們的根 CA 對其進行簽名。之後,我們將中間憑證授權單位簽署憑證設定為根簽署憑證。
最後,我們建立一個角色localhost-3
來頒發將在 3 小時後過期的憑證。
現在,我們的中間憑證授權單位已配置完畢。我們可以使用下面的命令來測試它:
vault write pki-int/issue/localhost-3 common_name="localhost" ttl=1h
此命令應在終端機上產生過期時間為 1 小時的憑證。
這是產生證書的手動方式。為了自動從中間 CA 產生證書,我們將使用 Vault Agent。
4.配置Vault代理
要使用中間 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.
將 role-id 和 Secret-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 代理程式在其中寫入所有憑證和金鑰的目標檔案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, and all-certs
檔案中驗證憑證的產生。我們使用sudo
命令運行以避免任何權限問題。
因此,我們已經設定了 Vault 伺服器和 Vault Agent。讓我們配置我們的 Spring Boot 應用程式。
5.配置Spring Boot應用程式
首先,我們使用[spring-boot-starter-web](https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web/3.4.0)
和[spring-cloud-starter-vault-config](https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-vault-config/4.2.0)
來建立一個 Spring Boot 應用程式:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>3.4.0</version>
</dependency>
<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
上述屬性指的是template.tpl
檔案中提到的private_key.key
和certificate.crt
檔案的位置。當內容變更時,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]
重新載入憑證時,上述日誌會繼續出現。
六、結論
在這篇文章中,我們做了很多事情。我們首先學習與 SSL 和 HashiCorp Vault 相關的基本概念。我們了解了根CA和中間CA,也了解了中間CA憑證的重要性。
接下來,我們進行了一些設定。我們學習如何執行 Vault 伺服器、設定根 CA 以及設定中間 CA。然後我們探討了 Vault Agent、它的重要性以及如何設定和運行它來頒發憑證。
最後,我們建立了一個 Spring Boot 應用程式並將其配置為熱重載憑證。