本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
憑證撤銷
當憑證因入侵、政策變更或終止的關係而需要撤銷時,您需要在 mTLS 交握期間拒絕這些憑證的機制。CloudFront 提供兩種憑證撤銷的原生方法,您可以結合它們進行分層控制。
-
OCSP (線上憑證狀態通訊協定) — CloudFront 會即時查詢憑證授權單位的 OCSP 回應程式,以檢查用戶端憑證是否已撤銷。在信任存放區上啟用 OCSPCloudFront 會在 TLS 交握期間自動處理驗證。OCSP 結果也會顯示在 Connection Functions 中,讓您以程式設計方式存取撤銷狀態以進行自訂決策。
-
CloudFront Functions 和 KeyValueStore — 您可以在 CloudFront KeyValueStore 中維護撤銷的憑證序號清單。連線函數會在 TLS 交握期間查詢 KeyValueStore,並允許或拒絕連線。這可讓您完全控制撤銷資料、更新時間,以及自訂邏輯,例如寬限期或 IP 型例外狀況。
| OCSP | CloudFront 函數 + KeyValueStore | |
|---|---|---|
| 資料來源 | 憑證授權單位的 OCSP 回應程式 | 您可以管理撤銷清單 |
| 更新機制 | CA 的即時查詢 | 您將更新推送至 KeyValueStore |
| 自訂邏輯 | 透過 Connection Functions 提供 | 內建於函數程式碼中 |
| 外部相依性 | 需要 CA OCSP 回應程式可用性 | 無外部相依性 |
| 最適合 | 維護 OCSP 回應者的 CAs;即時 CA 授權狀態 | 自我管理撤銷;自訂政策;無 OCSP 支援的 CAs |
您可以同時使用這兩種方法。啟用 OCSP 進行 CA 授權撤銷檢查,然後使用連線函數在 OCSP 結果之上分層其他邏輯,例如,允許在寬限期內從信任的 IP 範圍撤銷憑證。
OCSP (線上憑證狀態通訊協定)
OCSP 是一種即時通訊協定,可直接向憑證授權單位 (CA) 檢查憑證的撤銷狀態。在憑證簽署程序期間,CA 會在憑證中嵌入 OCSP 回應程式 URL。當用戶端在 mTLS 交握期間呈現其憑證時,CloudFront 會將 OCSP 請求傳送至內嵌的回應程式 URL,並對回應採取動作:有效憑證繼續,撤銷的憑證會終止。
CloudFront 會根據各自的 OCSP 回應程式 URLs,驗證整個憑證鏈:分葉憑證和最多三個中繼憑證。信任存放區中的根憑證會從 OCSP 驗證中排除。
啟用 OCSP
在信任存放區上啟用 OCSP。啟用時,CloudFront 會自動對其授權資訊存取 (AIA) 延伸模組中包含 OCSP 回應者 URL 的任何用戶端憑證執行 OCSP 驗證。啟用 OCSP 後,整個用戶端憑證鏈必須具有 OCSP URL。如果用戶端憑證鏈中的任何憑證不包含 OCSP URL,CloudFront 將不會建立連線。
CloudFront 會在邊緣快取 OCSP 回應,以減少往返時間並防止 OCSP 回應程式停機時間。OCSP 回應會快取約 30 分鐘,而更新的撤銷狀態最多可能需要 30 分鐘才會反映。
OCSP 會產生連線函數
在相同分佈上設定連線函數時,CloudFront 會在 OCSP 驗證完成後叫用它。連線物件包含分葉和中繼憑證的 OCSP 狀態:
{ "clientCertificate": { "certificates": { "leaf": { "subject": "CN=client.example.com, O=Example Org", "issuer": "CN=Intermediate CA, O=Example Org", "serialNumber": "00:a7:30:9e:73:7b:3e:63:bd:b7:c0:7e:bf:d5:c9:86", "validity": { "notBefore": "2024-01-01T00:00:00Z", "notAfter": "2025-01-01T00:00:00Z" }, "sha256Fingerprint": "AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90", "ocspEndpoint": "http://ocsp.example.org" }, "intermediates": [ { "subject": "CN=Intermediate CA, O=Example Org", "issuer": "CN=Root CA, O=Example Org", "serialNumber": "00:a7:30:9e:73:7b:3e:63:bd:b7:c0:7e:bf:d5:c9:86", "validity": { "notBefore": "2020-01-01T00:00:00Z", "notAfter": "2030-01-01T00:00:00Z" }, "sha256Fingerprint": "12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF", "ocspEndpoint": "http://ocsp.example.org" } ] }, "revocationStatus": { "chainValidity": "Valid", // "Valid" | "Invalid" | "Unknown" "certificates": { "leaf": { "method": "OCSP", // "OCSP" "status": "Good", // "Good" | "Revoked" | "Unknown" | "Error" "serialNumber": "00:a7:30:9e:73:7b:3e:63:bd:b7:c0:7e:bf:d5:c9:86" }, "intermediates": [ { "method": "OCSP", // "OCSP" "status": "Error", // "Good" | "Revoked" | "Unknown" | "Error" "errorType": "InternalError", // "InternalError" | "OCSP response verification failed: {Type}" "serialNumber": "00:a7:30:9e:73:7b:3e:63:bd:b7:c0:7e:bf:d5:c9:86" } ] } } }, "clientIp":"127.0.0.1", "endpoint":"d123.cloudfront.net", "distributionId":"E1NXS4MQZH501R", "connectionId":"xdzQ6lJUDUt8b7OuqOD8lmzOC9HcMaXPmhH5ZdzLCZpKxqzfCPpR4A==" }
chainValidity 欄位可以是 Valid、 Invalid或 Unknown。個別憑證status值可以是 Good、Unknown、 Revoked或 Error。當狀態為 OCSP response verification failed: {Type}時, errorType 欄位包含 InternalError或 Error。
連線函數可以覆寫 OCSP 結果 – 例如,允許從信任 IP 範圍撤銷的憑證,或拒絕 OCSP 根據其他商業邏輯回報為「良好」的憑證。
注意
只有當狀態為 時, errorType 欄位才會出現Error。
範例:具有信任 IP 例外狀況的自訂 OCSP 處理
function connectionHandler(connection) { var revocationStatus = connection.clientCertificate.revocationStatus; var trustedIP = (connection.clientIp === "[IP_ADDRESS]"); if (revocationStatus.chainValidity === "Invalid") { if (trustedIP) { connection.allow(); } else { connection.deny(); } } else if (revocationStatus.certificates.leaf.status === "Error") { console.log(revocationStatus.certificates.leaf.errorType); connection.deny(); } else { connection.allow(); } }
OCSP 失敗行為
當 CloudFront 無法判斷憑證的撤銷狀態時,因為 OCSP 回應程式無法連線、 傳回錯誤或傳回「未知」時,CloudFront 預設會拒絕連線。若要實作軟失敗行為,請使用連線函數。如果啟用 OCSP 且用戶端憑證中沒有 OCSP URL,則不會執行連線函數。OCSP 結果可在連線物件中使用,而您的函數可以在 OCSP 狀態未確定時允許連線:
async function connectionHandler(connection) { var revocationStatus = connection.clientCertificate.revocationStatus; if (revocationStatus.certificates.leaf.status === "Error" || revocationStatus.certificates.leaf.status === "Unknown") { // OCSP responder unreachable — allow connection (soft-fail) connection.logCustomData(`OCSP_SOFT_FAIL:${revocationStatus.certificates.leaf.errorType}`); return connection.allow(); } if (revocationStatus.chainValidity === "Invalid") { return connection.deny(); } return connection.allow(); }
CloudFront Functions 和 KeyValueStore 的憑證撤銷
您可以使用 CloudFront Connection Functions 搭配 KeyValueStore 實作憑證撤銷檢查,而不需要任何外部相依性。您可以在 KeyValueStore 中維護撤銷的憑證序號清單,而且連線函數會在 TLS 交握期間針對此清單檢查每個用戶端憑證。
憑證撤銷程序的運作方式如下:
-
將撤銷的憑證序號儲存在 CloudFront KeyValueStore 中。
-
當用戶端提供憑證時,就會叫用您的連線函數。
-
函數會根據 KeyValueStore 檢查憑證的序號。
-
如果在存放區中找到序號,則會撤銷憑證。
-
您的函數拒絕已撤銷憑證的連線。
此方法提供跨 CloudFront 全球邊緣網路的near-real-time撤銷檢查。
若要實作此方法,您需要:
-
使用檢視器 mTLS 設定的分佈
-
包含撤銷憑證序號的 KeyValueStore
-
查詢 KeyValueStore 以檢查憑證狀態的連線函數
當用戶端連線時,CloudFront 會根據信任存放區驗證憑證,然後執行連線函數。您的函數會根據 KeyValueStore 檢查憑證序號,並允許或拒絕連線。
步驟 1:為已撤銷的憑證建立 KeyValueStore
以 JSON 格式準備您撤銷的憑證序號:
{ "data": [ { "key": "ABC123DEF456", "value": "" }, { "key": "789XYZ012GHI", "value": "" } ] }
將此 JSON 檔案上傳至 S3 儲存貯體,然後建立 KeyValueStore:
aws s3 cp revoked-serials.json s3://your-bucket-name/revoked-serials.json aws cloudfront create-key-value-store \ --name revoked-serials-kvs \ --import-source '{ "SourceType": "S3", "SourceARN": "arn:aws:s3:::your-bucket-name/revoked-serials.json" }'
等待 KeyValueStore 完成佈建。使用 檢查狀態:
aws cloudfront get-key-value-store --name "revoked-serials-kvs"
步驟 2:建立撤銷連線函數
建立連線函數,根據 KeyValueStore 檢查憑證序號:
aws cloudfront create-connection-function \ --name "revocation-control" \ --connection-function-config file://connection-function-config.json \ --connection-function-code file://connection-function-code.txt
組態檔案會指定 KeyValueStore 關聯:
{ "Runtime": "cloudfront-js-2.0", "Comment": "A function that implements revocation control via KVS", "KeyValueStoreAssociations": { "Quantity": 1, "Items": [ { "KeyValueStoreArn": "arn:aws:cloudfront::account-id:key-value-store/kvs-id" } ] } }
連線函數程式碼範例:
import cf from 'cloudfront'; async function connectionHandler(connection) { const kvsHandle = cf.kvs(); // Get client serial number from client certificate const clientSerialNumber = connection.clientCertificate.certificates.leaf.serialNumber; // Check KVS to see if serial number exists as a key // Remove : from the clientSerialNumber if KVS entries dont have it const serialNumberExistsInKvs = await kvsHandle.exists(clientSerialNumber.replaceAll(":", "")); // Deny connection if serial number exists in KVS if (serialNumberExistsInKvs) { console.log("Connection denied — certificate revoked"); connection.logCustomData("Connection denied — certificate revoked"); return connection.deny(); } // Allow connections that don't exist in KVS console.log("Connection allowed"); return connection.allow(); }
步驟 3:測試您的撤銷函數
使用 CloudFront 主控台以範例憑證測試連線函數。導覽至 主控台中的連線函數,並使用測試索引標籤。
-
將 PEM 格式的範例憑證貼入測試界面。
-
選擇性地指定用戶端 IP 地址,以測試 IP 型邏輯。
-
選擇測試函數以查看執行結果。
-
檢閱執行日誌以驗證您的函數邏輯。
使用有效和已撤銷的憑證進行測試,以確保函數正確處理這兩種案例。
步驟 4:將函數與分佈建立關聯
發佈連線函數後,請將其與啟用 mTLS 的分佈建立關聯,以啟用憑證撤銷檢查。導覽至您的分佈設定,捲動至「檢視者交互驗證 (mTLS)」區段,選取連線函數,然後儲存變更。
進階撤銷策略
結合 OCSP 與連線函數邏輯
您可以為 CA 授權撤銷檢查啟用 OCSP,並在自訂政策的頂端分層連線函數。Connection Function 會收到 OCSP 結果,並可套用其他邏輯:
-
寬限期 — 允許在憑證輪換期間,在定義的期間內從內部網路撤銷憑證。
-
緊急存取 — 即使 OCSP 報告撤銷狀態,也允許來自特定 IPs連線。
-
自訂拒絕邏輯 — 根據您在 KeyValueStore 中的撤銷資料,封鎖 OCSP 報告為「良好」的憑證。
範例 OCSP + KVS 合併撤銷
import cf from 'cloudfront'; async function connectionHandler(connection) { var kvsHandle = cf.kvs(); var revocationStatus = connection.clientCertificate.revocationStatus; var serialNumber = connection.clientCertificate.certificates.leaf.serialNumber; // Check your own revocation list first (immediate revocation, no cache delay) var inKvs = await kvsHandle.exists(serialNumber.replaceAll(":", "")); if (inKvs) { connection.logCustomData("KVS_REVOKED:" + serialNumber); return connection.deny(); } // Then check OCSP result if (revocationStatus.chainValidity === 'Valid' && revocationStatus.certificates.leaf.status === "Revoked") { // OCSP says revoked — allow grace period from trusted IPs if (connection.clientIp.startsWith("10.0.")) { connection.logCustomData("GRACE_PERIOD:" + serialNumber + ":" + connection.clientIp); return connection.allow(); } connection.logCustomData("OCSP_REVOKED:" + serialNumber); return connection.deny(); } connection.allow(); }
此模式可讓您透過 KVS (無快取延遲) 進行立即撤銷,並透過 OCSP 進行 CA 授權撤銷,並在兩者之間處理自訂例外狀況。