Linux Unified Key Setup (LUKS)
You can enable Linux Unified Key Setup (LUKS) to encrypt ONTAP SAN and ONTAP SAN ECONOMY volumes on Trident. Trident supports passphrase rotation and volume expansion for LUKS-encrypted volumes.
In Trident, LUKS-encrypted volumes use the aes-xts-plain64 cypher and mode, as recommended by NIST.
-
Worker nodes must have cryptsetup 2.1 or higher (but lower than 3.0) installed. For more information, visit Gitlab: cryptsetup.
-
For performance reasons, we recommend that worker nodes support Advanced Encryption Standard New Instructions (AES-NI). To verify AES-NI support, run the following command:
grep "aes" /proc/cpuinfo
If nothing is returned, your processor does not support AES-NI. For more information on AES-NI, visit: Intel: Advanced Encryption Standard Instructions (AES-NI).
Enable LUKS encryption
You can enable per-volume, host-side encryption using Linux Unified Key Setup (LUKS) for ONTAP SAN and ONTAP SAN ECONOMY volumes.
-
Define LUKS encryption attributes in the backend configuration. For more information on backend configuration options for ONTAP SAN, refer to ONTAP SAN configuration options.
"storage": [ { "labels":{"luks": "true"}, "zone":"us_east_1a", "defaults": { "luksEncryption": "true" } }, { "labels":{"luks": "false"}, "zone":"us_east_1a", "defaults": { "luksEncryption": "false" } }, ]
-
Use
parameters.selector
to define the storage pools using LUKS encryption. For example:apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: luks provisioner: csi.trident.netapp.io parameters: selector: "luks=true" csi.storage.k8s.io/node-stage-secret-name: luks-${pvc.name} csi.storage.k8s.io/node-stage-secret-namespace: ${pvc.namespace}
-
Create a secret that contains the LUKS passphrase. For example:
kubectl -n trident create -f luks-pvc1.yaml apiVersion: v1 kind: Secret metadata: name: luks-pvc1 stringData: luks-passphrase-name: A luks-passphrase: secretA
Limitations
LUKS-encrypted volumes cannot take advantage of ONTAP deduplication and compression.
Backend configuration for importing LUKS volumes
To import a LUKS volume, you must set luksEncryption
to true
on the backend. The luksEncryption
option tells Trident if the volume is LUKS-compliant (true
) or not LUKS-compliant (false
) as shown in the following example.
version: 1 storageDriverName: ontap-san managementLIF: 10.0.0.1 dataLIF: 10.0.0.2 svm: trident_svm username: admin password: password defaults: luksEncryption: 'true' spaceAllocation: 'false' snapshotPolicy: default snapshotReserve: '10'
PVC configuration for importing LUKS volumes
To import LUKS volumes dynamically, set the annotation trident.netapp.io/luksEncryption
to true
and include a LUKS-enabled storage class in the PVC as shown in this example.
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: luks-pvc namespace: trident annotations: trident.netapp.io/luksEncryption: "true" spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi storageClassName: luks-sc
Rotate a LUKS passphrase
You can rotate the LUKS passphrase and confirm rotation.
Do not forget a passphrase until you have verified it is no longer referenced by any volume, snapshot, or secret. If a referenced passphrase is lost, you might be unable to mount the volume and the data will remain encrypted and inaccessible. |
LUKS passphrase rotation occurs when a pod that mounts the volume is created after a new LUKS passphrase is specified. When a new pod is created, Trident compares the LUKS passphrase on the volume to the active passphrase in the secret.
-
If the passphrase on the volume does not match the active passphrase in the secret, rotation occurs.
-
If the passphrase on the volume matches the active passphrase in the secret, the
previous-luks-passphrase
parameter is ignored.
-
Add the
node-publish-secret-name
andnode-publish-secret-namespace
StorageClass parameters. For example:apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: csi-san provisioner: csi.trident.netapp.io parameters: trident.netapp.io/backendType: "ontap-san" csi.storage.k8s.io/node-stage-secret-name: luks csi.storage.k8s.io/node-stage-secret-namespace: ${pvc.namespace} csi.storage.k8s.io/node-publish-secret-name: luks csi.storage.k8s.io/node-publish-secret-namespace: ${pvc.namespace}
-
Identify existing passphrases on the volume or snapshot.
Volumetridentctl -d get volume luks-pvc1 GET http://127.0.0.1:8000/trident/v1/volume/<volumeID> ...luksPassphraseNames:["A"]
Snapshottridentctl -d get snapshot luks-pvc1 GET http://127.0.0.1:8000/trident/v1/volume/<volumeID>/<snapshotID> ...luksPassphraseNames:["A"]
-
Update the LUKS secret for the volume to specify the new and previous passphrases. Ensure
previous-luke-passphrase-name
andprevious-luks-passphrase
match the previous passphrase.apiVersion: v1 kind: Secret metadata: name: luks-pvc1 stringData: luks-passphrase-name: B luks-passphrase: secretB previous-luks-passphrase-name: A previous-luks-passphrase: secretA
-
Create a new pod mounting the volume. This is required to initiate the rotation.
-
Verify the the passphrase was rotated.
Volumetridentctl -d get volume luks-pvc1 GET http://127.0.0.1:8000/trident/v1/volume/<volumeID> ...luksPassphraseNames:["B"]
Snapshottridentctl -d get snapshot luks-pvc1 GET http://127.0.0.1:8000/trident/v1/volume/<volumeID>/<snapshotID> ...luksPassphraseNames:["B"]
The passphrase was rotated when only the new passphrase is returned on the volume and snapshot.
If two passphrases are returned, for example luksPassphraseNames: ["B", "A"] , the rotation is incomplete. You can trigger a new pod to attempt to complete the rotation.
|
Enable volume expansion
You can enable volume expansion on a LUKS-encrypted volume.
-
Enable the
CSINodeExpandSecret
feature gate (beta 1.25+). Refer to Kubernetes 1.25: Use Secrets for Node-Driven Expansion of CSI Volumes for details. -
Add the
node-expand-secret-name
andnode-expand-secret-namespace
StorageClass parameters. For example:apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: luks provisioner: csi.trident.netapp.io parameters: selector: "luks=true" csi.storage.k8s.io/node-stage-secret-name: luks-${pvc.name} csi.storage.k8s.io/node-stage-secret-namespace: ${pvc.namespace} csi.storage.k8s.io/node-expand-secret-name: luks-${pvc.name} csi.storage.k8s.io/node-expand-secret-namespace: ${pvc.namespace} allowVolumeExpansion: true
When you initiate online storage expansion, the kubelet passes the appropriate credentials to the driver.