Files
ubicloud/migrate/20230705_storage_encryption.rb
Hadi Moshayedi ed5f363798 Enable encrypted-at-rest storage
Adds the option to keep storage devices encrypted at rest. This can
be enabled or disabled by a parameter to `Vm.assemble`. It is
enabled by default:

```
> st = Prog::Vm::Nexus.assemble(mykey, nil, storage_encrypted: true)
```

We also add a program to rotate key encryption keys:

```
> st = Strand.create(prog: 'RotateStorageKek', label: 'start', stack: [{subject_id: vm_storage_volume.id}])
```

We use envelope encryption [1]. On the Clover side, a "key
encryption key" (KEK) is generated & stored in database. On the
rhizome side, a "data encryption key" (DEK) is generated & used to
encrypt data. The DEK is encrypted using KEK & saved near the
storage data in the host. Now attackers cannot decrypt data if they
only get access to either of DB or the file system. They need to
get access to both of them to be able to decrypt.

We use "AES-256-GCM" for key encryption, and "AES_XTS" for data
encryption. The KEK is saved in the "StorageKeyEncryptionKey" table.
The DEK is saved in `/var/storage/$vm_name/$disk_index/data_encryption_key.json`.
Key fields of the json file are encrypted using KEK. I have named the
key fields "key" and "key2" to match the terminology SPDK uses.

[1] https://cloud.google.com/kms/docs/envelope-encryption
2023-07-06 21:42:07 -07:00

20 lines
735 B
Ruby

# frozen_string_literal: true
Sequel.migration do
change do
create_table(:storage_key_encryption_key) do
column :id, :uuid, primary_key: true, default: Sequel.lit("gen_random_uuid()")
column :algorithm, :text, null: false, collate: '"C"'
column :key, :text, null: false
column :init_vector, :text, null: false
column :auth_data, :text, null: false
column :created_at, :timestamptz, null: false, default: Sequel.lit("now()")
end
alter_table(:vm_storage_volume) do
add_foreign_key :key_encryption_key_1_id, :storage_key_encryption_key, type: :uuid, null: true
add_foreign_key :key_encryption_key_2_id, :storage_key_encryption_key, type: :uuid, null: true
end
end
end