Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions roles/sed_configure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
Role Definition
-------------------------------
- Role name: sed
- Definition:
- The self-encrypting drives (SED) support protects data at rest on IBM Storage Scale System drives.
- TPM is a specialized hardware security chip that provides secure cryptographic functions.
- mmvdisk tpm , esstpm and esstpmkey provides options to setup the tpm ,generate keys, enroll drives with the generated keys in the IBM Storage Scale cluster.
- These operations are performed on the I/O nodes and the keys generated are also backed up on the utility node.


Prerequisite
----------------------------
- Red Hat Enterprise Linux 9.x is supported.
- OpenSSL version 3+ is supported.
- TPM version 2.0 is required to use this support
- A password file with appropriate permissions (600) must exist for taking TPM ownership.

Design
---------------------------
- Directory Structure:
- Path: /ibm-spectrum-scale-install-infra/roles/sed_configure
- Inside the sed role, there are sub-tasks to setup the TPM stepwise
- `check_prereq`: This task checks that all the prerequisites are satisfied before proceeding with the TPM setup. It checks the following things:
- RHEL 9.x is present.
- OpenSSL 3+ version present.
- Check whether TPM is enabled from BIOS.
- Check tpm2-tools rpms. If not installed already, install it.
- `tpm_ownership`: This task sets up the TPM to be used.
- check if tpm ownership already taken, if yes skip the entire process after validating the ownership
- if not taken, we proceed to take the ownership
- if 'change_pasword' flag is set, we skip the setup and jump to the password change
- `create_nv_slots`: This task create NV slots which will be used for key generation.
- `generate_tpm_key`: This task generated a tpm key in the mentioned nv slot.
- `enroll_sed`: This task enrolls an sed using the tpm key
- `manage_key`: This task handles the backup and restore of the tpm key.
21 changes: 21 additions & 0 deletions roles/sed_configure/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
scale_sed_config:
tpm_password_file: "/path/to/password.txt"
new_tpm_password_file: "/path/to/newpassword.txt"
disable_clear: true
change_password: false
nv_slot_id: "0x01500000"
nv_slot_count: 4
recovery_group: "RecoveryGroupName"
enroll_drive: false
rekey_drive: false
generate: false
migrate: false
backup_key: false
restore_key: false
io_nodes:
- ionode1
- ionode2
utility_nodes:
- utilitynode
emsvm:
- emsvmnode
18 changes: 18 additions & 0 deletions roles/sed_configure/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
galaxy_info:
author: IBM Corporation
description: Highly-customizable Ansible role for installing and configuring IBM Spectrum Scale (GPFS)
company: IBM

license: Apache-2.0

min_ansible_version: 2.9

platforms:
- name: EL
versions:
- 9

galaxy_tags: []

dependencies: []
50 changes: 50 additions & 0 deletions roles/sed_configure/tasks/check_prereq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
- block:
# Check the OpenSSL version and fail if the version is < 3
- name: Check OpenSSL version
command: openssl version
register: openssl_version_output
changed_when: false
failed_when: openssl_version_output.stdout | regex_search('OpenSSL\s([0-2]\\.[0-9]+)')

- debug:
msg: "{{(openssl_version_output.rc == 0) | ternary(openssl_version_output.stdout.split('\n'), openssl_version_output.stderr.split('\n')) }}"

# Check the OS version and fail if the version is < RHEL 9
- name: Check OS version
command: cat /etc/redhat-release
register: os_version_output
changed_when: false
failed_when: os_version_output.stdout | regex_search('release\s([0-8])')

- debug:
msg: "{{(os_version_output.rc == 0) | ternary(os_version_output.stdout.split('\n'), os_version_output.stderr.split('\n')) }}"
delegate_to: "{{ item }}"

- block:
- name: Check TPM presence
stat:
path: /dev/tpm0
register: tpm_device

- debug:
msg: "TPM device present"
when: tpm_device.stat.exists

- fail:
msg: "TPM is not enabled in BIOS. Please enable it manually before proceeding."
when: not tpm_device.stat.exists

- name: Check if tpm2-tools is installed
command: rpm -q tpm2-tools
register: tpm2_tools_check
ignore_errors: true
changed_when: false

- name: Install tpm2-tools if not present
yum:
name: tpm2-tools
state: present
when: tpm2_tools_check.rc != 0
delegate_to: "{{ item }}"
when: item in scale_sed_config.io_nodes
24 changes: 24 additions & 0 deletions roles/sed_configure/tasks/create_nv_slot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- block:
# Creation of NV slots on IO nodes
- name: Create NV slots
command: mmvdisk tpm createSlots --number-of-slots {{ scale_sed_config.nv_slot_count }} --nv-slot-id {{ scale_sed_config.nv_slot_id }} --password-file {{ scale_sed_config.tpm_password_file }}
register: nv_slot_creation_io
failed_when: nv_slot_creation_io.rc != 0

- debug:
msg: "{{(nv_slot_creation_io.rc == 0) | ternary(nv_slot_creation_io.stdout.split('\n'), nv_slot_creation_io.stderr.split('\n')) }}"
delegate_to: "{{ item }}"
when: item in scale_sed_config.io_nodes

- block:
# Creation of NV slots on utility nodes
- name: Create NV slots on utility node
command: /opt/ibm/ess/tools/bin/.TPM/./esstpm createslot --nv-slot-id {{scale_sed_config.nv_slot_id}} --password-file {{ scale_sed_config.tpm_password_file }}
register: nv_slot_creation_utility
failed_when: nv_slot_creation_utility.rc != 0

- debug:
msg: "{{(nv_slot_creation_utility.rc == 0) | ternary(nv_slot_creation_utility.stdout.split('\n'), nv_slot_creation_utility.stderr.split('\n')) }}"
delegate_to: "{{ item }}"
when: item in scale_sed_config.utility_nodes
26 changes: 26 additions & 0 deletions roles/sed_configure/tasks/enroll_sed_drive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
- block:
# Enrolling the SED with the generated TPM key
- name: Enroll drives with TPM key
command: mmvdisk sed enroll --recovery-group {{ scale_sed_config.recovery_group }} --tpm-slot-id {{ scale_sed_config.nv_slot_id }} --confirm
register: drive_enrollment

- debug:
msg: "{{(drive_enrollment.rc == 0) | ternary(drive_enrollment.stdout.split('\n'), drive_enrollment.stderr.split('\n')) }}"
failed_when: drive_enrollment.rc != 0
delegate_to: "{{ item }}"
run_once: true
when: scale_sed_config.enroll_drive

- block:
# Rekeying the SED with the a new TPM key
- name: Rekey drives with new TPM key
command: mmvdisk sed rekey --recovery-group {{ scale_sed_config.recovery_group }} --tpm-slot-id {{ scale_sed_config.nv_slot_id }} --confirm
register: drive_rekey

- debug:
msg: "{{(drive_rekey.rc == 0) | ternary(drive_rekey.stdout.split('\n'), drive_rekey.stderr.split('\n')) }}"
failed_when: drive_rekey.rc != 0
delegate_to: "{{ item }}"
run_once: true
when: scale_sed_config.rekey_drive
28 changes: 28 additions & 0 deletions roles/sed_configure/tasks/generate_tpm_key.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
- block:
# Generate a TPM key
- name: Generate TPM key
command: mmvdisk tpm genkey --nv-slot-id {{ scale_sed_config.nv_slot_id }} --password-file {{ scale_sed_config.tpm_password_file }}
register: tpm_key_generate

- debug:
msg: "{{(tpm_key_generate.rc == 0) | ternary(tpm_key_generate.stdout.split('\n'), tpm_key_generate.stderr.split('\n')) }}"
failed_when: tpm_key_generate.rc != 0
delegate_to: "{{ item }}"
when: scale_sed_config.generate
run_once: true

- block:
# Migrate the generated TPM key to other io nodes
- name: Migrate TPM key to other nodes
command: mmvdisk tpm migratekey --nv-slot-id {{ scale_sed_config.nv_slot_id }} -s {{ scale_sed_config.io_nodes.0 }} -N {{ target_nodes | join(',') }}
vars:
target_nodes: "{{ scale_sed_config.io_nodes[1:] }}"
register: tpm_key_migrate

- debug:
msg: "{{ (tpm_key_migrate.rc == 0) | ternary(tpm_key_migrate.stdout.split('\n'),tpm_key_migrate.stderr.split('\n')) }}"
failed_when: tpm_key_migrate.rc != 0
delegate_to: "{{ io_nodes.0 }}"
when: scale_sed_config.migrate
run_once: true
22 changes: 22 additions & 0 deletions roles/sed_configure/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
- include_tasks: check_prereq.yml
tags: check prerequisites
loop: "{{ io_nodes + utility_nodes }}"

- include_tasks: tpm_ownership.yml
tags: tpm ownership
loop: "{{ io_nodes + utility_nodes }}"

- include_tasks: create_nv_slot.yml
tags: create nv slot
loop: "{{ io_nodes + utility_nodes }}"

- include_tasks: generate_tpm_key.yml
tags: generate tpm key

- include_tasks: enroll_sed_drive.yml
tags: enroll sed drive

- include_tasks: manage_key.yml
tags: restore and backup key
loop: "{{ emsvm }}"
27 changes: 27 additions & 0 deletions roles/sed_configure/tasks/manage_key.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
- block:
- name: Backup TPM key
command: /opt/ibm/ess/tools/bin/.TPM/./esstpmkey backup --source-node {{ source_node }} --destination-node {{ dest_node }} --tpm-slot-id {{ scale_sed_config.nv_slot_id }} --destination-node-password-file {{ scale_sed_config.tpm_password_file}}
vars:
source_node: "{{ scale_sed_config.io_nodes[0]}}"
dest_node: "{{ scale_sed_config.utility_nodes[0] }}"
register: backup_key
when: scale_sed_config.backup

- debug:
msg: "{{(backup_key.rc == 0) | ternary(backup_key.stdout.split('\n'), backup_key.stderr.split('\n')) }}"
when: scale_sed_config.backup

- name: Restore TPM key from backup
command: /opt/ibm/ess/tools/bin/.TPM/./esstpmkey restore --source-node {{ source_node }} --destination-node {{ dest_node }} --tpm-slot-id {{ scale_sed_config.nv_slot_id }} --source-node-password-file {{ scale_sed_config.tpm_password_file}}
vars:
source_node: "{{ scale_sed_config.utility_nodes[0] }}"
dest_node: "{{ scale_sed_config.io_nodes[0] }}"
register: restore_key
when: scale_sed_config.restore

- debug:
msg: "{{(restore_key.rc == 0) | ternary(restore_key.stdout.split('\n'), restore_key.stderr.split('\n')) }}"
when: scale_sed_config.restore
delegate_to: "{{ item }}"
run_once: true
112 changes: 112 additions & 0 deletions roles/sed_configure/tasks/tpm_ownership.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
- name: Check if ownership already taken on IO nodes
shell: |
tpm2_getcap properties-variable | awk -F': *' '/ownerAuthSet:/ { v=tolower($2); print (v ~ /(^1$|set|true)/) ? 1 : 0; exit }'
register: ownership_taken_io
changed_when: false
delegate_to: "{{ item }}"
when: item in scale_sed_config.io_nodes

- name: Check if ownership already taken on utility node
shell: |
tpm2_getcap properties-variable | awk -F': *' '/ownerAuthSet:/ { v=tolower($2); print (v ~ /(^1$|set|true)/) ? 1 : 0; exit }'
register: ownership_taken_utility
changed_when: false
delegate_to: "{{ item }}"
when: item in scale_sed_config.utility_nodes

# skip the setup -> if ownership taken. We mention that ownership is taken, validate it. And continue to nv slot creation.
- block:
- name: Validate ownership password
debug:
msg: Ownership already taken. Skipping the tpm ownership setup.

- name: Check the password
command: mmvdisk tpm chpasswd --old-password-file {{ scale_sed_config.tpm_password_file }} --new-password-file {{ scale_sed_config.tpm_password_file }}
register: pwd_validation_io

- debug:
msg: "Validated the Ownership successfully"
when: pwd_validation_io.rc == 0

- fail:
msg: "Ownership password did not match. Please verify"
when: pwd_validation_io.rc != 0
delegate_to: "{{ item }}"
when: item in scale_sed_config.io_nodes and ownership_taken_io.stdout == '1' and not scale_sed_config.change_password

- block:
- name: Validate ownership password
debug:
msg: Ownership already taken. Skipping the tpm ownership setup.

- name: Check the password
command: /opt/ibm/ess/tools/bin/.TPM/./esstpm chpasswd --old-password-file {{ scale_sed_config.tpm_password_file }} --new-password-file {{ scale_sed_config.tpm_password_file }}
register: pwd_validation_utility

- debug:
msg: "Validated the Ownership successfully"
when: pwd_validation_utility.rc == 0

- fail:
msg: "Ownership password did not match. Please verify"
when: pwd_validation_utility.rc != 0
delegate_to: "{{ item }}"
when: item in scale_sed_config.utility_nodes and ownership_taken_utility.stdout == '1' and not scale_sed_config.change_password

# if tpm ownership not taken already, proceed to take it on io nodes
- block:
- name: Disable TPM clear
command: tpm2_clearcontrol -C l s
register: disable_operation
when: disable_clear

- name: Take TPM ownership # ensure file permission is 600
command: mmvdisk tpm setup --password-file {{ scale_sed_config.tpm_password_file }}
register: take_ownership_io

- debug:
msg: "{{(take_ownership_io.rc == 0) | ternary(take_ownership_io.stdout.split('\n'),take_ownership_io.stderr.split('\n')) }}"
delegate_to: "{{ item }}"
when: item in scale_sed_config.io_nodes and ownership_taken_io.stdout == '0' and not scale_sed_config.change_password

# if tpm ownership not taken already, proceed to take it on utility node
- block:
- name: Disable TPM clear
command: tpm2_clearcontrol -C l s
register: disable_operation
when: disable_clear

- name: Take TPM ownership on utility node
command: /opt/ibm/ess/tools/bin/.TPM/./esstpm setup --password-file {{ scale_sed_config.tpm_password_file }}
register: take_ownership_utility

- debug:
msg: "{{(take_ownership_utility.rc == 0) | ternary(take_ownership_utility.stdout.split('\n'), take_ownership_utility.stderr.split('\n')) }}"
delegate_to: "{{ item }}"
when: item in scale_sed_config.utility_nodes and ownership_taken_utility.stdout == '0' and not scale_sed_config.change_password

# execute only when change password is set to true.
- block:
# Change password on IO nodes
- name: Change TPM Ownership password
command: mmvdisk tpm chpasswd --old-password-file {{ scale_sed_config.tpm_password_file }} --new-password-file {{ scale_sed_config.new_tpm_password_file }}
register: change_pw_io
failed_when: change_pw_io.rc != 0

- debug:
msg: "{{(change_pw_io.rc == 0) | ternary(change_pw_io.stdout.split('\n'), change_pw_io.stderr.split('\n')) }}"
delegate_to: "{{ item }}"
when: item in scale_sed_config.io_nodes and scale_sed_config.change_password

- block:
# Change password on Utility node
- name: Change TPM Ownership password
command: /opt/ibm/ess/tools/bin/.TPM/./esstpm chpasswd --old-password-file {{ scale_sed_config.tpm_password_file }} --new-password-file {{ scale_sed_config.new_tpm_password_file }}
register: change_pw_utility
failed_when: change_pw_utility.rc != 0

- debug:
msg: "{{(change_pw_utility.rc == 0) | ternary(change_pw_utility.stdout.split('\n'), change_pw_utility.stderr.split('\n')) }}"
delegate_to: "{{ item }}"
when: item in scale_sed_config.utility_nodes and scale_sed_config.change_password
7 changes: 7 additions & 0 deletions samples/playbook_sed_tpm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
- hosts: all
become: no
pre_tasks:
- include_vars: sed_tpm_vars.yml
roles:
- sed_configure
Loading