--- # Initramfs configuration for LUKS auto-unlock. # Runs AFTER Build LUKS parameters (so configuration_luks_keyfile_in_use is set). # _initramfs_generator and _tpm2_method are set by initramfs_detect.yml. # --- clevis: install and bind TPM2 --- - name: Install clevis in target system when: - configuration_luks_auto_method == 'tpm2' - _tpm2_method | default('') == 'clevis' ansible.builtin.command: >- {{ chroot_command }} apt install -y clevis clevis-luks clevis-tpm2 clevis-initramfs tpm2-tools register: _clevis_install_result changed_when: _clevis_install_result.rc == 0 - name: Install clevis on installer for LUKS binding when: - configuration_luks_auto_method == 'tpm2' - _tpm2_method | default('') == 'clevis' community.general.pacman: name: - clevis - tpm2-tools state: present retries: 3 delay: 5 - name: Create clevis passphrase file when: - configuration_luks_auto_method == 'tpm2' - _tpm2_method | default('') == 'clevis' ansible.builtin.copy: dest: /mnt/root/.luks-enroll-key content: "{{ configuration_luks_passphrase }}" mode: "0600" no_log: true - name: Ensure TPM device accessible for clevis when: - configuration_luks_auto_method == 'tpm2' - _tpm2_method | default('') == 'clevis' ansible.builtin.shell: >- ls /mnt/dev/tpmrm0 2>/dev/null || (ls /dev/tpmrm0 && cp -a /dev/tpmrm0 /mnt/dev/tpmrm0) changed_when: false failed_when: false - name: Bind LUKS to TPM2 via clevis when: - configuration_luks_auto_method == 'tpm2' - _tpm2_method | default('') == 'clevis' vars: _clevis_config: >- {{ '{"pcr_ids":"' + configuration_luks_tpm2_pcrs + '"}' if configuration_luks_tpm2_pcrs | length > 0 else '{}' }} ansible.builtin.command: >- clevis luks bind -f -k /mnt/root/.luks-enroll-key -d {{ configuration_luks_device }} tpm2 '{{ _clevis_config }}' register: _clevis_bind_result changed_when: _clevis_bind_result.rc == 0 failed_when: false # Initramfs regeneration is handled by the bootloader task which runs after # encryption configuration. Clevis hooks are included automatically by # update-initramfs when clevis-initramfs is installed. - name: Remove clevis passphrase file when: - configuration_luks_auto_method == 'tpm2' - _tpm2_method | default('') == 'clevis' ansible.builtin.file: path: /mnt/root/.luks-enroll-key state: absent - name: Report clevis binding result when: - configuration_luks_auto_method == 'tpm2' - _tpm2_method | default('') == 'clevis' ansible.builtin.debug: msg: >- {{ 'Clevis TPM2 binding succeeded' if (_clevis_bind_result.rc | default(1)) == 0 else 'Clevis TPM2 binding failed: ' + (_clevis_bind_result.stderr | default('unknown')) + '. System will require passphrase at boot.' }} # --- initramfs-tools: keyfile support (non-TPM2) --- - name: Configure initramfs-tools keyfile pattern when: - _initramfs_generator | default('') == 'initramfs-tools' - configuration_luks_keyfile_in_use | default(false) | bool 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" # --- mkinitcpio: systemd + sd-encrypt hooks --- - name: Configure mkinitcpio hooks for LUKS when: _initramfs_generator | default('') == 'mkinitcpio' 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' if system_cfg.filesystem != 'btrfs' else '' }} filesystems fsck) - name: Read mkinitcpio configuration when: _initramfs_generator | default('') == 'mkinitcpio' ansible.builtin.slurp: src: /mnt/etc/mkinitcpio.conf register: configuration_mkinitcpio_slurp - name: Build mkinitcpio FILES list when: _initramfs_generator | default('') == 'mkinitcpio' vars: mkinitcpio_files_list: >- {{ ( configuration_mkinitcpio_slurp.content | b64decode | regex_findall('^FILES=\\(([^)]*)\\)', multiline=True) | default([]) | first | default('') ).split() }} mkinitcpio_files_list_new: >- {{ ( (mkinitcpio_files_list + [configuration_luks_keyfile_path]) if (configuration_luks_keyfile_in_use | default(false)) else ( mkinitcpio_files_list | reject('equalto', configuration_luks_keyfile_path) | list ) ) | unique }} ansible.builtin.set_fact: configuration_mkinitcpio_files_list_new: "{{ mkinitcpio_files_list_new }}" - name: Configure mkinitcpio FILES list when: _initramfs_generator | default('') == 'mkinitcpio' ansible.builtin.lineinfile: path: /mnt/etc/mkinitcpio.conf regexp: "^FILES=" line: >- FILES=({{ configuration_mkinitcpio_files_list_new | join(' ') }})