Kubernetes Novice Tokyo #15 で発表した資料です。 KubernetesとHashiCorp Vaultを組み合わせて良い感じにSecretの管理ができるんだよという話をしました
Copyright © 2021 HashiCorpk8sとVaultを組み合わせてシークレットをもっとセキュアに
View Slide
Copyright © 2021 HashiCorp草間一人Sr. Solutions Engineer@jacopenKazutoKusama
大事なものちゃんと管理してますか?
大事なもの is 何▪ Cloud ProviderのAccess key/secretとか▪ API Tokenとか▪ DBのuser/passとか▪ SSHの鍵とか▪ TLSの証明書と鍵とか
ちゃんと管理 is 何AWSのAccess key/ secret access keyデータベースのメンテナンス用User/PassSSHのAuthorized keys*** / ****** / ***それぞれがKeyを手元で管理しているメンテ用のuser/passを共有している各ユーザーの公開鍵をauthorized_keysに設定している
ちゃんと管理 is 何AWSのAccess key/ secret access keyデータベースのメンテナンス用User/PassSSHのAuthorized keys*** / ****** / ***間違えてgitにコミットしちゃった!退職してもメンテ用パスワードは内緒にね !退職した人の公開鍵が登録されたままつまりちゃんと管理できてない状態
ちなみにk8sの場合、どう管理するんでしたっけ?
ちなみにk8sの場合、どう管理するんでしたっけ?kind: SecretapiVersion: v1data:username: YWRtaW4=password: MWYyZDFlMmU2N2Rmmetadata:annotations:kubectl.kubernetes.io/last-applied-configuration: { ... }creationTimestamp: 2016-01-22T18:41:56Zname: mysecretnamespace: defaultresourceVersion: "164619"uid: cfee02d6-c137-11e5-8d73-42010af00002type: Opaque
ちなみにk8sの場合、どう管理するんでしたっけ?kind: SecretapiVersion: v1data:username: YWRtaW4=password: MWYyZDFlMmU2N2Rmmetadata:annotations:kubectl.kubernetes.io/last-applied-configuration: { ... }creationTimestamp: 2016-01-22T18:41:56Zname: mysecretnamespace: defaultresourceVersion: "164619"uid: cfee02d6-c137-11e5-8d73-42010af00002type: Opaque“admin” “1f2d1e2e67df”Base64エンコードされているだけ。Git等に入れるのはNG
せっかくGitOpsにしたのにSecretSecret
せっかくGitOpsにしたのにSecretSecret間違えてgitにコミットしちゃった!あの鍵って誰が管理してるの?
Secret sprawlバラバラに保管アプリごと/チームごとバラバラのアクセスフローアクセスのコントロールができない
よくあるインシデントアクセスキーが漏洩大量のインスタンスを作成してマイニングとんでもない請求
よくあるインシデントアクセスキーが漏洩大量のインスタンスを作成してマイニングとんでもない請求どこから漏れたか分かっていれば対策はできるけど…
Secretのジレンマ▪ Secretが大事なことは誰もが分かってる▪ だから既存の自動化フローには載せず、特別対応– 一部の人だけが手元で厳重に管理– 権限を絞ったプライベートリポジトリで管理– 権限を絞ったSpreadsheetで管理▪ しかしこの特別対応こそが、Secret Sprawlを生みセキュリティを低下させる– 人間が把握できる範囲には限界がある– 人間はミスをする
ちゃんと管理しましょう!
Secret管理のベストプラクティス・定期的なローテーション・利用者に応じた細かな権限管理・監査記録・暗号化AWShttps://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-access-keys-best-practices.htmlAzurehttps://docs.microsoft.com/ja-jp/azure/architecture/framework/security/design-storage-keysGCPhttps://cloud.google.com/secret-manager?hl=ja
アイデンティティベースのシークレットと暗号化の管理システムこれまで挙げたような、扱いに悩むシークレットを“ちゃんと” 管理するためのシステムOSSで提供されているほか、商用版のVaultEnterpriseやHCP VaultというManaged Serviceもあります。
僕たちが欲しいものシークレットを”ちゃんと管理”できること
僕たちが欲しいもの暗号化され安全に管理されている追加・削除がすぐ出来る
僕たちが欲しいもの誰が使っているかを特定できる利用者ごとにポリシーを設定出来るAdminアプリ
僕たちが欲しいもの安全に使える効率的に使える
k8sに限らず、ありとあらゆるケースで活用可能今回はk8s+Vaultの組み合わせを中心に紹介
利用方法ororServerここで集中管理
利用方法ororServerCLIGUIAPIInterfaceClientAdminアプリCI/CDさまざまな人/システムが、さまざまな方法でアクセス
デプロイ方法Helmを使ってk8sの中にセットアップ
デプロイ方法k8sの外に建てたVaultと連携
デプロイ方法HCP VaultだとHashiCorpManagedなVaultが使える
デプロイ方法Vault間でReplication
認証 OtkaJWT/OIDCLDAPAzure ADAWS IAMGitHubTokenetc…AppRoleKubernetesTLS Certs
シンプルな例 - KV Secrets EngineGUIもしくはCLIでVaultに値を保存vault kv put kv/secret/path foo=barorGUICLIfoo=bar
アプリからアクセス (API)foo=barアプリfoo=barAPI
Kubernetesを経由してアプリに渡すfoo=barアプリ vault-agentfoo=barfoo=barinit-containerorSidecar
Kubernetesを経由してアプリに渡すVault Agent InjectorをKubernetes上にセットアップ。Helmでインストール可能Mutating webhookでPodにInitcontainerやSidecarを追加してくれる
CODE EDITOR{{- with secret "internal/data/database/config" -}}postgresql://{{ .Data.data.username }}:{{ .Data.data.password}}@postgres:5432/wizard{{- end -}}
CODE EDITORspec:template:metadata:annotations:vault.hashicorp.com/agent-inject: "true"vault.hashicorp.com/agent-inject-status: "update"vault.hashicorp.com/role: "internal-app"vault.hashicorp.com/agent-inject-secret-database-config.txt:"internal/data/database/config"vault.hashicorp.com/agent-inject-template-database-config.txt: |{{- with secret "internal/data/database/config" -}}postgresql://{{ .Data.data.username }}:{{ .Data.data.password}}@postgres:5432/wizard{{- end -}}
TERMINAL> kubectl exec payroll --container payroll \-- cat /vault/secrets/database-config.txtpostgresql://db-readonly-user:[email protected]:5432/wizardRender されたTemplate
Kubernetesを経由してアプリに渡す(CSI Provider)foo=barアプリ CSI Providerfoo=barfoo=barボリュームとしてPodにマウント
Kubernetesを経由してアプリに渡す(CSI Provider)
Kubernetesを経由してアプリに渡す(Kubernetes External Secrets)https://github.com/external-secrets/kubernetes-external-secretsExternal SecretsControllerSecretsfoo=barfoo=barkube-apiserverExternalSecrets
External Secrets Operator▪ 前述のKubernetes External Secrets (KES)はメンテナンスモードに▪ 後継のExternal Secrets Operatorが登場– https://github.com/external-secrets/external-secrets– Vaultにも対応– まだ試したことないので誰か教えてください
便利さは分かったけどほかの選択肢もあるよね?
Vaultの醍醐味はDynamic Secretにあり
データベースのメンテナンスMaintenanceUser/PassMaintenanceUser/Pass
データベースのメンテナンス(Dynamic Secret)TemporaryUser/PassログDatabase Secret Engine
CI/CDからクラウドの利用CloudProviderIAMTest&BuildDeployCI/CDツール
CI/CDからクラウドの利用(Dynamic Secret)TemporaryIAMTest&BuildDeployCI/CDツールAWS Secret EngineAzure, GCPにも対応
外部の運用者からの利用内部の人外部の人CloudProviderIAM作成 & 権限設定
外部の運用者からの利用(Dynamic Secret)内部の人外部の人TemporaryIAM Account権限、TTL設定TTLが設定出来るので、一定時間経つと自動で無効になる
さらにこんなのも
PKIルート認証局X.509証明書● Vault を中間認証局として設定● 認証や暗号化通信に必要な署名済みのX.509証明書を動的に発行X.509証明書SignedX.509証明書LeaseLeaseApplication AApplication B中間認証局
Cert-managerapiVersion: cert-manager.io/v1kind: Issuermetadata:name: vault-issuernamespace: sandboxspec:vault:path: pki_int/sign/example-dot-comserver: https://vault.localcaBundle: PEM file>auth:...apiVersion: cert-manager.io/v1kind: Certificatemetadata:name: app-certspec:dnsNames:- '*.example.local'issuerRef:kind: ClusterIssuername: vault-issuersecretName: app-cert
Encryption as a Service● データの暗号化/復号の中継地点暗号化/復号Application AApplication BPIIPII = Personal Identifiable InformationPII暗号化復号暗号鍵PIIPIIデータベース書き込み読み出し
OIDC Provider▪ Vault 1.9からの新機能(Tech Preview)▪ VaultがOIDCのIdPとして振る舞えるhttps://www.vaultproject.io/docs/secrets/identity/oidc-provider
紹介しきれないのでまずは触ってみて!$ vault server -dev
Vault Users Group発足 & Meetupやります!▪ #vugjp▪ 12/16 19:00 -https://vault.connpass.com/event/228646/
3/11 (金) 開催!来週からCFP開始!
Thank You[email protected]www.hashicorp.com