本指南提供操作說明,說明如何設定 NGINX,以便在 Debian 11 (Bullseye) 上使用 Cloud HSM 金鑰來卸載 TLS。您可能需要修改這些指令,才能與 OS 或 Linux 發行版本搭配使用。
您可以在 kms-solutions GitHub 存放區中,找到以 Terraform 為基礎的藍圖版本教學課程。
用途
搭配使用 Cloud HSM 金鑰和 NGINX 的 TLS 卸載功能,有助於滿足下列企業安全需求:
- 您希望 NGINX 網路伺服器將 TLS 加密編譯作業卸載至 Cloud HSM。
- 您不想將憑證的私密金鑰儲存在託管網路應用程式的 Compute Engine 執行個體本機檔案系統中。
- 您必須遵守法規規定,公開應用程式需要由經 FIPS 140-2 第 3 級認證的 HSM 保護憑證。
- 您想使用 NGINX 建立具備 TLS 終止功能的反向 Proxy,以保護網頁應用程式。
事前準備
請先完成「使用 OpenSSL 搭配 Cloud HSM 金鑰」中的步驟,再繼續操作。
完成 OpenSSL 設定後,請確認已安裝最新版本的 nginx
:
sudo apt-get update
sudo apt-get install libengine-pkcs11-openssl opensc nginx
安全性設定建議
請按照下列建議,保護代管 NGINX 的執行個體:
請按照建立及啟用執行個體的服務帳戶操作說明,代管 NGINX。
- 指派下列角色:
roles/cloudkms.signerVerifier
roles/cloudkms.viewer
- 指派下列角色:
如要限制外部 IP 和服務帳戶金鑰建立功能,請設定機構政策,如下所示。
constraints/compute.vmExternalIpAccess
constraints/iam.disableServiceAccountKeyCreation
建立自訂子網路,啟用私人 Google 存取權。
設定防火牆規則。
- 請只為 SSH 建立 IAP 防火牆規則。
建立 Linux VM,並按照以下步驟進行設定:
- 選取先前建立的正確服務帳戶。
- 選取先前建立的網路。
- 為所有防火牆規則新增適當的標籤。
- 確認子網路的「外部 IP」欄位已設為
none
。
在執行個體上授予身分「受 IAP 保護的通道使用者」(
roles/iap.tunnelResourceAccessor
) 角色。- 如要進一步瞭解相關資訊,請參閱「Compute 的 IAP 設定」。
建立及設定由 Cloud KMS 代管的簽署金鑰
接下來幾節將詳細說明如何建立及設定 Cloud KMS 代管的簽署金鑰。
建立由 Cloud KMS 代管的簽署金鑰
在Google Cloud 專案中,使用先前為 OpenSSL 設定的金鑰環,建立 Cloud KMS EC-P256-SHA256
簽署金鑰:
gcloud kms keys create NGINX_KEY \
--keyring "KEY_RING" --project "PROJECT_ID" \
--location "LOCATION" --purpose "asymmetric-signing" \
--default-algorithm "ec-sign-p256-sha256" --protection-level "hsm"
使用 IAP 透過 SSH 存取 VM
使用 IAP 搭配下列指令,透過 SSH 連線至 VM:
gcloud compute ssh INSTANCE \
--zone ZONE --tunnel-through-iap
如果遇到問題,請確認您已使用 --tunnel-through-iap
標記。此外,請確認您已為透過 gcloud CLI 驗證的身分識別資訊,在執行個體上設定「受 IAP 保護的通道使用者」(roles/iap.tunnelResourceAccessor
) 角色。
使用 OpenSSL 建立憑證
如果是實際工作環境,請建立憑證簽署要求 (CSR)。如要進一步瞭解如何產生 CSR,請參閱範例。將 CSR 提供給憑證授權單位 (CA),讓他們為您建立憑證。在後續章節中使用 CA 提供的憑證。
您可以使用 Cloud KMS 代管的簽署金鑰,產生自行簽署的憑證,以供示範用途。為此,OpenSSL 可讓您使用 PKCS #11 URI 而非一般路徑,透過標籤識別金鑰 (對於 Cloud KMS 金鑰,標籤即為 CryptoKey 名稱)。
openssl req -new -x509 -days 3650 -subj '/CN=CERTIFICATE_NAME/' \
DIGEST_FLAG -engine pkcs11 -keyform engine \
-key PKCS_KEY_TYPE=KEY_IDENTIFIER > CA_CERT
更改下列內容:
CERTIFICATE_NAME
:憑證的名稱。DIGEST_FLAG
:非對稱式簽署金鑰使用的摘要演算法。視鍵而定,使用-sha256
、-sha384
或-sha512
。PKCS_KEY_TYPE
:用於識別金鑰的 ID 類型。如要使用最新的金鑰版本,請使用pkcs11:object
搭配金鑰名稱。如要使用特定金鑰版本,請使用pkcs11:id
搭配金鑰版本的完整資源 ID。KEY_IDENTIFIER
:鍵的 ID。如果您使用pkcs11:object
,請使用金鑰名稱,例如NGINX_KEY
。如果您使用pkcs11:id
,請使用金鑰或金鑰版本的完整資源 ID,例如projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/NGINX_KEY/cryptoKeyVersions/KEY_VERSION
。CA_CERT
:要儲存憑證檔案的路徑。
如果指令失敗,表示 PKCS11_MODULE_PATH
可能設定不正確,或是您沒有使用 Cloud KMS 簽署金鑰的正確權限。
您現在應該會看到類似下方的證書:
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
安裝 NGINX 憑證
執行下列指令,建立公用憑證的放置位置:
sudo mkdir /etc/ssl/nginx
sudo mv CA_CERT /etc/ssl/nginx
設定環境以使用 PKCS #11 程式庫
接下來幾節將詳細說明準備及測試環境所需的步驟。
為 NGINX 準備程式庫設定
允許 NGINX 使用下列程式庫記錄 PKCS #11 引擎作業:
sudo mkdir /var/log/kmsp11
sudo chown www-data /var/log/kmsp11
建立空白程式庫設定檔,並為 NGINX 設定適當權限。
sudo touch /etc/nginx/pkcs11-config.yaml
sudo chmod 744 /etc/nginx/pkcs11-config.yaml
編輯空白設定檔,並新增所需設定,如以下程式碼片段所示:
# cat /etc/nginx/pkcs11-config.yaml
---
tokens:
- key_ring: "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING"
log_directory: "/var/log/kmsp11"
測試 OpenSSL 設定
執行下列指令:
openssl engine -tt -c -v pkcs11
畫面會顯示類似以下的輸出:
(pkcs11) pkcs11 engine
[RSA, rsaEncryption, id-ecPublicKey]
[ available ]
SO_PATH, MODULE_PATH, PIN, VERBOSE, QUIET, INIT_ARGS, FORCE_LOGIN
設定 NGINX 使用 Cloud HSM
編輯幾個 NGINX 檔案,允許 TLS 卸載。首先,請在兩個位置編輯 /etc/nginx/nginx.conf
檔案,新增幾個指示來設定 NGINX 使用 PKCS #11。
在 event
區塊之後,但在 http
區塊之前,新增下列指示:
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
在同一個 /etc/nginx/nginx.conf
檔案中,設定 SSL 指令,以便在 Cloud HSM 中使用憑證和私密金鑰。在 http
區塊中加入下列屬性:
ssl_certificate "/etc/ssl/nginx/CA_CERT";
ssl_certificate_key "engine:pkcs11:PKCS_KEY_TYPE=KEY_IDENTIFIER";
ssl_protocols TLSv1.2 TLSv1.3; # Consider changing the default to only TLS1.2 or newer
# Consider defining the `ssl_ciphers` to use ciphers approved by your security teams and handle
# appropriate client compatibility requirements.
/etc/nginx/nginx.conf
檔案應如下所示:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
http {
#...
#...
# SSL configuration
ssl_certificate "/etc/ssl/nginx/CA_CERT";
ssl_certificate_key "engine:pkcs11:pkcs11:object=NGINX_KEY";
ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
# ssl_ciphers YOUR_CIPHERS
ssl_prefer_server_ciphers on;
#...
#...
}
設定 NGINX 以監聽 TLS 流量
編輯 /etc/nginx/sites-enabled/default
檔案,以便監聽 TLS 流量。取消註解 server
區塊中的 SSL 設定。結果應如下所示:
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# ...
# ...
}
為 NGINX 服務提供環境變數
執行下列指令:
sudo systemctl edit nginx.service
在產生的編輯器中,新增下列行,並將 LIBPATH
替換為您安裝 libkmsp11.so
的位置的值:
[Service]
Environment="GRPC_ENABLE_FORK_SUPPORT=1"
Environment="KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml"
Environment="PKCS11_MODULE_PATH=LIBPATH/libkmsp11-1.0-linux-amd64/libkmsp11.so"
設定這些值後,您必須執行下列指令才能使用這些值:
sudo systemctl daemon-reload
使用 TLS Offloading 重新啟動 NGINX
執行下列指令,讓 NGINX 重新啟動並使用更新的設定:
sudo systemctl start nginx
測試 NGINX 是否使用 TLS 將工作卸載至 Cloud HSM
使用 openssl s_client
執行下列指令,測試與 NGINX 伺服器的連線:
openssl s_client -connect localhost:443
用戶端應完成 SSL 交握並暫停。如以下所示,用戶端正在等待您的輸入內容:
# completes SSL handshake
# ...
# ...
# ...
Verify return code: 18 (self signed certificate)
# ...
Max Early Data: 0
---
read R BLOCK
# When the client pauses, it’s waiting for instructions.
# Have the client get the index.html file in the root path (“/”), by typing the following:
GET /
# Press enter.
# You should now see the default NGINX index.html file.
稽核記錄現在應會顯示 NGINX_KEY
索引鍵的作業。如要查看記錄,請在雲端控制台中前往 Cloud Logging。在您使用的專案中,新增下列篩選器:
resource.type="cloudkms_cryptokeyversion"
執行查詢後,您應該會看到 NGINX_KEY
金鑰的非對稱金鑰作業。
選用設定
您可能需要建立外部直通式網路負載平衡器,才能透過外部 IP 公開 NGINX 伺服器。
如果您需要使用 NGINX 做為負載平衡的反向 Proxy,請考慮更新 NGINX 設定檔。如要進一步瞭解如何將 NGINX 設為反向 Proxy,請參閱「Google Cloud Platform 上 NGINX Plus 的 All-Active HA」。
後續步驟
您現在已將 NGINX 伺服器設為使用 TLS 卸載至 Cloud HSM。