LUKS enrollment and RHEL cmdline/BLS
This commit is contained in:
365
roles/configuration/tasks/encryption.yml
Normal file
365
roles/configuration/tasks/encryption.yml
Normal file
@@ -0,0 +1,365 @@
|
||||
---
|
||||
- name: Configure disk encryption
|
||||
when: partitioning_luks_enabled | default(luks_enabled | default(false)) | bool
|
||||
vars:
|
||||
configuration_luks_passphrase_effective: >-
|
||||
{{ (partitioning_luks_passphrase | default(luks_passphrase | default(''))) | string }}
|
||||
block:
|
||||
- name: Set LUKS configuration facts
|
||||
vars:
|
||||
configuration_luks_mapper_name_value: >-
|
||||
{{
|
||||
partitioning_luks_mapper_name
|
||||
| default(luks_mapper_name | default('SYSTEM_DECRYPTED'))
|
||||
}}
|
||||
configuration_luks_device_value: >-
|
||||
{{
|
||||
partitioning_luks_device
|
||||
| default(
|
||||
install_drive
|
||||
~ (partitioning_main_partition_suffix | default(2) | string)
|
||||
)
|
||||
}}
|
||||
configuration_luks_tpm2_pcrs_raw: >-
|
||||
{{ partitioning_luks_tpm2_pcrs | default(luks_tpm2_pcrs | default('')) }}
|
||||
configuration_luks_tpm2_pcrs_effective_value: >-
|
||||
{{
|
||||
(
|
||||
configuration_luks_tpm2_pcrs_raw
|
||||
if configuration_luks_tpm2_pcrs_raw is string
|
||||
else (configuration_luks_tpm2_pcrs_raw | map('string') | join('+'))
|
||||
)
|
||||
| string
|
||||
| replace(',', '+')
|
||||
| regex_replace('\\s+', '')
|
||||
| regex_replace('^\\+|\\+$', '')
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
configuration_luks_mapper_name: "{{ configuration_luks_mapper_name_value }}"
|
||||
configuration_luks_uuid: "{{ partitioning_luks_uuid | default('') }}"
|
||||
configuration_luks_device: "{{ configuration_luks_device_value }}"
|
||||
configuration_luks_options: >-
|
||||
{{ partitioning_luks_options | default(luks_options | default('discard,tries=3')) }}
|
||||
configuration_luks_auto_method: >-
|
||||
{{
|
||||
(partitioning_luks_auto_decrypt | default(luks_auto_decrypt | default(true)) | bool)
|
||||
| ternary(
|
||||
partitioning_luks_auto_decrypt_method | default(luks_auto_decrypt_method | default('tpm2')),
|
||||
'manual'
|
||||
)
|
||||
}}
|
||||
configuration_luks_tpm2_device: >-
|
||||
{{ partitioning_luks_tpm2_device | default(luks_tpm2_device | default('auto')) }}
|
||||
configuration_luks_tpm2_pcrs: "{{ configuration_luks_tpm2_pcrs_raw }}"
|
||||
configuration_luks_tpm2_pcrs_effective: "{{ configuration_luks_tpm2_pcrs_effective_value }}"
|
||||
configuration_luks_keyfile_path: >-
|
||||
/etc/cryptsetup-keys.d/{{ configuration_luks_mapper_name_value }}.key
|
||||
changed_when: false
|
||||
|
||||
- name: Validate LUKS UUID is available
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- configuration_luks_uuid | length > 0
|
||||
fail_msg: LUKS UUID not available. Ensure partitioning ran before configuration.
|
||||
|
||||
- name: Validate LUKS passphrase for auto-decrypt
|
||||
when: configuration_luks_auto_method in ['tpm2', 'keyfile']
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- configuration_luks_passphrase_effective | length > 0
|
||||
fail_msg: luks_passphrase (or partitioning_luks_passphrase) must be set for LUKS auto-decrypt.
|
||||
no_log: true
|
||||
|
||||
- name: Enroll TPM2 for LUKS
|
||||
when: configuration_luks_auto_method == 'tpm2'
|
||||
ansible.builtin.include_tasks: encryption/tpm2.yml
|
||||
|
||||
- name: Configure LUKS keyfile auto-decrypt
|
||||
when: configuration_luks_auto_method == 'keyfile'
|
||||
ansible.builtin.include_tasks: encryption/keyfile.yml
|
||||
|
||||
- name: Build LUKS parameters
|
||||
vars:
|
||||
configuration_luks_keyfile_in_use_value: "{{ configuration_luks_auto_method == 'keyfile' }}"
|
||||
configuration_luks_option_list_value: >-
|
||||
{{
|
||||
(configuration_luks_options | trim).split(',')
|
||||
if configuration_luks_options | trim | length > 0
|
||||
else []
|
||||
}}
|
||||
configuration_luks_tpm2_option_list_value: >-
|
||||
{{
|
||||
(configuration_luks_auto_method == 'tpm2')
|
||||
| ternary(
|
||||
['tpm2-device=' + configuration_luks_tpm2_device]
|
||||
+ (['tpm2-pcrs=' + configuration_luks_tpm2_pcrs_effective]
|
||||
if configuration_luks_tpm2_pcrs_effective | length > 0 else []),
|
||||
[]
|
||||
)
|
||||
}}
|
||||
configuration_luks_crypttab_keyfile_value: >-
|
||||
{{ configuration_luks_keyfile_path if configuration_luks_keyfile_in_use_value else 'none' }}
|
||||
configuration_luks_crypttab_options_value: >-
|
||||
{{
|
||||
(['luks'] + configuration_luks_option_list_value + configuration_luks_tpm2_option_list_value)
|
||||
| join(',')
|
||||
}}
|
||||
configuration_luks_rd_options_value: >-
|
||||
{{ (configuration_luks_option_list_value + configuration_luks_tpm2_option_list_value) | join(',') }}
|
||||
configuration_luks_kernel_args_value: >-
|
||||
{{
|
||||
(
|
||||
['rd.luks.name=' + configuration_luks_uuid + '=' + configuration_luks_mapper_name]
|
||||
+ (
|
||||
['rd.luks.options=' + configuration_luks_uuid + '=' + configuration_luks_rd_options_value]
|
||||
if configuration_luks_rd_options_value | length > 0 else []
|
||||
)
|
||||
+ (
|
||||
['rd.luks.key=' + configuration_luks_uuid + '=' + configuration_luks_keyfile_path]
|
||||
if configuration_luks_keyfile_in_use_value else []
|
||||
)
|
||||
) | join(' ')
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
configuration_luks_keyfile_in_use: "{{ configuration_luks_keyfile_in_use_value }}"
|
||||
configuration_luks_option_list: "{{ configuration_luks_option_list_value }}"
|
||||
configuration_luks_tpm2_option_list: "{{ configuration_luks_tpm2_option_list_value }}"
|
||||
configuration_luks_crypttab_keyfile: "{{ configuration_luks_crypttab_keyfile_value }}"
|
||||
configuration_luks_crypttab_options: "{{ configuration_luks_crypttab_options_value }}"
|
||||
configuration_luks_rd_options: "{{ configuration_luks_rd_options_value }}"
|
||||
configuration_luks_kernel_args: "{{ configuration_luks_kernel_args_value }}"
|
||||
|
||||
- name: Remove LUKS keyfile if TPM2 auto-decrypt is active
|
||||
when: configuration_luks_auto_method == 'tpm2'
|
||||
ansible.builtin.file:
|
||||
path: /mnt{{ configuration_luks_keyfile_path }}
|
||||
state: absent
|
||||
|
||||
- name: Write crypttab entry
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/crypttab
|
||||
regexp: "^{{ configuration_luks_mapper_name }}\\s"
|
||||
line: >-
|
||||
{{ configuration_luks_mapper_name }} UUID={{ configuration_luks_uuid }}
|
||||
{{ configuration_luks_crypttab_keyfile }} {{ configuration_luks_crypttab_options }}
|
||||
create: true
|
||||
mode: "0600"
|
||||
|
||||
- name: Ensure keyfile pattern for initramfs-tools
|
||||
when:
|
||||
- is_debian | default(false)
|
||||
- configuration_luks_keyfile_in_use
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/cryptsetup-initramfs/conf-hook
|
||||
regexp: '^KEYFILE_PATTERN='
|
||||
line: 'KEYFILE_PATTERN=/etc/cryptsetup-keys.d/*.key'
|
||||
create: true
|
||||
mode: "0644"
|
||||
|
||||
- name: Configure mkinitcpio hooks for LUKS
|
||||
when: os | lower == 'archlinux'
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/mkinitcpio.conf
|
||||
regexp: '^HOOKS='
|
||||
line: >-
|
||||
HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole
|
||||
block sd-encrypt lvm2 filesystems fsck)
|
||||
|
||||
- name: Read mkinitcpio configuration
|
||||
when: os | lower == 'archlinux'
|
||||
ansible.builtin.slurp:
|
||||
src: /mnt/etc/mkinitcpio.conf
|
||||
register: configuration_mkinitcpio_slurp
|
||||
|
||||
- name: Build mkinitcpio FILES list
|
||||
when: os | lower == 'archlinux'
|
||||
vars:
|
||||
configuration_mkinitcpio_files_list_value: >-
|
||||
{{
|
||||
(
|
||||
configuration_mkinitcpio_slurp.content | b64decode
|
||||
| regex_findall('^FILES=\\(([^)]*)\\)', multiline=True)
|
||||
| default([])
|
||||
| first
|
||||
| default('')
|
||||
).split()
|
||||
}}
|
||||
configuration_mkinitcpio_files_list_new_value: >-
|
||||
{{
|
||||
(
|
||||
(configuration_mkinitcpio_files_list_value + [configuration_luks_keyfile_path])
|
||||
if configuration_luks_keyfile_in_use
|
||||
else (
|
||||
configuration_mkinitcpio_files_list_value
|
||||
| reject('equalto', configuration_luks_keyfile_path)
|
||||
| list
|
||||
)
|
||||
)
|
||||
| unique
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
configuration_mkinitcpio_files_list_new: "{{ configuration_mkinitcpio_files_list_new_value }}"
|
||||
|
||||
- name: Configure mkinitcpio FILES list
|
||||
when: os | lower == 'archlinux'
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/mkinitcpio.conf
|
||||
regexp: '^FILES='
|
||||
line: >-
|
||||
FILES=({{
|
||||
configuration_mkinitcpio_files_list_new | join(' ')
|
||||
}})
|
||||
|
||||
- name: Ensure dracut config directory exists
|
||||
when: is_rhel | default(false)
|
||||
ansible.builtin.file:
|
||||
path: /mnt/etc/dracut.conf.d
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Configure dracut for LUKS
|
||||
when: is_rhel | default(false)
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/dracut.conf.d/crypt.conf
|
||||
content: |
|
||||
add_dracutmodules+=" crypt "
|
||||
{% if configuration_luks_keyfile_in_use %}
|
||||
install_items+=" {{ configuration_luks_keyfile_path }} "
|
||||
{% endif %}
|
||||
mode: "0644"
|
||||
|
||||
- name: Read kernel cmdline defaults
|
||||
when: is_rhel | default(false)
|
||||
ansible.builtin.slurp:
|
||||
src: /mnt/etc/kernel/cmdline
|
||||
register: configuration_kernel_cmdline_slurp
|
||||
|
||||
- name: Build kernel cmdline with LUKS args
|
||||
when: is_rhel | default(false)
|
||||
vars:
|
||||
configuration_kernel_cmdline_current_value: >-
|
||||
{{ configuration_kernel_cmdline_slurp.content | b64decode | trim }}
|
||||
configuration_kernel_cmdline_list_value: >-
|
||||
{{
|
||||
configuration_kernel_cmdline_current_value.split()
|
||||
if configuration_kernel_cmdline_current_value | length > 0 else []
|
||||
}}
|
||||
configuration_kernel_cmdline_filtered_value: >-
|
||||
{{
|
||||
configuration_kernel_cmdline_list_value
|
||||
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
||||
| list
|
||||
}}
|
||||
configuration_kernel_cmdline_new_value: >-
|
||||
{{
|
||||
(configuration_kernel_cmdline_filtered_value + configuration_luks_kernel_args.split())
|
||||
| unique
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
configuration_kernel_cmdline_new: "{{ configuration_kernel_cmdline_new_value }}"
|
||||
changed_when: false
|
||||
|
||||
- name: Write kernel cmdline with LUKS args
|
||||
when: is_rhel | default(false)
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/kernel/cmdline
|
||||
mode: "0644"
|
||||
content: "{{ configuration_kernel_cmdline_new }}\n"
|
||||
|
||||
- name: Find BLS entries
|
||||
when: is_rhel | default(false)
|
||||
ansible.builtin.find:
|
||||
paths: /mnt/boot/loader/entries
|
||||
patterns: "*.conf"
|
||||
register: configuration_kernel_bls_entries
|
||||
changed_when: false
|
||||
|
||||
- name: Update BLS options with LUKS args
|
||||
when:
|
||||
- is_rhel | default(false)
|
||||
- configuration_kernel_bls_entries.files | length > 0
|
||||
ansible.builtin.lineinfile:
|
||||
path: "{{ item.path }}"
|
||||
regexp: '^options '
|
||||
line: "options {{ configuration_kernel_cmdline_new }}"
|
||||
loop: "{{ configuration_kernel_bls_entries.files }}"
|
||||
loop_control:
|
||||
label: "{{ item.path }}"
|
||||
|
||||
- name: Read grub defaults
|
||||
when: not is_rhel | default(false)
|
||||
ansible.builtin.slurp:
|
||||
src: /mnt/etc/default/grub
|
||||
register: configuration_grub_slurp
|
||||
|
||||
- name: Build grub command lines with LUKS args
|
||||
when: not is_rhel | default(false)
|
||||
vars:
|
||||
configuration_grub_content_value: "{{ configuration_grub_slurp.content | b64decode }}"
|
||||
configuration_grub_cmdline_linux_value: >-
|
||||
{{
|
||||
configuration_grub_content_value
|
||||
| regex_findall('^GRUB_CMDLINE_LINUX=\"(.*)\"', multiline=True)
|
||||
| default([])
|
||||
| first
|
||||
| default('')
|
||||
}}
|
||||
configuration_grub_cmdline_default_value: >-
|
||||
{{
|
||||
configuration_grub_content_value
|
||||
| regex_findall('^GRUB_CMDLINE_LINUX_DEFAULT=\"(.*)\"', multiline=True)
|
||||
| default([])
|
||||
| first
|
||||
| default('')
|
||||
}}
|
||||
configuration_grub_cmdline_linux_list_value: >-
|
||||
{{
|
||||
configuration_grub_cmdline_linux_value.split()
|
||||
if configuration_grub_cmdline_linux_value | length > 0 else []
|
||||
}}
|
||||
configuration_grub_cmdline_default_list_value: >-
|
||||
{{
|
||||
configuration_grub_cmdline_default_value.split()
|
||||
if configuration_grub_cmdline_default_value | length > 0 else []
|
||||
}}
|
||||
configuration_luks_kernel_args_list_value: "{{ configuration_luks_kernel_args.split() }}"
|
||||
configuration_grub_cmdline_linux_new_value: >-
|
||||
{{
|
||||
(
|
||||
(
|
||||
configuration_grub_cmdline_linux_list_value
|
||||
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
||||
| list
|
||||
)
|
||||
+ configuration_luks_kernel_args_list_value
|
||||
)
|
||||
| unique
|
||||
| join(' ')
|
||||
}}
|
||||
configuration_grub_cmdline_default_new_value: >-
|
||||
{{
|
||||
(
|
||||
(
|
||||
configuration_grub_cmdline_default_list_value
|
||||
| reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=')
|
||||
| list
|
||||
)
|
||||
+ configuration_luks_kernel_args_list_value
|
||||
)
|
||||
| unique
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
configuration_grub_content: "{{ configuration_grub_content_value }}"
|
||||
configuration_grub_cmdline_linux: "{{ configuration_grub_cmdline_linux_value }}"
|
||||
configuration_grub_cmdline_default: "{{ configuration_grub_cmdline_default_value }}"
|
||||
configuration_grub_cmdline_linux_new: "{{ configuration_grub_cmdline_linux_new_value }}"
|
||||
configuration_grub_cmdline_default_new: "{{ configuration_grub_cmdline_default_new_value }}"
|
||||
|
||||
- name: Update GRUB_CMDLINE_LINUX_DEFAULT for LUKS
|
||||
when: not is_rhel | default(false)
|
||||
ansible.builtin.lineinfile:
|
||||
path: /mnt/etc/default/grub
|
||||
regexp: '^GRUB_CMDLINE_LINUX_DEFAULT='
|
||||
line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ configuration_grub_cmdline_default_new }}"'
|
||||
110
roles/configuration/tasks/encryption/keyfile.yml
Normal file
110
roles/configuration/tasks/encryption/keyfile.yml
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
- name: Configure LUKS keyfile auto-decrypt
|
||||
block:
|
||||
- name: Ensure cryptsetup key directory exists
|
||||
ansible.builtin.file:
|
||||
path: /mnt/etc/cryptsetup-keys.d
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0700"
|
||||
|
||||
- name: Ensure LUKS keyfile exists
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt{{ configuration_luks_keyfile_path }}
|
||||
content: >-
|
||||
{{
|
||||
lookup(
|
||||
'community.general.random_string',
|
||||
length=(partitioning_luks_keyfile_size | default(luks_keyfile_size | default(64)) | int),
|
||||
override_all='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||||
)
|
||||
}}
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
force: false
|
||||
register: configuration_luks_keyfile_copy
|
||||
no_log: true
|
||||
|
||||
- name: Ensure keyfile permissions
|
||||
ansible.builtin.file:
|
||||
path: /mnt{{ configuration_luks_keyfile_path }}
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
|
||||
- name: Check whether keyfile already unlocks the LUKS device
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- cryptsetup
|
||||
- luksOpen
|
||||
- --test-passphrase
|
||||
- --key-file
|
||||
- "/mnt{{ configuration_luks_keyfile_path }}"
|
||||
- "{{ configuration_luks_device }}"
|
||||
register: configuration_luks_keyfile_unlock_test
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Add keyfile to LUKS header
|
||||
when: configuration_luks_keyfile_unlock_test.rc != 0
|
||||
community.crypto.luks_device:
|
||||
device: "{{ configuration_luks_device }}"
|
||||
passphrase: "{{ configuration_luks_passphrase_effective }}"
|
||||
new_keyfile: "/mnt{{ configuration_luks_keyfile_path }}"
|
||||
register: configuration_luks_addkey_result
|
||||
failed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Regenerate keyfile and retry adding to LUKS header
|
||||
when:
|
||||
- configuration_luks_keyfile_unlock_test.rc != 0
|
||||
- configuration_luks_keyfile_copy.changed | default(false) | bool
|
||||
- configuration_luks_addkey_result is failed
|
||||
block:
|
||||
- name: Regenerate LUKS keyfile
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt{{ configuration_luks_keyfile_path }}
|
||||
content: >-
|
||||
{{
|
||||
lookup(
|
||||
'community.general.random_string',
|
||||
length=(partitioning_luks_keyfile_size | default(luks_keyfile_size | default(64)) | int),
|
||||
override_all='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||||
)
|
||||
}}
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
force: true
|
||||
no_log: true
|
||||
|
||||
- name: Retry adding keyfile to LUKS header
|
||||
community.crypto.luks_device:
|
||||
device: "{{ configuration_luks_device }}"
|
||||
passphrase: "{{ configuration_luks_passphrase_effective }}"
|
||||
new_keyfile: "/mnt{{ configuration_luks_keyfile_path }}"
|
||||
register: configuration_luks_addkey_retry
|
||||
failed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Re-check whether keyfile unlocks the LUKS device
|
||||
ansible.builtin.command:
|
||||
argv:
|
||||
- cryptsetup
|
||||
- luksOpen
|
||||
- --test-passphrase
|
||||
- --key-file
|
||||
- "/mnt{{ configuration_luks_keyfile_path }}"
|
||||
- "{{ configuration_luks_device }}"
|
||||
register: configuration_luks_keyfile_unlock_test_after
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
no_log: true
|
||||
|
||||
- name: Fallback to manual LUKS unlock if keyfile enrollment failed
|
||||
when: (configuration_luks_keyfile_unlock_test_after.rc | default(1)) != 0
|
||||
ansible.builtin.set_fact:
|
||||
configuration_luks_auto_method: manual
|
||||
90
roles/configuration/tasks/encryption/tpm2.yml
Normal file
90
roles/configuration/tasks/encryption/tpm2.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
- name: Enroll TPM2 for LUKS
|
||||
block:
|
||||
- name: Create temporary passphrase file for TPM2 enrollment
|
||||
ansible.builtin.tempfile:
|
||||
path: /mnt/tmp
|
||||
prefix: luks-passphrase-
|
||||
state: file
|
||||
register: configuration_luks_tpm2_passphrase_tempfile
|
||||
|
||||
- name: Write passphrase into temporary file for TPM2 enrollment
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ configuration_luks_tpm2_passphrase_tempfile.path }}"
|
||||
content: "{{ configuration_luks_passphrase_effective }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
no_log: true
|
||||
|
||||
- name: Enroll TPM2 token
|
||||
vars:
|
||||
configuration_luks_enroll_args: >-
|
||||
{{
|
||||
[
|
||||
'/usr/bin/systemd-cryptenroll',
|
||||
'--tpm2-device=' + configuration_luks_tpm2_device,
|
||||
'--tpm2-with-pin=false',
|
||||
'--wipe-slot=tpm2',
|
||||
'--unlock-key-file=' + (
|
||||
configuration_luks_tpm2_passphrase_tempfile.path
|
||||
| regex_replace('^/mnt', '')
|
||||
)
|
||||
]
|
||||
+ (['--tpm2-pcrs=' + configuration_luks_tpm2_pcrs_effective]
|
||||
if configuration_luks_tpm2_pcrs_effective | length > 0 else [])
|
||||
+ [configuration_luks_device]
|
||||
}}
|
||||
configuration_luks_enroll_chroot_args: "{{ ['arch-chroot', '/mnt'] + configuration_luks_enroll_args }}"
|
||||
ansible.builtin.command:
|
||||
argv: "{{ configuration_luks_enroll_chroot_args }}"
|
||||
register: configuration_luks_tpm2_enroll_chroot
|
||||
changed_when: configuration_luks_tpm2_enroll_chroot.rc == 0
|
||||
failed_when: false
|
||||
|
||||
- name: Retry TPM2 enrollment in installer environment
|
||||
when:
|
||||
- (configuration_luks_tpm2_enroll_chroot.rc | default(1)) != 0
|
||||
vars:
|
||||
configuration_luks_enroll_args: >-
|
||||
{{
|
||||
[
|
||||
'/usr/bin/systemd-cryptenroll',
|
||||
'--tpm2-device=' + configuration_luks_tpm2_device,
|
||||
'--tpm2-with-pin=false',
|
||||
'--wipe-slot=tpm2',
|
||||
'--unlock-key-file=' + configuration_luks_tpm2_passphrase_tempfile.path
|
||||
]
|
||||
+ (['--tpm2-pcrs=' + configuration_luks_tpm2_pcrs_effective]
|
||||
if configuration_luks_tpm2_pcrs_effective | length > 0 else [])
|
||||
+ [configuration_luks_device]
|
||||
}}
|
||||
ansible.builtin.command:
|
||||
argv: "{{ configuration_luks_enroll_args }}"
|
||||
register: configuration_luks_tpm2_enroll_host
|
||||
changed_when: configuration_luks_tpm2_enroll_host.rc == 0
|
||||
failed_when: false
|
||||
|
||||
- name: Validate TPM2 enrollment succeeded
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
(configuration_luks_tpm2_enroll_chroot.rc | default(1)) == 0
|
||||
or (configuration_luks_tpm2_enroll_host.rc | default(1)) == 0
|
||||
fail_msg: >-
|
||||
TPM2 enrollment failed.
|
||||
chroot rc={{ configuration_luks_tpm2_enroll_chroot.rc | default('n/a') }},
|
||||
host rc={{ configuration_luks_tpm2_enroll_host.rc | default('n/a') }},
|
||||
chroot stderr={{ configuration_luks_tpm2_enroll_chroot.stderr | default('') }},
|
||||
host stderr={{ configuration_luks_tpm2_enroll_host.stderr | default('') }}
|
||||
rescue:
|
||||
- name: Fallback to keyfile auto-decrypt
|
||||
ansible.builtin.set_fact:
|
||||
configuration_luks_auto_method: keyfile
|
||||
always:
|
||||
- name: Remove TPM2 enrollment passphrase file
|
||||
when: configuration_luks_tpm2_passphrase_tempfile.path is defined
|
||||
ansible.builtin.file:
|
||||
path: "{{ configuration_luks_tpm2_passphrase_tempfile.path }}"
|
||||
state: absent
|
||||
changed_when: false
|
||||
109
roles/configuration/tasks/grub.yml
Normal file
109
roles/configuration/tasks/grub.yml
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
- name: Configure grub
|
||||
when: not is_rhel | default(false)
|
||||
block:
|
||||
- name: Add commandline information to grub config
|
||||
ansible.builtin.lineinfile:
|
||||
dest: /mnt/etc/default/grub
|
||||
regexp: ^GRUB_CMDLINE_LINUX_DEFAULT=
|
||||
line: GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3"
|
||||
|
||||
- name: Change Grub time
|
||||
ansible.builtin.lineinfile:
|
||||
dest: /mnt/etc/default/grub
|
||||
regexp: ^GRUB_TIMEOUT=
|
||||
line: GRUB_TIMEOUT=1
|
||||
|
||||
- name: Ensure grub defaults file exists for RHEL-based systems
|
||||
when: is_rhel | default(false)
|
||||
block:
|
||||
- name: Build RHEL kernel command line defaults
|
||||
vars:
|
||||
configuration_grub_root_uuid_value: >-
|
||||
{{
|
||||
(
|
||||
partitioning_main_uuid.stdout
|
||||
if (filesystem | lower) == 'btrfs'
|
||||
else (partitioning_uuid_root | default([]) | first | default(''))
|
||||
)
|
||||
| default('')
|
||||
| trim
|
||||
}}
|
||||
configuration_grub_lvm_args_value: >-
|
||||
{{
|
||||
['resume=/dev/mapper/sys-swap', 'rd.lvm.lv=sys/root', 'rd.lvm.lv=sys/swap']
|
||||
if (filesystem | lower) != 'btrfs'
|
||||
else []
|
||||
}}
|
||||
configuration_grub_root_flags_value: >-
|
||||
{{ ['rootflags=subvol=@'] if (filesystem | lower) == 'btrfs' else [] }}
|
||||
configuration_grub_cmdline_linux_base_value: >-
|
||||
{{
|
||||
(['crashkernel=auto'] + configuration_grub_lvm_args_value)
|
||||
| join(' ')
|
||||
}}
|
||||
configuration_grub_kernel_cmdline_base_value: >-
|
||||
{{
|
||||
(
|
||||
(['root=UUID=' + configuration_grub_root_uuid_value]
|
||||
if configuration_grub_root_uuid_value | length > 0 else [])
|
||||
+ ['ro', 'crashkernel=auto']
|
||||
+ configuration_grub_lvm_args_value
|
||||
+ configuration_grub_root_flags_value
|
||||
)
|
||||
| join(' ')
|
||||
}}
|
||||
ansible.builtin.set_fact:
|
||||
configuration_grub_cmdline_linux_base: "{{ configuration_grub_cmdline_linux_base_value }}"
|
||||
configuration_kernel_cmdline_base: "{{ configuration_grub_kernel_cmdline_base_value }}"
|
||||
changed_when: false
|
||||
|
||||
- name: Check if grub defaults file exists
|
||||
ansible.builtin.stat:
|
||||
path: /mnt/etc/default/grub
|
||||
register: configuration_grub_defaults_stat
|
||||
changed_when: false
|
||||
|
||||
- name: Create default grub configuration
|
||||
when: not configuration_grub_defaults_stat.stat.exists
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/default/grub
|
||||
mode: "0644"
|
||||
content: |
|
||||
GRUB_TIMEOUT=5
|
||||
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
|
||||
GRUB_DEFAULT=saved
|
||||
GRUB_DISABLE_SUBMENU=true
|
||||
GRUB_TERMINAL_OUTPUT="console"
|
||||
GRUB_CMDLINE_LINUX="{{ configuration_grub_cmdline_linux_base }}"
|
||||
GRUB_DISABLE_RECOVERY="true"
|
||||
GRUB_ENABLE_BLSCFG=true
|
||||
|
||||
- name: Ensure kernel cmdline directory exists
|
||||
ansible.builtin.file:
|
||||
path: /mnt/etc/kernel
|
||||
state: directory
|
||||
mode: "0755"
|
||||
|
||||
- name: Write kernel cmdline defaults
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/kernel/cmdline
|
||||
mode: "0644"
|
||||
content: "{{ configuration_kernel_cmdline_base }}\n"
|
||||
|
||||
- name: Find BLS entries
|
||||
ansible.builtin.find:
|
||||
paths: /mnt/boot/loader/entries
|
||||
patterns: "*.conf"
|
||||
register: configuration_grub_bls_entries
|
||||
changed_when: false
|
||||
|
||||
- name: Update BLS options with kernel cmdline defaults
|
||||
when: configuration_grub_bls_entries.files | length > 0
|
||||
ansible.builtin.lineinfile:
|
||||
path: "{{ item.path }}"
|
||||
regexp: '^options '
|
||||
line: "options {{ configuration_kernel_cmdline_base }}"
|
||||
loop: "{{ configuration_grub_bls_entries.files }}"
|
||||
loop_control:
|
||||
label: "{{ item.path }}"
|
||||
Reference in New Issue
Block a user