ansible: add collect-luks-keys playbook for LUKS backup key archival

New playbook collect-luks-keys.yml connects to all enrolled FreeIPA
clients, checks for /_LUKS_BACKUP_KEY (placed there by the installer
when encryption is enabled), and fetches each key to the Ansible
controller as luks-keys/<HOSTNAME>_LUKS_BACKUP_KEY (mode 0400).

Hosts without the file are reported but not treated as errors.
The luks-keys/ store directory is created with mode 0700.

Usage:
  ansible-playbook -i inventory collect-luks-keys.yml

Can be scheduled via cron on the controller for automatic collection.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
The_miro 2026-05-18 15:25:05 +02:00
parent b5a3b46c79
commit f1ea6dcb54
1 changed files with 69 additions and 0 deletions

View File

@ -0,0 +1,69 @@
---
# collect-luks-keys.yml — fetch LUKS backup keys from enrolled clients.
#
# When a client was installed with disk encryption via the M-Archy installer,
# a backup LUKS key is stored at /_LUKS_BACKUP_KEY inside the encrypted root.
# This playbook fetches those keys to the controller and names each copy
# <HOSTNAME>_LUKS_BACKUP_KEY so they can be archived securely.
#
# Keys are stored in luks-keys/ relative to the playbook directory.
# Protect that directory carefully — keys can unlock client root partitions.
#
# Usage:
# ansible-playbook -i inventory collect-luks-keys.yml
# ansible-playbook -i inventory collect-luks-keys.yml -e luks_keys_store=/secure/path
#
# To run automatically, add a cron job on the Ansible controller:
# 0 3 * * * cd /path/to/playbooks && ansible-playbook -i inventory collect-luks-keys.yml
- name: Collect LUKS backup keys from enrolled clients
hosts: all
become: yes
vars:
luks_key_path: /_LUKS_BACKUP_KEY
luks_keys_store: "{{ playbook_dir }}/luks-keys"
tasks:
- name: Ensure local key store directory exists
file:
path: "{{ luks_keys_store }}"
state: directory
mode: '0700'
delegate_to: localhost
run_once: true
become: false
- name: Check for LUKS backup key on client
stat:
path: "{{ luks_key_path }}"
register: luks_key_stat
- name: Fetch LUKS backup key to controller
fetch:
src: "{{ luks_key_path }}"
dest: "{{ luks_keys_store }}/{{ inventory_hostname }}_LUKS_BACKUP_KEY"
flat: yes
when: luks_key_stat.stat.exists
register: luks_key_fetch
- name: Secure fetched key permissions
file:
path: "{{ luks_keys_store }}/{{ inventory_hostname }}_LUKS_BACKUP_KEY"
mode: '0400'
delegate_to: localhost
become: false
when:
- luks_key_stat.stat.exists
- luks_key_fetch is changed
- name: Report key status
debug:
msg: >-
{{ inventory_hostname }}:
{% if luks_key_stat.stat.exists %}
key found and fetched to {{ luks_keys_store }}/{{ inventory_hostname }}_LUKS_BACKUP_KEY
{% else %}
no /_LUKS_BACKUP_KEY present (unencrypted or already collected)
{% endif %}