Adds per volume encryption with Vault integration

- adds proposal document for PVC encryption from PR448
- adds per-volume encription by generating encryption passphrase
  for each volume and storing it in a KMS
- adds HashiCorp Vault integration as a KMS for encryption passphrases
- avoids encrypting volume second time if it was already encrypted but
  no file system created
- avoids unnecessary checks if volume is a mapped device when encryption
  was not requested
- prevents resizing encrypted volumes (it is not currently supported)
- prevents creating snapshots from encrypted volumes to prevent attack
  on encryption key (security guard until re-encryption of volumes
  implemented)

Signed-off-by: Vasyl Purchel vasyl.purchel@workday.com
Signed-off-by: Andrea Baglioni andrea.baglioni@workday.com

Fixes #420
Fixes #744
This commit is contained in:
Vasyl Purchel
2020-01-29 11:44:45 +00:00
committed by mergify[bot]
parent 1adef00c86
commit 419ad0dd8e
26 changed files with 1210 additions and 102 deletions

View File

@ -0,0 +1,28 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: rbd-csi-vault-token-review
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbd-csi-vault-token-review
rules:
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create", "get", "list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbd-csi-vault-token-review
subjects:
- kind: ServiceAccount
name: rbd-csi-vault-token-review
namespace: default
roleRef:
kind: ClusterRole
name: rbd-csi-vault-token-review
apiGroup: rbac.authorization.k8s.io

View File

@ -0,0 +1,18 @@
---
apiVersion: v1
kind: ConfigMap
data:
config.json: |-
[
{
"encryptionKMSID": "vault-test",
"vaultAddress": "http://vault.default.svc.cluster.local:8200",
"vaultAuthPath": "/v1/auth/kubernetes/login",
"vaultRole": "csi-kubernetes",
"vaultPassphraseRoot": "/v1/secret",
"vaultPassphrasePath": "ceph-csi/",
"vaultCAVerify": false
}
]
metadata:
name: ceph-csi-encryption-kms-config

View File

@ -0,0 +1,47 @@
---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: rbd-csi-vault-token-review-psp
spec:
fsGroup:
rule: RunAsAny
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- 'configMap'
- 'secret'
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# replace with non-default namespace name
namespace: default
name: rbd-csi-vault-token-review-psp
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['rbd-csi-vault-token-review-psp']
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: rbd-csi-vault-token-review-psp
# replace with non-default namespace name
namespace: default
subjects:
- kind: ServiceAccount
name: rbd-csi-vault-token-review
# replace with non-default namespace name
namespace: default
roleRef:
kind: Role
name: rbd-csi-vault-token-review-psp
apiGroup: rbac.authorization.k8s.io

View File

@ -0,0 +1,150 @@
# HashiCorp Vault configuration for minikube
# This is not part of ceph-csi project, used only
# for e2e testing of integration with such KMS
---
apiVersion: v1
kind: Service
metadata:
name: vault
labels:
app: vault-api
spec:
ports:
- name: vault-api
port: 8200
clusterIP: None
selector:
app: vault
role: server
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: vault
labels:
app: vault
role: server
spec:
replicas: 1
selector:
matchLabels:
app: vault
role: server
template:
metadata:
labels:
app: vault
role: server
spec:
containers:
- name: vault
image: vault
securityContext:
runAsUser: 100
env:
- name: VAULT_DEV_ROOT_TOKEN_ID
value: sample_root_token_id
- name: SKIP_SETCAP
value: any
livenessProbe:
exec:
command:
- pidof
- vault
initialDelaySeconds: 5
timeoutSeconds: 2
ports:
- containerPort: 8200
name: vault-api
---
apiVersion: v1
items:
- apiVersion: v1
data:
init-vault.sh: |
set -x -e
timeout 300 sh -c 'until vault status; do sleep 5; done'
# login into vault to retrieve token
vault login ${VAULT_DEV_ROOT_TOKEN_ID}
# enable kubernetes auth method under specific path:
vault auth enable -path="/${CLUSTER_IDENTIFIER}" kubernetes
# write configuration to use your cluster
vault write auth/${CLUSTER_IDENTIFIER}/config \
token_reviewer_jwt=@${SERVICE_ACCOUNT_TOKEN_PATH}/token \
kubernetes_host="${K8S_HOST}" \
kubernetes_ca_cert=@${SERVICE_ACCOUNT_TOKEN_PATH}/ca.crt
# create policy to use keys related to the cluster
vault policy write "${CLUSTER_IDENTIFIER}" - << EOS
path "secret/data/ceph-csi/*" {
capabilities = ["create", "update", "delete", "read"]
}
path "secret/metadata/ceph-csi/*" {
capabilities = ["read", "delete"]
}
EOS
# create a role
vault write "auth/${CLUSTER_IDENTIFIER}/role/${PLUGIN_ROLE}" \
bound_service_account_names="${SERVICE_ACCOUNTS}" \
bound_service_account_namespaces="${SERVICE_ACCOUNTS_NAMESPACE}" \
policies="${CLUSTER_IDENTIFIER}"
kind: ConfigMap
metadata:
creationTimestamp: null
name: init-scripts
kind: List
metadata: {}
---
apiVersion: batch/v1
kind: Job
metadata:
name: vault-init-job
spec:
parallelism: 1
completions: 1
template:
metadata:
name: vault-init-job
spec:
serviceAccount: rbd-csi-vault-token-review
volumes:
- name: init-scripts-volume
configMap:
name: init-scripts
containers:
- name: vault-init-job
image: vault
volumeMounts:
- mountPath: /init-scripts
name: init-scripts-volume
env:
- name: HOME
value: /tmp
- name: CLUSTER_IDENTIFIER
value: kubernetes
- name: SERVICE_ACCOUNT_TOKEN_PATH
value: /var/run/secrets/kubernetes.io/serviceaccount
- name: K8S_HOST
value: https://kubernetes.default.svc.cluster.local
- name: PLUGIN_ROLE
value: csi-kubernetes
- name: SERVICE_ACCOUNTS
value: rbd-csi-nodeplugin,rbd-csi-provisioner
- name: SERVICE_ACCOUNTS_NAMESPACE
value: default
- name: VAULT_ADDR
value: http://vault.default.svc.cluster.local:8200/
- name: VAULT_DEV_ROOT_TOKEN_ID
value: sample_root_token_id
command:
- /bin/sh
- /init-scripts/init-vault.sh
restartPolicy: Never

View File

@ -43,6 +43,13 @@ parameters:
# By default it is disabled. Valid values are “true” or “false”.
# A string is expected here, i.e. “true”, not true.
# encrypted: "true"
# Use external key management system for encryption passphrases
# encryptionKMS: vault
# String representing KMS configuration. Should be unique and match ID in
# KMS ConfigMap. The ID is only used for correlation to config map entry.
# encryptionKMSID: <kms-config-id>
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions: