領先一步
VMware 提供培訓和認證,以加速您的進步。
瞭解更多在 Spring Boot 3.2.0 中,我們添加了嵌入式 Web 伺服器熱過載 SSL 證書和金鑰的功能。 這意味著您可以輪換您的 SSL 信任材料,而無需重新啟動您的應用程式。 Tomcat 和 Netty 嵌入式 Web 伺服器都支援熱過載。
讓我們看看它的實際效果!
首先,我們將使用 OpenSSL 建立我們的 SSL 私鑰和匹配的證書
mkdir certs
cd certs
openssl req -x509 -subj "/CN=demo-cert-1" -keyout demo.key -out demo.crt -sha256 -days 365 -nodes -newkey rsa
這將建立一個儲存在 certs/demo.key
中的私鑰,以及一個匹配的(自簽名)證書,其通用名稱為 certs/demo.crt
中的 "demo-cert-1"。
現在我們正在建立一個新的 Spring Boot 3.2.0 應用程式,使用 "Spring Web" 依賴項,預設情況下使用 Tomcat Web 伺服器,使用我們最喜歡的網站 start.spring.io。
在應用程式配置中,我們新增以下內容
spring.ssl.bundle.pem:
demo:
reload-on-update: true
keystore:
certificate: "certs/demo.crt"
private-key: "certs/demo.key"
這配置了一個名為 "demo" 的 SSL 捆綁包,以及我們生成的證書和私鑰。 reload-on-update: true
配置指示 Spring Boot 在後臺監視檔案,並在檔案更改時觸發重新載入。
現在,我們配置 Web 伺服器以使用該捆綁包並接受埠 8443 上的連線
server.ssl.bundle: "demo"
server.port: 8443
讓我們也新增一個簡單的控制器,它用純文字 "Hello World" 進行響應
@RestController
class DemoController {
@GetMapping(path = "/", produces = MediaType.TEXT_PLAIN_VALUE)
String helloWorld() {
return "Hello World";
}
}
當我們啟動應用程式時,我們在日誌中看到類似這樣的內容,這證實它已在埠 8443 上使用 HTTPS 啟動。
INFO 82407 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8443 (https)
現在我們可以使用 curl 發出我們的第一個請求
$ curl --insecure https://:8443/
Hello World%
萬歲,它有效! 我們必須傳遞 --insecure
,因為 SSL 證書是自簽名且不受 curl 信任。
讓我們將 curl 切換到 verbose 模式,以獲取有關發生的 SSL 握手的一些資訊
$ curl --verbose --insecure https://:8443/
* Trying 127.0.0.1:8443...
* Connected to localhost (127.0.0.1) port 8443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: CN=demo-cert-1
* start date: Nov 2 09:22:53 2023 GMT
* expire date: Nov 1 09:22:53 2024 GMT
* issuer: CN=demo-cert-1
* SSL certificate verify result: self-signed certificate (18), continuing anyway.
* using HTTP/1.x
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/8.0.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/1.1 200
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 11
< Date: Thu, 02 Nov 2023 09:33:37 GMT
<
* Connection #0 to host localhost left intact
Hello World
在 subject: CN=demo-cert-1
行中,您可以看到證書的通用名稱是 "demo-cert-1",這在以後會很重要。
讓我們透過使用 OpenSSL 生成新的私鑰和證書來嘗試熱過載,覆蓋舊檔案
cd certs
openssl req -x509 -subj "/CN=demo-cert-2" -keyout demo.key -out demo.crt -sha256 -days 365 -nodes -newkey rsa
這次,我們的證書的通用名稱為 "demo-cert-2"。
一段時間後,您會在日誌中看到類似這樣的內容
INFO 83162 --- [-bundle-watcher] o.a.t.util.net.NioEndpoint.certificate : Connector [https-jsse-nio-8443], TLS virtual host [_default_], certificate type [UNDEFINED] configured from keystore [/home/xxx/.keystore] using alias [tomcat] with trust store [null]
這是一種複雜的說法,即 Tomcat 已重新載入私鑰和證書。
我們現在可以使用 curl 驗證是否使用了新證書
$ curl --verbose --insecure https://:8443/
* Trying 127.0.0.1:8443...
* Connected to localhost (127.0.0.1) port 8443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server did not agree on a protocol. Uses default.
* Server certificate:
* subject: CN=demo-cert-2
* start date: Nov 2 09:37:46 2023 GMT
* expire date: Nov 1 09:37:46 2024 GMT
* issuer: CN=demo-cert-2
* SSL certificate verify result: self-signed certificate (18), continuing anyway.
* using HTTP/1.x
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/8.0.1
> Accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
< HTTP/1.1 200
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 11
< Date: Thu, 02 Nov 2023 09:39:47 GMT
<
* Connection #0 to host localhost left intact
Hello World
subject: CN=demo-cert-2
行驗證使用了新證書。 萬歲,大獲成功!
概括一下:我們建立了一個 SSL 私鑰和證書,然後配置 Spring Boot 以使用它並監視更改。 當私鑰和證書更改時,Spring Boot 會重新載入它們,並且它們將在不重新啟動應用程式的情況下使用。 這不是很酷嗎?!
順便說一句,如果您想知道現有連線會發生什麼:它們將繼續使用舊證書,但所有新連線將使用新證書。
我們希望此功能可以簡化您的操作。 您可以透過測試 Spring Boot 3.2.0-RC2 來嘗試一下。 如果您有增強的想法或發現錯誤,請隨時在 我們的跟蹤器上提出問題。