Skip to content

Commit 897faad

Browse files
committed
feat(secret_registration_client): add secret registration client service creation
The secret registration client service is the counterpart of the server service. It does 1. register the trustee client with server by an attestation. 2. fetch the key created by server service and mount the encrypted disk. Signed-off-by: Li Tian <litian@redhat.com>
1 parent e7b6c1d commit 897faad

16 files changed

Lines changed: 321 additions & 100 deletions

README.md

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,50 +7,28 @@
77
Ansible role for deploying Trustee Guest Components using Podman Quadlets for
88
confidential virtual machine deployments. The role downloads quadlet files and
99
configuration files from a GitHub repository, installs them, and manages them as
10-
systemd services. The role also supports optional disk encryption functionality for
11-
securing additional storage devices.
12-
13-
The role will:
14-
15-
1. Install Podman and Git if not already present
16-
2. Download Trustee Guest Components quadlet files and config files from the
17-
specified GitHub repository
18-
3. Copy quadlet files (`.container`, `.volume`, `.network`, `.kube`) to the
19-
install directory (`/etc/containers/systemd` by default)
20-
4. Copy config files from the repository's `configs` directory to `/etc/trustee-gc/`
21-
5. Replace `KBS_URL` and `KBS_CERT` placeholders in `/etc/trustee-gc/cdh/config.toml`
22-
with the values from `trustee_attestation_client_trustee_kbs_url` and `trustee_attestation_client_trustee_kbs_cert`
23-
variables (if provided)
24-
6. Reload systemd daemon
25-
7. Enable and start the Trustee Guest Components services
26-
8. (Optional) If `trustee_attestation_client_encrypt_disk` is `true`:
27-
- Find an unpartitioned and unmounted disk
28-
- Create a GPT partition table and partition on the disk
29-
- Generate an encryption key and encrypt the partition using LUKS
30-
- Format the encrypted partition with ext4
31-
- Mount the encrypted disk at the specified mount point
32-
- Store the encryption key in the `encrypted_disk_key` fact
10+
systemd services. The role also supports an optional secret registration client
11+
for disk key registration and optional disk encryption for securing additional
12+
storage devices.
13+
14+
## Features
15+
16+
- **Trustee Client (Quadlet)**: Deploys Trustee guest components Attestation Agent(AA), Confidential Data Hub(CDH) and API Server REST(ASR) using Podman Quadlets from a Github repository
17+
- **Secret Registration Client**: Utility script and service which registers to Secret Registration Server on Trustee Server. It acquires the encryption key from Trustee and decrypts the designated disk upon boot
18+
- **Encrypt Disk**: Does LUKS2 encryption of the found empty data disk. The encryption key is provided by Secret Registration Client.
3319

3420
Example of setting the variables:
3521

3622
```yaml
3723
trustee_attestation_client_quadlet_repo_url: "https://github.com/litian1992/trustee-gc-quadlet-rhel"
3824
trustee_attestation_client_quadlet_repo_path: "quadlet"
3925
trustee_attestation_client_quadlet_repo_branch: "main"
40-
trustee_attestation_client_trustee_kbs_url: "https://kbs.example.com"
41-
trustee_attestation_client_trustee_kbs_cert: "/path/to/cert.pem"
26+
trustee_attestation_client_kbs_url: "https://kbs.example.com"
27+
trustee_attestation_client_kbs_cert_content: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
28+
trustee_attestation_client_secret_registration_enabled: true
4229
trustee_attestation_client_encrypt_disk: true
4330
```
4431
45-
## Variables Exported by the Role
46-
47-
### encrypted_disk_key
48-
49-
If disk encryption is enabled (`trustee_attestation_client_encrypt_disk: true`), this fact
50-
contains the base64-encoded encryption key for the encrypted disk. This key is
51-
required to mount the encrypted disk after a reboot. The key is automatically
52-
generated during disk encryption and should be securely stored for future use.
53-
5432
## Example Playbook
5533
5634
Including an example of how to use your role (for instance, with variables
@@ -63,13 +41,37 @@ passed in as parameters) is always nice for users too:
6341
trustee_attestation_client_quadlet_repo_url: "https://github.com/litian1992/trustee-gc-quadlet-rhel"
6442
trustee_attestation_client_quadlet_repo_path: "quadlet"
6543
trustee_attestation_client_quadlet_repo_branch: "main"
66-
trustee_attestation_client_trustee_kbs_url: "https://kbs.example.com"
67-
trustee_attestation_client_trustee_kbs_cert: "/path/to/kbs-cert.pem"
44+
trustee_attestation_client_kbs_url: "https://kbs.example.com"
45+
trustee_attestation_client_kbs_cert_content: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
46+
trustee_attestation_client_secret_registration_enabled: true
6847
trustee_attestation_client_encrypt_disk: true
6948
roles:
7049
- linux-system-roles.trustee_attestation_client
7150
```
7251
52+
## Trustee Client
53+
54+
The task:
55+
56+
1. Downloads the Podman Quadlets from designated repo
57+
2. Configures the settings in /etc/trustee-gc/
58+
3. Enables and starts trustee-gc.pod as a service
59+
60+
## Secret Registration Client
61+
62+
When enabled, this task:
63+
64+
1. Sends registration request to Secret Registration Server via HTTPS to acquire disk encryption keys
65+
2. Requests above disk encryption key upon boot when Encrypt Disk is enabled to decrypt and mount disk
66+
67+
## Encrypt Disk
68+
69+
When enabled, this task:
70+
71+
1. Finds the first unpartitioned and unmounted disk
72+
2. Requests disk encryption key from Secret Registration Client
73+
3. Encrypts the disk using above encryption key and mounts it at the designated path
74+
7375
## License
7476
7577
Whenever possible, please prefer MIT.

defaults/main.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ trustee_attestation_client_quadlet_repo_branch: "main"
1111
trustee_attestation_client_quadlet_install_dir: "/etc/containers/systemd"
1212

1313
# Trustee KBS configuration
14-
trustee_attestation_client_trustee_kbs_url: ""
15-
trustee_attestation_client_trustee_kbs_cert: ""
14+
trustee_attestation_client_kbs_url: ""
15+
trustee_attestation_client_kbs_cert_content: ""
16+
17+
# Secret registration client configuration
18+
trustee_attestation_client_secret_registration_enabled: false
1619

1720
# Encrypt disk configuration
1821
trustee_attestation_client_encrypt_disk: false

examples/simple.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
trustee_attestation_client_quadlet_repo_branch: "main"
99
trustee_attestation_client_quadlet_install_dir: "/etc/containers/systemd"
1010
trustee_attestation_client_encrypt_disk: false
11-
trustee_attestation_client_trustee_kbs_url: "https://kbs.example.com"
12-
trustee_attestation_client_trustee_kbs_cert: "/path/to/kbs-cert.pem"
11+
trustee_attestation_client_kbs_url: "https://kbs.example.com"
12+
trustee_attestation_client_kbs_cert_content: "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
13+
trustee_attestation_client_secret_registration_enabled: false
1314
roles:
1415
- linux-system-roles.trustee_attestation_client

handlers/main.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
# SPDX-License-Identifier: MIT
22
---
3-
- name: Handler for trustee_attestation_client to restart services
4-
service:
3+
- name: Reload systemd daemon for trustee
4+
ansible.builtin.systemd:
5+
daemon_reload: true
6+
listen: "restart trustee services"
7+
8+
- name: Enable and restart trustee services
9+
ansible.builtin.systemd:
510
name: "{{ item }}"
11+
enabled: true
612
state: restarted
7-
loop: "{{ __trustee_attestation_client_services }}"
13+
loop: "{{ __trustee_attestation_client_services | default([]) }}"
14+
listen: "restart trustee services"

meta/main.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ galaxy_info:
1414
versions:
1515
- "9"
1616
galaxy_tags:
17+
- trustee
18+
- attestation
1719
- el9
1820
- el10
1921
- fedora

tasks/encrypt_disk.yml

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,16 @@
1515
}
1616
}
1717
'
18-
register: unpartitioned_disk
18+
register: __trustee_attestation_client_unpartitioned_disk
1919
changed_when: false
2020
failed_when: false
2121

2222
- name: Encrypt disk
23-
when: unpartitioned_disk.stdout != ""
23+
when: __trustee_attestation_client_unpartitioned_disk.stdout != ""
24+
vars:
25+
__trustee_attestation_client_disk_device: "/dev/{{ __trustee_attestation_client_unpartitioned_disk.stdout }}"
26+
__trustee_attestation_client_disk_partition: >-
27+
/dev/{{ __trustee_attestation_client_unpartitioned_disk.stdout }}{{ 'p' if 'nvme' in __trustee_attestation_client_unpartitioned_disk.stdout else '' }}1
2428
block:
2529
- name: Ensure packages for disk encryption are installed
2630
ansible.builtin.package:
@@ -29,48 +33,32 @@
2933
use: "{{ (__trustee_attestation_client_is_ostree | d(false)) |
3034
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
3135

32-
- name: Set fact with disk device path and partition path
33-
ansible.builtin.set_fact:
34-
disk_device: "/dev/{{ unpartitioned_disk.stdout }}"
35-
disk_partition: >-
36-
/dev/{{ unpartitioned_disk.stdout }}{{ 'p' if 'nvme' in unpartitioned_disk.stdout else '' }}1
36+
- name: Create temporary file for disk encryption key
37+
ansible.builtin.tempfile:
38+
state: file
39+
suffix: .bin
40+
register: __trustee_attestation_client_secret_key_tempfile
3741

38-
- name: Create partition table and partition on disk
42+
- name: Acquire disk encryption key from Secret Registration Client service
3943
ansible.builtin.shell: |
40-
parted -s {{ disk_device }} mklabel gpt
41-
parted -s {{ disk_device }} mkpart primary ext4 0% 100%
44+
/usr/local/bin/secret_registration_client.sh --fetch-key-to {{ __trustee_attestation_client_secret_key_tempfile.path }}
4245
changed_when: true
46+
no_log: true
4347

44-
- name: Generate a temp file for the key
45-
ansible.builtin.tempfile:
46-
state: file
47-
register: __trustee_attestation_client_tmp_key
48-
49-
- name: Generate a key and encrypt the partition
48+
- name: Encrypt the partition
5049
ansible.builtin.shell: |
5150
set -o pipefail
52-
head -c 32 /dev/urandom | base64 > {{ __trustee_attestation_client_tmp_key.path }}
53-
cryptsetup luksFormat --key-file {{ __trustee_attestation_client_tmp_key.path }} --batch-mode {{ disk_partition }}
54-
cryptsetup open --key-file {{ __trustee_attestation_client_tmp_key.path }} {{ disk_partition }} encrypted-disk
51+
parted -s {{ __trustee_attestation_client_disk_device }} mklabel gpt
52+
parted -s {{ __trustee_attestation_client_disk_device }} mkpart primary ext4 0% 100%
53+
cryptsetup luksFormat --key-file {{ __trustee_attestation_client_secret_key_tempfile.path }} --batch-mode {{ __trustee_attestation_client_disk_partition }}
54+
cryptsetup open --key-file {{ __trustee_attestation_client_secret_key_tempfile.path }} {{ __trustee_attestation_client_disk_partition }} encrypted-disk
5555
mkfs.ext4 /dev/mapper/encrypted-disk
5656
[ -d {{ trustee_attestation_client_encrypt_disk_mount_point }} ] || mkdir -p {{ trustee_attestation_client_encrypt_disk_mount_point }}
5757
mount /dev/mapper/encrypted-disk {{ trustee_attestation_client_encrypt_disk_mount_point }}
5858
changed_when: true
5959
no_log: true
6060

61-
- name: Read key from remote host
62-
ansible.builtin.slurp:
63-
src: "{{ __trustee_attestation_client_tmp_key.path }}"
64-
register: slurped_key
65-
no_log: true
66-
67-
- name: Set encrypted disk key fact
68-
ansible.builtin.set_fact:
69-
encrypted_disk_key: "{{ slurped_key.content }}"
70-
no_log: true
71-
72-
- name: Clean up temporary key file
61+
- name: Clean up disk encryption key file
7362
ansible.builtin.file:
74-
path: "{{ __trustee_attestation_client_tmp_key.path }}"
63+
path: "{{ __trustee_attestation_client_secret_key_tempfile.path }}"
7564
state: absent
76-
# TODO: Add a systemd service to mount the encrypted disk at boot

tasks/main.yml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,21 @@
33
- name: Set platform/version specific variables
44
include_tasks: tasks/set_vars.yml
55

6-
- name: Create encrypted disk partition
7-
include_tasks: encrypt_disk.yml
8-
when: trustee_attestation_client_encrypt_disk | bool
9-
106
- name: Deploy Trustee Guest Components using Podman Quadlets
117
include_tasks: trustee_quadlet.yml
128
when: trustee_attestation_client_trustee_gc | bool
9+
10+
- name: Deploy Secret Registration Client Service
11+
include_tasks: secret_registration_client.yml
12+
when:
13+
- trustee_attestation_client_secret_registration_enabled | bool
14+
- trustee_attestation_client_trustee_gc | bool
15+
16+
- name: Create encrypted disk partition
17+
include_tasks: encrypt_disk.yml
18+
when:
19+
- trustee_attestation_client_encrypt_disk | bool
20+
- trustee_attestation_client_secret_registration_enabled | bool
21+
22+
- name: Flush handlers to ensure services are started
23+
ansible.builtin.meta: flush_handlers
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# SPDX-License-Identifier: MIT
2+
---
3+
# Secret registration client: registers with server using attestation,
4+
# fetches disk encryption key from Trustee KBS.
5+
# Requires Trustee GC (trustee_attestation_client_trustee_gc).
6+
7+
- name: Ensure secret registration client dependencies are installed
8+
ansible.builtin.package:
9+
name: "{{ __trustee_attestation_client_secret_registration_client_packages }}"
10+
state: present
11+
use: "{{ (__trustee_attestation_client_is_ostree | d(false)) |
12+
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
13+
14+
- name: Deploy secret registration client script
15+
ansible.builtin.template:
16+
src: secret_registration_client.sh.j2
17+
dest: "/usr/local/bin/secret_registration_client.sh"
18+
mode: "0755"
19+
register: __trustee_attestation_client_reg_script
20+
21+
- name: Deploy secret registration client systemd unit
22+
ansible.builtin.template:
23+
src: secret_registration_client.service.j2
24+
dest: /etc/systemd/system/secret_registration_client.service
25+
mode: "0644"
26+
register: __trustee_attestation_client_service
27+
28+
- name: Append secret_registration_client to services list
29+
ansible.builtin.set_fact:
30+
__trustee_attestation_client_services: >-
31+
{{ __trustee_attestation_client_services | default([]) + ['secret_registration_client'] }}
32+
notify: "restart trustee services"

tasks/trustee_quadlet.yml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,19 @@
7575
loop:
7676
- path: /etc/trustee-gc/cdh/config.toml
7777
regexp: KBS_URL
78-
replace: "{{ trustee_attestation_client_trustee_kbs_url }}"
78+
replace: "{{ trustee_attestation_client_kbs_url }}"
7979
- path: /etc/trustee-gc/cdh/config.toml
8080
regexp: KBS_CERT
81-
replace: "{{ trustee_attestation_client_trustee_kbs_cert }}"
81+
replace: "{{ trustee_attestation_client_kbs_cert_content }}"
8282
- path: /etc/trustee-gc/aa/config.toml
8383
regexp: KBS_URL
84-
replace: "{{ trustee_attestation_client_trustee_kbs_url }}"
84+
replace: "{{ trustee_attestation_client_kbs_url }}"
8585
- path: /etc/trustee-gc/aa/config.toml
8686
regexp: KBS_CERT
87-
replace: "{{ trustee_attestation_client_trustee_kbs_cert }}"
87+
replace: "{{ trustee_attestation_client_kbs_cert_content }}"
8888
when:
8989
- __repo_configs_dir.stat.exists
90-
- trustee_attestation_client_trustee_kbs_url != "" or trustee_attestation_client_trustee_kbs_cert != ""
90+
- trustee_attestation_client_kbs_url != "" or trustee_attestation_client_kbs_cert_content != ""
9191

9292
- name: Stat /dev/sev-guest device
9393
ansible.builtin.stat:
@@ -101,10 +101,6 @@
101101
replace: 'AddDevice=/dev/sev-guest'
102102
when: __sev_guest_device.stat.exists
103103

104-
- name: Reload systemd daemon
105-
ansible.builtin.systemd:
106-
daemon_reload: true
107-
108104
- name: Get the installed Trustee Guest Components pod name
109105
ansible.builtin.find:
110106
paths: "{{ trustee_attestation_client_quadlet_install_dir }}"
@@ -120,6 +116,13 @@
120116
when: trustee_gc_pod_name.files | length > 0
121117
failed_when: false
122118

119+
- name: Write KBS certificate to /etc/trustee-gc/server.crt
120+
ansible.builtin.copy:
121+
content: "{{ trustee_attestation_client_kbs_cert_content }}"
122+
dest: /etc/trustee-gc/server.crt
123+
mode: "0644"
124+
when: trustee_attestation_client_kbs_cert_content | length > 0
125+
123126
- name: Clean up temporary repository directory
124127
ansible.builtin.file:
125128
path: "{{ __trustee_attestation_client_quadlet_repo_dir.path }}"

templates/foo.conf.j2

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)