Skip to content

Commit

Permalink
feat: Allow creating encrypted Stratis Pools with Clevis/Tang
Browse files Browse the repository at this point in the history
Tang server configuration or TPM2 can now be used when creating
an encrypted Stratis Pool.

Related: RHEL-31854
  • Loading branch information
vojtechtrefny committed May 16, 2024
1 parent 76976c5 commit fb2481a
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 2 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ keys:

This integer specifies the LUKS version to use.

- `encryption_clevis_pin`

For Stratis pools, the clevis method that should be used to encrypt the created pool.
Accepted values are: `tang` and `tpm2`

- `encryption_tang_url`

When creating a Stratis pool encrypted via NBDE using a tang server,
specifies the URL of the server.

- `encryption_tang_thumbprint`

When creating a Stratis pool encrypted via NBDE using a tang server,
specifies the thumbprint of the server.

### `storage_volumes`

The `storage_volumes` variable is a list of volumes to manage. Each volume has the following
Expand Down
28 changes: 27 additions & 1 deletion library/blivet.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,15 @@
encryption_password:
description: encryption_password
type: str
encryption_clevis_pin:
description: encryption_clevis_pin
type: str
encryption_tang_url:
description: encryption_tang_url
type: str
encryption_tang_thumbprint:
description: encryption_tang_thumbprint
type: str
name:
description: name
type: str
Expand Down Expand Up @@ -1907,6 +1916,12 @@ def _update_from_device(self, param_name):
self._pool['disks'] = [d.name for d in self._device.disks]
elif param_name == 'encryption':
self._pool['encryption'] = self._device.encrypted
elif param_name == 'encryption_clevis_pin':
self._pool['encryption_clevis_pin'] = self._device._clevis.pin
elif param_name == 'encryption_tang_url':
self._pool['encryption_tang_url'] = self._device._clevis.tang_url
elif param_name == 'encryption_tang_thumbprint':
self._pool['encryption_tang_thumbprint'] = self._device._clevis.tang_thumbprint
else:
return False

Expand Down Expand Up @@ -1961,11 +1976,19 @@ def _create(self):
if not self._device:
members = self._create_members()
try:
if self._spec_dict['encryption'] and self._spec_dict['encryption_clevis_pin']:
clevis_config = devices.stratis.StratisClevisConfig(pin=self._spec_dict['encryption_clevis_pin'],
tang_url=self._spec_dict['encryption_tang_url'],
tang_thumbprint=self._spec_dict['encryption_tang_thumbprint'])
else:
clevis_config = None

pool_device = self._blivet.new_stratis_pool(name=self._pool['name'],
parents=members,
encrypted=self._spec_dict['encryption'],
passphrase=self._spec_dict.get('encryption_password') or None,
key_file=self._spec_dict.get('encryption_key') or None)
key_file=self._spec_dict.get('encryption_key') or None,
clevis=clevis_config)
except Exception as e:
raise BlivetAnsibleError("failed to set up pool '%s': %s" % (self._pool['name'], str(e)))

Expand Down Expand Up @@ -2291,6 +2314,9 @@ def run_module():
encryption_key_size=dict(type='int'),
encryption_luks_version=dict(type='str'),
encryption_password=dict(type='str', no_log=True),
encryption_clevis_pin=dict(type='str'),
encryption_tang_url=dict(type='str'),
encryption_tang_thumbprint=dict(type='str'),
name=dict(type='str'),
raid_level=dict(type='str'),
raid_device_count=dict(type='int'),
Expand Down
37 changes: 37 additions & 0 deletions tests/tests_stratis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,40 @@

- name: Verify role results
include_tasks: verify-role-results.yml

- name: Setup Tang server on localhost for testing
ansible.builtin.include_role:
name: linux-system-roles.nbde_server
vars:
nbde_server_manage_firewall: true
nbde_server_manage_selinux: true
nbde_server_port: 7500

- name: Create encrypted Stratis pool with Clevis/Tang
include_role:
name: linux-system-roles.storage
vars:
storage_pools:
- name: foo
disks: "{{ unused_disks[0] }}"
type: stratis
encryption: true
encryption_password: yabbadabbadoo
encryption_clevis_pin: tang
encryption_tang_url: localhost:7500

- name: Verify role results
include_tasks: verify-role-results.yml

- name: Clean up
include_role:
name: linux-system-roles.storage
vars:
storage_pools:
- name: foo
disks: "{{ unused_disks[0] }}"
type: stratis
state: absent

- name: Verify role results
include_tasks: verify-role-results.yml
15 changes: 14 additions & 1 deletion tests/verify-pool-stratis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,26 @@
- name: Verify that encryption is correctly set
assert:
that: storage_test_pool.name in
_stratis_pool_info[0]['blockdevs']['datadevs'][0]['key_description']
_stratis_pool_info.pools[0]['blockdevs']['datadevs'][0]['key_description']
msg: >-
Stratis pool '{{ storage_test_pool.name }}' is not encrypted
when:
- storage_test_pool.state == 'present'
- storage_test_pool.encryption

- name: Verify that Clevis/Tang encryption is correctly set
assert:
that:
_stratis_pool_info.pools[0]['blockdevs']['datadevs'][0]['clevis_pin'] == 'tang' and
_stratis_pool_info.pools[0]['blockdevs']['datadevs'][0]['clevis_config']['url'] ==
storage_test_pool.encryption_tang_url
msg: >-
Stratis pool '{{ storage_test_pool.name }}' Clevis is not correctly configured
when:
- storage_test_pool.state == 'present'
- storage_test_pool.encryption
- storage_test_pool.encryption_clevis_pin == 'tang'

- name: Reset variable used by test
set_fact:
storage_test_stratis_report: null

0 comments on commit fb2481a

Please sign in to comment.