ceph-csi/docs/design/proposals/encrypted-pvc.md
Vasyl Purchel 669dc4536f Reduce encryption KMS configuration SC parameters
* moves KMS type from StorageClass into KMS configuration itself
 * updates omapval used to identify KMS to only it's ID without the type

why?

1. when using multiple KMS configurations (not currently supported)
automated parsing of kms configuration will be failing because some
entries in configs won't comply with the requested type
2. less options are needed in the StorageClass and less data used to
identify the KMS

Signed-off-by: Vasyl Purchel vasyl.purchel@workday.com
Signed-off-by: Andrea Baglioni andrea.baglioni@workday.com
2020-02-10 15:21:11 +00:00

130 lines
4.3 KiB
Markdown

# Encrypted Persistent Volume Claims
## Proposal
Subject of this proposal is to add support for encryption of RBD volumes in
Ceph-CSI.
Some but not all the benefits of this approach:
* guarantee encryption in transit to rbd without using messenger v2
* extra security layer to application with special regulatory needs
* at rest encryption can be disabled to selectively allow encryption only where
required
## Document Terminology
* volume encryption: encryption of a volume attached by rbd
* encryption at rest: encryption of physical disk done by ceph
* LUKS: Linux Unified Key Setup: stores all of the needed setup information for
dm-crypt on the disk
* dm-crypt: linux kernel device-mapper crypto target
* cryptsetup: the command line tool to interface with dm-crypt
## Proposed Solution
The proposed solution in this document, is to address the volume encryption
requirement by using dm-crypt module through cryptsetup cli interface.
### Implementation Summary
* Encryption is implemented using cryptsetup with LUKS extension.
A good introduction to LUKS and dm-crypt in general can be found
[here](https://wiki.archlinux.org/index.php/Dm-crypt/Device_encryption#Encrypting_devices_with_cryptsetup)
Functions to implement necessary interaction are implemented in a separate
`cryptsetup.go` file.
* LuksFormat
* LuksOpen
* LuksClose
* LuksStatus
* `CreateVolume`: refactored to prepare for encryption (tag image that it
requires encryption later), before returning, if encrypted volume option is
set.
* `NodeStageVolume`: refactored to call `encryptDevice` method on the very first
volume attach request
* `NodeStageVolume`: refactored to open encrypted device (`openEncryptedDevice`)
* `openEncryptedDevice`: looks up for a passphrase matching the volume id,
returns the new device path in the form: `/dev/mapper/luks-<volume_id>`.
On the woker node where the attach is scheduled:
```shell
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 10G 0 disk
└─sda1 8:1 0 10G 0 part /
sdb 8:16 0 20G 0 disk
rbd0 253:0 0 1G 0 disk
└─luks-pvc-8a710f4c934811e9 252:0 0 1020M 0 crypt /var/lib/kubelet/pods/9eaceaef-936c-11e9-b396-005056af3de0/volumes/kubernetes.io~csi/pvc-8a710f4c934811e9/mount
```
* `detachRBDDevice`: calls `LuksClose` function to remove the LUKS mapping
before detaching the volume.
* StorageClass extended with following parameters:
1. `encrypted` ("true" or "false")
1. `encryptionKMSID` (string representing kms configuration of choice)
ceph-csi plugin may support different kms vendors with different type of
authentication
* New KMS Configuration created.
#### Annotated YAML for RBD StorageClass
```yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd
provisioner: rbd.csi.ceph.com
parameters:
# String representing Ceph cluster configuration
clusterID: <cluster-id>
# ceph pool
pool: rbd
# RBD image features, CSI creates image with image-format 2
# CSI RBD currently supports only `layering` feature.
imageFeatures: layering
# The secrets have to contain Ceph credentials with required access
# to the 'pool'.
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: default
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: default
# Specify the filesystem type of the volume. If not specified,
# csi-provisioner will set default as `ext4`.
csi.storage.k8s.io/fstype: ext4
# Encrypt volumes
encrypted: "true"
# Use external key management system for encryption passphrases by specifying
# a unique ID matching KMS ConfigMap. The ID is only used for correlation to
# config map entry.
encryptionKMSID: <kms-id>
reclaimPolicy: Delete
```
And kms configuration:
```yaml
---
apiVersion: v1
kind: ConfigMap
data:
config.json: |-
{
"<kms-id>": {
"encryptionKMSType": "kmsType",
kms specific config...
}
}
metadata:
name: ceph-csi-encryption-kms-config
```