fix: encryption, partitioning, cis and virtualization hardening
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
# User-facing API: override via top-level `cis` dict in inventory.
|
||||
# Merged with these defaults in _normalize.yml → cis_cfg.
|
||||
# Merged with these defaults in _normalize.yml -> cis_cfg.
|
||||
cis_defaults:
|
||||
modules_blacklist:
|
||||
- freevxfs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
- name: Disable Kernel Modules
|
||||
vars:
|
||||
# Ubuntu uses squashfs for snap packages — blacklisting it breaks snap entirely
|
||||
# Ubuntu uses squashfs for snap packages - blacklisting it breaks snap entirely
|
||||
cis_modules_squashfs: "{{ [] if os in ['ubuntu', 'ubuntu-lts'] else ['squashfs'] }}"
|
||||
cis_modules_all: "{{ cis_cfg.modules_blacklist + cis_modules_squashfs }}"
|
||||
ansible.builtin.copy:
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
---
|
||||
# Network configuration dispatch — maps OS name to the task file
|
||||
# Network configuration dispatch - maps OS name to the task file
|
||||
# that writes network config. Default (NetworkManager) applies to
|
||||
# all OSes not explicitly listed.
|
||||
configuration_network_task_map:
|
||||
alpine: network_alpine.yml
|
||||
void: network_void.yml
|
||||
configuration_network_task_map: {}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
RedHat: >-
|
||||
{{ chroot_command }} dnf install -y
|
||||
clevis clevis-luks clevis-systemd tpm2-tools
|
||||
Suse: >-
|
||||
{{ chroot_command }} zypper install -y
|
||||
clevis clevis-systemd tpm2.0-tools
|
||||
Archlinux: >-
|
||||
{{ chroot_command }} pacman -S --noconfirm --needed
|
||||
clevis tpm2-tools
|
||||
ansible.builtin.command: "{{ _clevis_install_cmd[os_family] }}"
|
||||
register: _clevis_install_result
|
||||
changed_when: _clevis_install_result.rc == 0
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Sets _initramfs_generator and _tpm2_method facts.
|
||||
#
|
||||
# Generator detection: derived from the platform's initramfs_cmd
|
||||
# (dracut → dracut, mkinitcpio → mkinitcpio, else → initramfs-tools)
|
||||
# (dracut -> dracut, mkinitcpio -> mkinitcpio, else -> initramfs-tools)
|
||||
# TPM2 method: systemd-cryptenroll when generator supports tpm2-device,
|
||||
# clevis fallback otherwise. Non-native dracut installed automatically.
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
when: (configuration_luks_keyfile_unlock_test_after.rc | default(1)) != 0
|
||||
ansible.builtin.debug:
|
||||
msg: >-
|
||||
LUKS keyfile enrollment failed — falling back to manual unlock at boot.
|
||||
LUKS keyfile enrollment failed - falling back to manual unlock at boot.
|
||||
The system will prompt for the LUKS passphrase during startup.
|
||||
|
||||
- name: Fallback to manual LUKS unlock if keyfile enrollment failed
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
# TPM2 enrollment via systemd-cryptenroll.
|
||||
# Works with dracut and mkinitcpio (sd-encrypt). The user-set passphrase
|
||||
# remains as a backup unlock method — no auto-generated keyfiles.
|
||||
# remains as a backup unlock method - no auto-generated keyfiles.
|
||||
- name: Enroll TPM2 for LUKS
|
||||
block:
|
||||
- name: Create temporary passphrase file for TPM2 enrollment
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
- name: Create zram config
|
||||
when:
|
||||
- (os != "debian" or (os_version | string) != "11") and os != "rhel"
|
||||
- os not in ["alpine", "void"]
|
||||
- system_cfg.features.swap.enabled | bool
|
||||
ansible.builtin.copy:
|
||||
dest: /mnt/etc/systemd/zram-generator.conf
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
validate: /usr/sbin/visudo --check --file=%s
|
||||
|
||||
- name: Deploy per-user sudoers rules
|
||||
when: item.value.sudo is defined and (item.value.sudo | string | length > 0)
|
||||
# Jinja truthiness: bool true / a rule string => deploy; false / '' / unset => skip.
|
||||
when: item.value.sudo | default(false)
|
||||
vars:
|
||||
configuration_sudoers_rule: >-
|
||||
{{ item.value.sudo if item.value.sudo is string else 'ALL=(ALL) NOPASSWD: ALL' }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
partitioning_btrfs_compress_opt: "{{ 'compress=zstd:15' if system_cfg.features.zstd.enabled | bool else '' }}"
|
||||
# Partition separator: 'p' for NVMe/mmcblk (device path ends in digit), empty for SCSI/virtio.
|
||||
# Examples: /dev/sda → /dev/sda1, /dev/nvme0n1 → /dev/nvme0n1p1
|
||||
# Examples: /dev/sda -> /dev/sda1, /dev/nvme0n1 -> /dev/nvme0n1p1
|
||||
partitioning_part_sep: "{{ 'p' if (install_drive | default('') | regex_search('\\d$')) else '' }}"
|
||||
partitioning_boot_partition_suffix: 1
|
||||
partitioning_main_partition_suffix: 2
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
# Sizes are computed from disk_size_gb, memory_mb, and feature flags.
|
||||
#
|
||||
# Swap sizing:
|
||||
# - RAM >= 16 GB → swap = RAM/2 (in GB)
|
||||
# - RAM < 16 GB → swap = max(RAM_GB, 2)
|
||||
# - RAM >= 16 GB -> swap = RAM/2 (in GB)
|
||||
# - RAM < 16 GB -> swap = max(RAM_GB, 2)
|
||||
# - Capped to: min(target, 4 + max(disk - overhead, 0))
|
||||
# - Further capped to: max available after subtracting reserved + CIS + extent reserve + 4 GB buffer
|
||||
#
|
||||
# Root sizing:
|
||||
# - Full-disk mode (default): disk - reserved - swap - extent_reserve - (CIS volumes if enabled)
|
||||
# - Partial mode: tiered — <4 GB available → 4 GB, 4-12 GB → all available, >12 GB → 40% of disk
|
||||
# - Partial mode: tiered - <4 GB available -> 4 GB, 4-12 GB -> all available, >12 GB -> 40% of disk
|
||||
#
|
||||
# CIS volumes (only when CIS enabled):
|
||||
# - /home: max(min(home_raw, home_max), home_min) where home_raw = (disk - overhead) * 10%
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
# Cloud-init support matrix:
|
||||
# libvirt — cloud-init ISO attached as CDROM (user-data + network-config)
|
||||
# proxmox — cloud-init via Proxmox API (cicustom, ciuser, cipassword, etc.)
|
||||
# vmware — no cloud-init; configuration is applied post-install via chroot
|
||||
# xen — no cloud-init; configuration is applied post-install via chroot
|
||||
# libvirt - cloud-init ISO attached as CDROM (user-data + network-config)
|
||||
# proxmox - cloud-init via Proxmox API (cicustom, ciuser, cipassword, etc.)
|
||||
# vmware - no cloud-init; configuration is applied post-install via chroot
|
||||
# xen - no cloud-init; configuration is applied post-install via chroot
|
||||
virtualization_libvirt_image_dir: >-
|
||||
{{
|
||||
system_cfg.path
|
||||
@@ -17,8 +17,18 @@ virtualization_libvirt_cloudinit_path: >-
|
||||
virtualization_xen_disk_path: /var/lib/xen/images
|
||||
|
||||
virtualization_libvirt_machine_type: q35
|
||||
virtualization_libvirt_ovmf_code: /usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd
|
||||
virtualization_libvirt_ovmf_vars: /usr/share/edk2/x64/OVMF_VARS.4m.fd
|
||||
# Secboot OVMF firmware candidates, ordered Arch, Debian/Ubuntu, Fedora/RHEL.
|
||||
# libvirt.yml resolves these to the first file present on the controller.
|
||||
virtualization_libvirt_ovmf_code_candidates:
|
||||
- /usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd
|
||||
- /usr/share/OVMF/OVMF_CODE_4M.secboot.fd
|
||||
- /usr/share/edk2/ovmf/OVMF_CODE.secboot.fd
|
||||
- /usr/share/OVMF/OVMF_CODE.secboot.fd
|
||||
virtualization_libvirt_ovmf_vars_candidates:
|
||||
- /usr/share/edk2/x64/OVMF_VARS.4m.fd
|
||||
- /usr/share/OVMF/OVMF_VARS_4M.fd
|
||||
- /usr/share/edk2/ovmf/OVMF_VARS.fd
|
||||
- /usr/share/OVMF/OVMF_VARS.fd
|
||||
|
||||
virtualization_tpm2_enabled: >-
|
||||
{{
|
||||
|
||||
@@ -70,6 +70,19 @@
|
||||
- /tmp/cloud-user-data-{{ hostname }}.yml
|
||||
- /tmp/cloud-network-config-{{ hostname }}.yml
|
||||
|
||||
# Resolve OVMF firmware to the first candidate present on the controller
|
||||
# unless the user pinned an explicit path. first_found needs the localhost
|
||||
# delegation since the candidates live on the libvirt host, not the target.
|
||||
- name: Resolve OVMF firmware paths
|
||||
delegate_to: localhost
|
||||
ansible.builtin.set_fact:
|
||||
virtualization_libvirt_ovmf_code: >-
|
||||
{{ virtualization_libvirt_ovmf_code if virtualization_libvirt_ovmf_code | default('', true) | length > 0
|
||||
else lookup('ansible.builtin.first_found', virtualization_libvirt_ovmf_code_candidates) }}
|
||||
virtualization_libvirt_ovmf_vars: >-
|
||||
{{ virtualization_libvirt_ovmf_vars if virtualization_libvirt_ovmf_vars | default('', true) | length > 0
|
||||
else lookup('ansible.builtin.first_found', virtualization_libvirt_ovmf_vars_candidates) }}
|
||||
|
||||
# uri defaults to qemu:///system (local libvirtd)
|
||||
- name: Create VM using libvirt
|
||||
delegate_to: localhost
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
esxi_hostname: "{{ hypervisor_cfg.node if (hypervisor_cfg.node | default('') | length > 0) else omit }}"
|
||||
folder: "{{ system_cfg.path if system_cfg.path | string | length > 0 else omit }}"
|
||||
name: "{{ hostname }}"
|
||||
# Generic guest ID — VMware auto-detects OS post-install
|
||||
# Generic guest ID - VMware auto-detects OS post-install
|
||||
guest_id: otherLinux64Guest
|
||||
annotation: |
|
||||
{{ note if note is defined else '' }}
|
||||
|
||||
Reference in New Issue
Block a user