問題: “我可以在 git 中管理所有 K8s 配置,除了 Secrets。”
解決方案:將您的 Secret 加密到 SealedSecret 中,即使在公共儲存庫中也可以安全儲存。 SealedSecret 只能由目標叢集中執行的控制器解密,其他人(甚至原作者)都無法從 SealedSecret 中取得原始 Secret。
概述
SealedSecrets 作為秘密的模板
公鑰/憑證
範圍
安裝
自製
Mac埠
Linux
從來源安裝
客製化
舵圖
控制器
庫貝密封
升級
用法
管理現有秘密
修補現有秘密
更新現有機密
原始模式(實驗)
驗證密封的秘密
秘密輪換
密封鑰匙更新
使用者秘密輪換
提前更新密鑰
關於密鑰更新的常見誤解
手動密鑰管理(進階)
重新加密(進階)
詳細資訊(進階)
加密貨幣
發展
常問問題
如果您無法再存取集群,您仍然能夠解密嗎?
我如何備份我的 SealedSecrets?
我可以使用備份金鑰離線解密我的秘密嗎?
kubeseal 有哪些可用標誌?
如何更新使用密封秘密加密的 JSON/YAML/TOML/.. 檔案的部分內容?
我可以攜帶自己的(預先產生的)證書嗎?
如果控制器不在kube-system
命名空間內運行,如何使用 kubeseal?
如何驗證影像?
如何將一個控制器用於命名空間的子集
我可以設定控制器開封重試嗎
社群
相關項目
密封的秘密由兩個部分組成:
集群端控制器/操作員
客戶端實用程式: kubeseal
kubeseal
實用程式使用非對稱加密來加密只有控制器才能解密的秘密。
這些加密的機密被編碼在SealedSecret
資源中,您可以將其視為創建機密的秘訣。它看起來是這樣的:
api版本:bitnami.com/v1alpha1kind:SealedSecretmetadata:名稱:mysecret命名空間:mynamespacespec:加密資料:foo:AgBy3i4OJSWK + PiTySYZZA9rO43cGDEq.....
一旦解封,這將產生一個與此等效的秘密:
apiVersion: v1kind: Secretmetadata: name: mysecret 命名空間: mynamespacedata: foo: YmFy # <- base64 編碼的“bar”
幾秒鐘後,這個正常的 kubernetes 金鑰將出現在叢集中,您可以像使用直接建立的任何金鑰一樣使用它(例如,從Pod
引用它)。
跳到安裝部分以啟動並運行。
使用部分更詳細地探討如何製作SealedSecret
資源。
前面的範例只關注加密的秘密專案本身,但SealedSecret
自訂資源與其解封到的Secret
之間的關係在許多方面(但不是全部)與熟悉的Deployment
與Pod
類似。
特別是, SealedSecret
資源的註釋和標籤與從中產生的Secret
的註釋不同。
為了捕捉這種區別, SealedSecret
物件有一個template
部分,它對您希望控制器放入未密封Secret
中的所有欄位進行編碼。
除了預設的 Go 文字範本函數之外,還可以使用 Sprig 函數庫。
metadata
區塊按原樣複製( ownerReference
欄位將更新,除非停用)。
其他秘密字段單獨處理。複製type
和immutable
字段,且data
字段可用於在Secret
上模板化複雜值。目前忽略所有其他字段。
apiVersion:bitnami.com/v1alpha1kind:SealedSecretmetadata:名稱:mysecret 命名空間:mynamespace 註釋:「kubectl.kubernetes.io/last-applied-configuration」:....spec:加密資料:.dockerconfigjson:AgB .. . template: type: kubernetes.io/dockerconfigjson immutable: true # 這是將添加到輸出秘密元資料中的標籤和註解的範例: labels: "jenkins.io/credentials-type": usernamePassword comments: "jenkins . io/credentials-description":來自 Kubernetes 的憑證
控制器會將其解封為以下內容:
apiVersion:v1kind:Secretmetadata:名稱:mysecret 命名空間:mynamespace 標籤:「jenkins.io/credentials-type」:使用者名稱密碼註解:「jenkins.io/credentials-description」:來自 Kubernetes 擁有者的憑證參考: - api版本:bitnami.com/v1alpha1 控制器:真實種類:SealedSecret 名稱:mysecret uid:5caff6a0-c9ac-11e9-881e-42010aac003etype:kubernetes.io/dockerconfigjsonim-42010aac003etype:kubernetes.io/dockerconfigjsonimmutable:true:+cmdom
正如您所看到的,產生的Secret
資源是SealedSecret
的“依賴物件”,因此每當SealedSecret
物件更新或刪除時,它都會被更新和刪除。
密鑰憑證(公鑰部分)用於密封秘密,並且在任何要使用kubeseal
的地方都需要可用。該證書不是秘密訊息,但您需要確保使用正確的證書。
kubeseal
會在運行時從控制器取得憑證(需要安全存取Kubernetes API 伺服器),這方便互動使用,但眾所周知,當使用者擁有具有特殊配置的叢集(例如之間有防火牆的私有GKE 叢集)時,它會很脆弱。
另一個工作流程是使用kubeseal --fetch-cert >mycert.pem
將憑證儲存在某處(例如本機磁碟),並使用kubeseal --cert mycert.pem
離線使用它。該證書也會在啟動時列印到控制器日誌中。
自 v0.9.x 起,證書每 30 天自動更新一次。您和您的團隊定期更新離線憑證是一個很好的做法。為了幫助您解決這個問題,從 v0.9.2 開始, kubeseal
也接受 URL。您可以設定內部自動化以在您信任的地方發布證書。
kubeseal --cert https://your.intranet.company.com/sealed-secrets/your-cluster.cert
它還可以識別SEALED_SECRETS_CERT
環境變數。 (專業提示:另請參閱 direnv)。
注意:我們正在致力於提供金鑰管理機制,將加密卸載到基於 HSM 的模組或託管雲端加密解決方案(例如 KMS)。
SealedSecrets 是來自最終用戶的 POV 的「只寫」設備。
這個想法是,SealedSecret 只能由目標叢集中運行的控制器解密,其他人(甚至原作者)都無法從 SealedSecret 中取得原始 Secret。
使用者可能有也可能沒有直接存取目標群集的權限。更具體地說,使用者可能有權利也可能無權存取由控制器解封的 Secret。
在 k8s 上配置 RBAC 的方法有很多種,但禁止低權限使用者讀取 Secrets 是很常見的。為使用者提供一個或多個具有更高權限的命名空間也很常見,這將允許他們建立和讀取機密(和/或建立可以引用這些機密的部署)。
加密的SealedSecret
資源旨在安全地查看,而無需了解其隱藏的秘密。這意味著我們不能允許用戶讀取用於他們無權訪問的命名空間的 SealedSecret,而只是將其副本推送到他們可以從中讀取機密的命名空間中。
因此,密封秘密的行為就像每個命名空間都有自己獨立的加密金鑰一樣,因此一旦您密封了命名空間的秘密,它就無法移動到另一個命名空間並在那裡解密。
從技術上講,我們並沒有為每個命名空間使用獨立的私鑰,而是在加密過程中包含命名空間名稱,從而有效地達到相同的結果。
此外,命名空間並不是 RBAC 配置可以決定誰可以看到哪個秘密的唯一層級。事實上,使用者可以存取給定名稱空間中名為foo
的機密,但不能存取同一名稱空間中的任何其他機密。因此,預設情況下,我們不能讓使用者自由重命名SealedSecret
資源,否則惡意使用者只需重命名該名稱空間以覆蓋使用者有權存取的一個秘密,就能夠解密該命名空間的任何 SealedSecret。我們使用與在加密金鑰中包含命名空間相同的機制來包含秘密名稱。
也就是說,在很多情況下您可能不關心這種程度的保護。例如,唯一有權存取叢集的人要么是管理員,要么根本無法讀取任何Secret
資源。您可能有一個將密封秘密移動到其他命名空間的用例(例如,您可能不知道預先命名空間名稱),或者您可能不知道秘密的名稱(例如,它可能包含基於該秘密的雜湊值的唯一後綴)內容等)。
這些是可能的範圍:
strict
(預設):秘密必須使用完全相同的名稱和名稱空間進行密封。這些屬性成為加密資料的一部分,因此更改名稱和/或命名空間將導致「解密錯誤」。
namespace-wide
:您可以在給定命名空間內自由重命名密封的秘密。
cluster-wide
:秘密可以在任何名稱空間中解封,並且可以指定任何名稱。
與name和namespace的限制相反,秘密項目(即 JSON 物件金鑰,如spec.encryptedData.my-key
)可以隨意重新命名,而不會失去解密密封秘密的能力。
使用--scope
標誌選擇範圍:
kubeseal --scope 集群範圍sealed-secret.json
也可以透過傳遞給kubeseal
輸入金鑰中的註解來請求範圍:
sealedsecrets.bitnami.com/namespace-wide: "true"
-> 用於namespace-wide
sealedsecrets.bitnami.com/cluster-wide: "true"
-> 適用於cluster-wide
缺少任何此類註釋都意味著strict
模式。如果兩者都設置,則cluster-wide
優先。
注意:下一個版本將把它合併到一個單一的
sealedsecrets.bitnami.com/scope
註解中。
請參閱 https://github.com/bitnami-labs/sealed-secrets/releases 以了解最新版本和詳細安裝說明。
雲端平台具體注意事項及說明:
吉凱
部署清單後,它將建立SealedSecret
資源並將控制器安裝到kube-system
命名空間中,建立服務帳戶和必要的 RBAC 角色。
片刻之後,控制器將啟動,產生密鑰對,並準備好運行。如果沒有,請檢查控制器日誌。
官方控制器清單安裝機制只是一個 YAML 檔案。
在某些情況下,您可能需要套用自己的自訂設置,例如設定自訂命名空間或設定一些環境變數。
kubectl
對此有原生支持,請參閱 kustomize。
Sealed Secrets helm 圖表已正式支援並託管在此 GitHub 儲存庫中。
helm 倉庫加入密封秘密 https://bitnami-labs.github.io/sealed-secrets
注意:Helm Chart 的版本控制方案與密封秘密專案本身的版本控制方案不同。
最初 Helm Chart 是由社群維護的,第一個版本採用了主要版本 1,而 Sealed Secrets 專案本身仍然是主要版本 0。然而這很令人困惑,所以我們目前的版本控制規則是:
SealedSecret
控制器版本方案:0.XY
helm圖表版本方案:1.XY-rZ
因此,Helm Chart 可以有多個修訂版,其中的修復僅適用於 Helm Chart,而不會影響靜態 YAML 清單或控制器映像本身。
注意:Helm Chart 自述文件仍然包含棄用通知,但它不再反映現實,並將在下一個版本中刪除。
注意:Helm Chart 預設安裝名為
sealed-secrets
控制器,而kubeseal
命令列介面 (CLI) 嘗試存取名為sealed-secrets-controller
控制器。您可以明確地將--controller-name
傳遞給 CLI:
kubeseal --控制器名稱封印秘密
或者,您可以在安裝圖表時設定fullnameOverride
以覆蓋名稱。另請注意, kubeseal
假定控制器預設安裝在kube-system
命名空間內。因此,如果您想使用kubeseal
CLI 而無需傳遞預期的控制器名稱和命名空間,您應該像這樣安裝 Helm Chart:
helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets
在某些公司中,您可能只能存取單一名稱空間,而不是完整的叢集。
您可能遇到的最嚴格的環境之一是:
已使用某個service account
為您指派了一個namespace
。
您無權存取叢集的其餘部分,甚至無法存取叢集 CRD。
您甚至可能無法在命名空間中建立更多服務帳戶或角色。
您需要在所有部署中包含資源限制。
即使有這些限制,您仍然可以安裝密封的 Helm Chart,只有一個先決條件:
叢集必須已經安裝了密封的機密 CRD 。
一旦您的管理員安裝了 CRD(如果它們尚不存在),您可以透過準備 YAML 設定檔來安裝圖表,如下所示:
服務帳號: 創作:假 名稱:{已指派的服務帳戶} RBAC: 創作:假 clusterRole:錯誤資源: 限制: 中央處理器:150m 內存:256Mi
注意:
不會建立服務帳戶,而是使用指派給您的服務帳戶。
{allocated-service-account}
service account
帳戶的名稱。
命名空間和叢集中都不會建立 RBAC 角色。
必須指定資源限制。
這些限制是應該有效的範例,但您可能需要在特定設定中查看它們。
該檔案準備好後,如果將其命名為config.yaml
現在可以安裝密封的機密 Helm Chart,如下所示:
helm install seal-secrets -n {分配的命名空間} sealed-secrets/sealed-secrets --skip-crds -f config.yaml
其中{allocated-namespace}
是您在叢集中指派的namespace
空間的名稱。
kubeseal
客戶端也可在自製軟體上使用:
沖泡安裝 kubeseal
kubeseal
客戶端也可在 MacPorts 上使用:
端口安裝 kubeseal
Nixpkgs 上也提供了kubeseal
客戶端:(免責聲明:不是由 bitnami-labs 維護)
nix-env -iA nixpkgs.kubeseal
可以使用以下指令在 Linux 上安裝kubeseal
用戶端:
KUBESEAL_VERSION='' # 將其設定為,例如 KUBESEAL_VERSION='0.23.0'curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?} / kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz"tar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
如果您的電腦上安裝了curl
和jq
,則可以透過這種方式動態取得版本。這對於自動化等使用的環境非常有用。
# Fetch the latest sealed-secrets version using GitHub API KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/tags | jq -r '.[0].name' | cut -c 2-) # Check if the version was fetched successfully if [ -z "$KUBESEAL_VERSION" ]; then echo "Failed to fetch the latest KUBESEAL_VERSION" exit 1 fi curl -OL "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz" tar -xvzf kubeseal-${KUBESEAL_VERSION}-linux-amd64.tar.gz kubeseal sudo install -m 755 kubeseal /usr/local/bin/kubeseal
其中KUBESEAL_VERSION
是您要使用的 kubeseal 版本的版本標記。例如: v0.18.0
。
如果您只需要最新的客戶端工具,可以使用以下命令將其安裝到$GOPATH/bin
中:
去安裝 github.com/bitnami-labs/sealed-secrets/cmd/kubeseal@main
您可以指定發布標籤或提交 SHA 而不是main
。
go install
指令會將kubeseal
進位檔案放置在$GOPATH/bin
:
$(go env GOPATH)/bin/kubeseal
升級用戶端工具和/或控制器時,不要忘記查看發行說明,以獲取有關可能發生的重大變更的指導。
目前,生產環境僅支援最新版本的 Sealed Secrets。
Sealed Secrets 控制器依靠穩定的 Kubernetes API 來確保與不同版本 Kubernetes 的兼容性。通常,1.16 以上的 Kubernetes 版本被認為是相容的。但是,我們官方支援目前推薦的 Kubernetes 版本。此外,1.24 以上的版本在每個版本中都會透過我們的 CI 流程進行徹底驗證。
# 以某種方式建立一個 json/yaml 編碼的 Secret:# (注意使用 `--dry-run` - 這只是一個本地檔案!)echo -n bar | kubectl create Secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json# 這是重要的一點:kubeseal -f mysecret.json -w mysealedsecret.json#此時mysealedsecret.json 可以安全地上傳到Github,# 在Twitter 上發布,等等。
請注意, SealedSecret
和Secret
必須具有相同的命名空間和名稱。此功能可防止同一叢集上的其他使用者重複使用您的密封機密。有關詳細信息,請參閱範圍部分。
kubeseal
從輸入金鑰中讀取命名空間,接受明確的--namespace
參數,並使用kubectl
預設命名空間(按該順序)。原始Secret
上的任何標籤、註釋等都會保留,但不會自動反映在SealedSecret
中。
根據設計,該方案不對使用者進行身份驗證。換句話說,任何人都可以創建一個包含他們喜歡的任何Secret
SealedSecret
(只要命名空間/名稱匹配)。這取決於您現有的組態管理工作流程、叢集 RBAC 規則等,以確保僅將預期的SealedSecret
上傳到叢集。與現有 Kubernetes 的唯一變化是Secret
的內容現在在叢集外部隱藏。
如果您希望 Sealed Secrets 控制器管理現有Secret
,您可以使用sealedsecrets.bitnami.com/managed: "true"
註解來註解您的Secret
。當解封具有相同名稱和命名空間的SealedSecret
時,現有的Secret
將被覆蓋,並且SealedSecret
將獲得該Secret
的所有權(因此,當刪除SealedSecret
時,該Secret
也會被刪除)。
v0.23.0 中的新功能
在某些用例中,您不想取代整個Secret
,而只想新增或修改現有Secret
中的一些金鑰。為此,您可以使用sealedsecrets.bitnami.com/patch: "true"
註解您的Secret
。使用此註釋將確保Secret
中不存在於SealedSecret
中的密鑰、標籤和註釋不會被刪除,並且那些存在於SealedSecret
中的將被添加到Secret
中(存在的密鑰、標籤和註釋) Secret
和SealedSecret
中的內容都會被SealedSecret
修改)。
此註解不會使SealedSecret
獲得Secret
的所有權。您可以新增patch
和managed
註解以獲得補丁行為,同時也獲得Secret
的所有權。
如果您希望SealedSecret
和Secret
是獨立的,這意味著當您刪除SealedSecret
時Secret
不會隨之消失,那麼您必須使用註釋sealedsecrets.bitnami.com/skip-set-owner-references: "true"
。您也可以將sealedsecrets.bitnami.com/managed: "true"
加入您的Secret
中,以便在SealedSecret
更新時更新您的 Secret。
如果您想新增或更新現有的密封秘密,而沒有其他項目的明文,您只需複製並貼上新的加密資料項目並將其合併到現有的密封秘密中。
您必須注意使用相容的名稱和命名空間密封更新的項目(請參閱上面有關範圍的註釋)。
如果您不想複製和貼上,可以使用--merge-into
命令更新現有的密封機密:
迴聲 -n 酒吧 | kubectl 建立秘密通用 mysecret --dry-run=client --from-file=foo=/dev/stdin -o json | kubeseal > mysealedsecret.jsonecho -n baz | kubeseal > mysealedsecret.jsonecho -n baz | kubectl 建立秘密通用 mysecret --dry-run=client --from-file=bar=/dev/stdin -o json | kubeseal --merge-into mysealedsecret.json
使用kubectl
命令創建臨時 Secret,然後在通過管道傳輸到kubeseal
後將其丟棄,這可能是一種非常不友好的用戶體驗。我們正在對 CLI 體驗進行徹底改革。同時,我們提供了另一種模式,其中 kubeseal 只關心將值加密到標準輸出,並且您有責任將其放入SealedSecret
資源中(與任何其他 k8s 資源不同)。
它也可以用作編輯器/IDE 整合的構建塊。
缺點是您必須小心與密封範圍、命名空間和名稱保持一致。
查看範圍
strict
範圍(預設):
$ echo -n foo | 迴聲kubeseal --raw --namespace bar --name mysecretAgBChHUWLMx...
namespace-wide
範圍:
$ echo -n foo | 迴聲kubeseal --raw --namespace bar --scope 命名空間-wideAgAbbFNkM54...
在SealedSecret
中包含sealedsecrets.bitnami.com/namespace-wide
註釋
元資料:註解:sealedsecrets.bitnami.com/namespace-wide:“true”
cluster-wide
範圍:
$ echo -n foo | 迴聲kubeseal --raw --scope 集群範圍AgAjLKpIYV+...
在SealedSecret
中包含sealedsecrets.bitnami.com/cluster-wide
註釋
元資料:註解:sealedsecrets.bitnami.com/cluster-wide:“true”
如果您想驗證現有的密封秘密, kubeseal
有標誌--validate
來幫助您。
提供一個名為sealed-secrets.yaml
的文件,其中包含以下密封秘密:
api版本:bitnami.com/v1alpha1kind:SealedSecretmetadata:名稱:mysecret命名空間:mynamespacespec:加密資料:foo:AgBy3i4OJSWK + PiTySYZZA9rO43cGDEq.....
您可以驗證密封的秘密是否已正確建立:
$ cat seal-secrets.yaml | kubeseal --驗證
如果密封秘密無效, kubeseal
將顯示:
$ cat seal-secrets.yaml | kubeseal --validateerror:無法解密密封的秘密
你應該經常輪換你的秘密。但由於您的秘密是用另一個秘密加密的,因此您需要了解這兩層如何關聯才能做出正確的決定。
長話短說:
如果密封私鑰洩露,您需要按照「早期密鑰更新」部分中的說明進行操作,然後再旋轉任何實際的秘密值。
SealedSecret 金鑰更新和重新加密功能不能取代實際秘密值的定期輪替。
密封密鑰每 30 天自動更新一次。這意味著將建立一個新的密封密鑰並將其附加到控制器可用於解封SealedSecret
資源的活動密封密鑰集。
最近建立的密封金鑰是在您使用kubeseal
時用於密封新秘密的金鑰,也是在您使用kubeseal --fetch-cert
時下載憑證的金鑰。
30 天的續約時間是一個合理的預設值,但可以根據需要使用SealedSecret
控制器的 pod 模板中的命令的--key-renew-period=
標誌進行調整。 value
欄位可以作為 golang 持續時間標誌給出(例如: 720h30m
)。假設您已將 Sealed Secrets 安裝到kube-system
命名空間中,請使用下列指令編輯 Deployment 控制器,並新增--key-renew-period
參數。關閉文字編輯器並且 Deployment 控制器已修改後,將自動建立新的 Pod 來取代舊的 Pod。
kubectl edit deployment/sealed-secrets-controller --namespace=kube-system
值為0
將停用自動密鑰更新。當然,您可能有一個有效的用例來停用自動密封密鑰更新,但經驗表明,新用戶在完全理解密封秘密的工作原理之前,往往傾向於得出他們想要控制密鑰更新的結論。請在下面的常見誤解部分中了解更多相關資訊。
不幸的是,您不能使用例如“d”作為幾天的單位,因為 Go stdlib 不支援它。不要用手掌打你的臉,而是以此為契機思考程式設計師所相信的關於時間的謊言。
一個常見的誤解是,密鑰更新通常被認為是密鑰輪換的一種形式,其中舊密鑰不僅過時而且實際上很糟糕,因此您想擺脫它。此功能歷來被稱為“密鑰輪換”,這並沒有幫助,這會增加混亂。
產生新密鑰時,密封的秘密不會自動輪換,舊密鑰也不會被刪除。舊的SealedSecret
資源仍然可以解密(這是因為舊的密封密鑰不會被刪除)。
密封金鑰更新和 SealedSecret 輪換不能取代輪換實際機密。
該工具的核心價值主張為:
將您的 Secret 加密到 SealedSecret 中,即使在公共儲存庫中也可以安全儲存。
如果您將任何內容儲存在版本控制儲存中,特別是公共儲存中,則必須假設您永遠無法刪除該資訊。
如果密封密鑰以某種方式從叢集中洩漏,您必須將使用該密鑰加密的所有SealedSecret
資源視為已洩露。叢集中的密封金鑰輪換次數,甚至現有 SealedSecrets 檔案的重新加密都無法改變這一點。
最佳實踐是定期輪換所有實際機密(例如更改密碼)並使用這些新機密製作新的SealedSecret
資源。
但如果SealedSecret
控制器不更新密封密鑰,則輪換將毫無意義,因為攻擊者也可以解密新的秘密。因此,您需要同時執行這兩件事:定期更新密封密鑰並輪換您的實際秘密!
如果您知道或懷疑密封金鑰已洩露,您應該在開始密封新的輪換機密之前盡快更新金鑰,否則攻擊者也將獲得對您的新機密的存取權。
透過將目前時間戳記傳遞到控制器到名為--key-cutoff-time
標誌或名為SEALED_SECRETS_KEY_CUTOFF_TIME
環境變量,可以提前產生金鑰。預期格式為 RFC1123,您可以使用date -R
unix 指令產生它。
密封的秘密密封密鑰不是存取控制密鑰(例如密碼)。它們更像是您可以用來閱讀發送給您的加密郵件的 GPG 金鑰。讓我們繼續用電子郵件做類比:
想像一下,您有理由相信您的 GPG 私鑰可能已洩露。如果您做的第一件事就是刪除您的私鑰,那麼您將失去更多。您將無法再存取先前使用該金鑰發送的所有電子郵件(除非您擁有這些電子郵件的解密副本),也無法存取您尚未告知其使用新金鑰的朋友所發送的新電子郵件。
當然,這些加密電子郵件的內容並不安全,因為攻擊者現在可能能夠解密它們,但已經完成了。您突然失去閱讀這些電子郵件的能力肯定不會消除損害。如果有的話,那就更糟了,因為你不再確定攻擊者知道了什麼秘密。您真正想做的是確保您的朋友停止使用您的舊密鑰,並且從現在起所有進一步的通信都使用新密鑰對進行加密(即您的朋友必須知道該新密鑰)。
同樣的邏輯也適用於 SealedSecrets。最終目標是保護您實際的“用戶”秘密。 「封印」的秘密只是一個機制,一個「信封」。如果秘密被洩露,就沒有回頭路了,做過的事就已經過去了。
您首先需要確保新的秘密不會使用舊的洩漏金鑰進行加密(在上面的電子郵件類比中,即:建立一個新的金鑰對並向所有朋友提供新的公鑰)。
第二個邏輯步驟是消除損害,這取決於秘密的性質。一個簡單的例子是資料庫密碼:如果您不小心洩漏了資料庫密碼,您應該做的就是更改資料庫密碼(在資料庫上;並撤銷舊密碼!)並使用以下內容更新SealedSecret
資源新密碼(即再次執行kubeseal
)。
前面的部分描述了這兩個步驟,儘管方式不太冗長。既然您已經更深入地掌握了基本原理,那麼再次閱讀它們並沒有什麼可恥的。
SealedSecret
控制器和相關工作流程旨在保留舊的密封金鑰並定期添加新的密封金鑰。除非您知道自己在做什麼,否則不應刪除舊金鑰。
也就是說,如果您願意,您可以手動管理(建立、移動、刪除)密封密鑰。它們只是普通的 k8s 秘密,位於SealedSecret
控制器所在的同一命名空間中(通常是kube-system
,但它是可配置的)。
您可以透過密封密鑰的創造性管理來解決一些高級用例。例如,您可以在幾個叢集之間共用相同的密封金鑰,以便您可以在多個叢集中套用完全相同的密封秘密。由於密封金鑰只是普通的 k8s 金鑰,您甚至可以使用密封金鑰本身並使用 GitOps 工作流程來管理您的密封金鑰(當您想在不同叢集之間共用相同金鑰時很有用)!
使用active
以外的任何內容標記密封金鑰機密會有效地從SealedSecret
控制器中刪除該金鑰,但如果需要,它仍然可以在 k8s 中用於手動加密/解密。
注意SealedSecret
控制器目前不會自動擷取手動建立、刪除或重新標記的密封密鑰。管理員必須重新啟動控制器才能套用效果。
在擺脫一些舊的密封金鑰之前,您需要使用最新的私鑰重新加密您的 SealedSecrets。
kubeseal --重新加密tmp.json && mv tmp.json my_sealed_secret.json
上面的呼叫將產生一個使用最新密鑰進行新加密的新的密封秘密文件,而不會使秘密將叢集留給客戶端。然後,您可以將該檔案儲存在版本控制系統中( kubeseal --re-encrypt
不會更新叢集內物件)。
目前,舊密鑰不會被自動垃圾回收。
定期重新加密您的 SealedSecrets 是個好主意。但如上所述,不要讓自己沉浸在錯誤的安全感中:您必須假設舊版本的SealedSecret
資源(使用您認為已失效的密鑰加密的資源)仍然可能存在並且可供攻擊者訪問。即,重新加密並不能取代定期輪換您的實際秘密。
此控制器新增了一個新的SealedSecret
自訂資源。 SealedSecret
有趣的部分是 base64 編碼的非對稱加密Secret
。
控制器維護一組私鑰/公鑰對作為 kubernetes 秘密。密鑰帶有sealedsecrets.bitnami.com/sealed-secrets-key
標籤,並在標籤中標識為active
或compromised
。啟動時,密封的秘密控制器將...
搜尋這些金鑰並將它們新增至其本機儲存體(如果它們被標記為活動)。
建立新密鑰
啟動密鑰輪換週期
有關加密貨幣的更多詳細資訊可以在這裡找到。
開髮指南可以在開發者指南中找到。
是的,你可以!在一個文件中放入任意數量的秘密。確保透過---
對於 YAML 和 JSON 中的額外單一物件將它們分開。
不,私鑰僅儲存在控制器管理的 Secret 中(除非您有 k8s 物件的其他備份)。沒有後門 - 如果沒有用於加密給定 SealedSecrets 的私鑰,您將無法解密它。如果您無法使用加密金鑰存取 Secret,也無法存取叢集中的 Secret 的解密版本,那麼您將需要為所有內容重新產生新密碼,並使用新密碼再次密封它們密封鑰匙等
如果您確實想備份加密私鑰,可以透過具有適當存取權限的帳戶輕鬆完成:
kubectl get Secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml >main.keyecho "---" >> main.key kubectl 取得秘密 -n kube-system seal-secrets-key -o yaml >>main.key
注意:只有當您在叢集上安裝了早於版本 0.9.x 的 seal-secrets 時,才需要第二條語句。
注意:此文件將包含控制器的公鑰+私鑰,並且應該保持安全!
注意:密封金鑰更新後,您應該重新建立備份。否則,您的備份將無法解密新的密封秘密。
要在災難發生後從備份中恢復,只需在啟動控制器之前將這些機密放回原處 - 或者如果控制器已啟動,則替換新建立的機密並重新啟動控制器:
對於 Helm 部署:
kubectl apply -f main.key kubectl 刪除 pod -n kube-system -l app.kubernetes.io/name=sealed-secrets
透過controller.yaml
清單進行部署
kubectl apply -f main.key kubectl 刪除 pod -n kube-system -l name=sealed-secrets-controller
雖然將密封秘密視為秘密的長期儲存系統不是建議的用例,但有些人確實有一個合理的要求,即在 k8s 叢集關閉時能夠恢復秘密,並且不能將備份恢復到新的SealedSecret
控制器部署中實際的。
如果您已備份一個或多個私鑰(請參閱上一問題),您可以使用kubeseal --recovery-unseal --recovery-private-key file1.key,file2.key,...
指令來解密密封的秘密文件。
您可以使用kubeseal --help
檢查可用的標誌。
kubernetes Secret
資源包含多個項目,基本上是鍵/值對的平面映射。 SealedSecrets 在該層級運行,並且不關心您在值中放入的內容。換句話說,它無法理解您可能放入秘密的任何結構化配置文件,因此無法幫助您更新其中的各個欄位。
由於這是一個常見問題,特別是在處理遺留應用程式時,我們確實提供了一個可能的解決方法的範例。
是的,您可以向控制器提供您自己的證書,它會使用它們。請檢查此處以獲取解決方法。
kube-system
命名空間內運行,如何使用 kubeseal?如果您將控制器安裝在與預設kube-system
不同的命名空間中,則需要將此命名空間提供給kubeseal
命令列工具。有兩種選擇:
您可以透過命令列選項--controller-namespace
指定命名空間:
kubeseal --controller-namespace seal-secretsmysealedsecret.json
透過環境變數SEALED_SECRETS_CONTROLLER_NAMESPACE
:
匯出 SEALED_SECRETS_CONTROLLER_NAMESPACE=密封的秘密 kubesealmysealedsecret.json
我們的圖像正在使用 cosign 進行簽名。簽名已保存在我們的 GitHub 容器註冊表中。
v0.20.2 及先前版本的映像均使用 Cosign v1 進行簽署。較新的映像檔使用 Cosign v2 進行簽署。
驗證映像非常簡單:
# 匯出。 /bitnami-labs/sealed-secrets-controller:latest# 驗證Dockerhub 中上傳的映像 cosign verify --key .github/workflows/cosign.pub docker.io/bitnami/sealed-secrets-controller:latest
如果您想將一個控制器用於多個命名空間,但不是所有命名空間,則可以使用命令列標誌--additional-namespaces=
提供其他命名空間。確保在目標命名空間中提供適當的角色和角色綁定,以便控制器可以管理其中的機密。
答案是肯定的,您可以使用標誌--max-unseal-retries
在控制器中配置重試次數。此標誌可讓您配置解封您的密封秘密的最大重試次數。
Kubernetes Slack 上的#sealed-secrets
按此註冊 Kubernetes Slack 組織。
kubeseal-convert
:https://github.com/EladLeev/kubeseal-convert
Visual Studio 代碼擴充:https://marketplace.visualstudio.com/items?itemName=codecontemplator.kubeseal
WebSeal:在瀏覽器中產生秘密:https://socialgouv.github.io/webseal
HybridEncrypt TypeScript 實作:https://github.com/SocialGouv/aes-gcm-rsa-oaep
[已棄用] 密封秘密操作員:https://github.com/disposab1e/sealed-secrets-operator-helm