Distribuciones

Re-enroll TPM2: lo que cambia en Arch con mkinitcpio 42-1 y el hook systemd

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 30 minutos para instalación, 1-2 horas para upgrade in-place.
  • Requisitos: Backup de /home, conexión a internet, 20+ GB libres.
  • Resultado: Sistema actualizado con soporte extendido, drivers funcionando.
  • Troubleshooting: dnf distro-sync, akmods para NVIDIA, journalctl -p err.

Por qué este cambio importa hoy

El 22 de septiembre de 2026, Arch Linux publicó el paquete mkinitcpio 42-1 con un cambio silencioso pero de alto impacto: el hook systemd ahora arrastra el unit systemd-pcrosseparator.service, una pieza que mide la cadena os-separator en los PCR 0-7, 9 y 12-14 del TPM2 justo cuando el dispositivo TPM queda disponible para userspace. Hasta aquí suena a detalle interno, pero la consecuencia práctica es inmediata: cualquier servidor o workstation Arch que tenga LUKS desbloqueado automáticamente vía TPM2 va a dejar de arrancar el rootfs en el próximo reinicio si no re-enrolla las claves.

El aviso oficial de David Runge en archlinux.org/news lo dice sin rodeos: “you need to re-enroll the TPM2 in use”. No hay autodetección, no hay fallback transparente, no hay script mágico. El admin tiene que correr systemd-cryptenroll o cambiar a systemd-pcrlock con política calculada. Si no lo hace, el próximo boot se queda en el shell de initrd pidiéndole la passphrase de LUKS como si fuera 2015.

Y ojo: este cambio no es exclusivo de Arch. Como systemd-pcrosseparator.service viene de systemd v261, va a tocar Fedora, openSUSE, Debian unstable y cualquier distro que alinee el initramfs con esa versión. Arch simplemente llegó primero a la versión 42-1 porque mueve el paquete mkinitcpio de forma independiente al resto del stack.

Qué cambió exactamente en el initramfs

El commit relevante está en el CHANGELOG de mkinitcpio. Antes de 42-1, el hook systemd sólo incluía el árbol de units mínimo para que systemd en initrd pudiera montar root, pedir passphrase y continuar. Desde 42-1 también incluye systemd-pcrosseparator.service, que es un service-type oneshot declarado por systemd ≥ 261 y que se ejecuta cuando el device TPM se hace visible en userspace.

El propósito oficial, según la especificación UAPI Group “Linux TPM PCR Registry”, es introducir una barrera explícita: el string medido os-separator permite que las políticas TPM distingan entre “se llegó a userspace” y “todavía estamos en firmware/bootloader”, evitando que una política bindada sólo a PCR 7 (Secure Boot state) confunda un initrd con un userland. Es la misma idea que ya se aplica con systemd-pcrphase.service (que mide phase strings en PCR 11), pero extendida al resto de PCRs relevantes.

El problema es que los PCRs que toca (0-7, 9 y 12-14) son exactamente los que la mayoría de las instalaciones con systemd-cryptenroll --tpm2-pcrs=... eligieron como política de unlock automático. Cuando actualizas a mkinitcpio 42-1 y regeneras el initramfs sin re-enrollar, el hash que el TPM2 calcula en el próximo boot ya no coincide con el que cryptenroll selló: el auto-unlock falla.

Por qué los PCRs 0-7, 9 y 12-14 son los importantes

PCR Mide Razón para incluirlo en política
0 BIOS / firmware code Detecta cambios de firmware/UEFI
1 BIOS configuration Detecta cambios en config de placa
2 Option ROMs Cambios en devices de expansión
3 Option ROM config Config de Option ROMs
4 MBR / bootloader Detecta cambios en MBR/bootloader
5 Bootloader config Config del bootloader
6 Host platform state Eventos de platform/ACPI en power transitions
7 Secure Boot state El PCR “estrella” para Secure Boot
9 Kernel command line / initrd Cambios en cmdline + initrd
12-14 Boot loader / kernel / module events Eventos del kernel y módulos

Antes de mkinitcpio 42-1, una política que usaba PCR 7 + PCR 9 (la receta más popular) seguía funcionando aunque os-separator se midiera en esos mismos registros, porque la cadena de medición no cambiaba para tu initrd específico: el nuevo service corría, sí, pero el valor final del PCR era el mismo hasta que algo más (kernel, initrd, bootloader) cambiara.

Ahora la medición del os-separator entra dentro del hash final. Como ese PCR se “mide” en distintos momentos del arranque (incluyendo post-userspace), el policy que systemd-cryptenroll calculó sobre el sistema viejo no es estable: la policy pasa a depender de un valor que cambia con cada release de systemd o de mkinitcpio. Es por diseño — pero la consecuencia operacional es que cualquier upgrade del lado del initramfs requiere re-enrollar.

Cómo diagnosticar si tu sistema está afectado

Antes de regenerar initramfs a lo loco, confirmá si realmente usas TPM2 para unlock. En el servidor donde estés trabajando:

# 1. ¿Hay TPM2 disponible?
ls /dev/tpm* 2>/dev/null
# Esperado: /dev/tpm0 y /dev/tpmrm0
# 2. ¿Qué slot tiene la LUKS2 con TPM2?
sudo cryptsetup luksDump /dev/sdX2 | grep -A2 "tpm2"
# Si aparece un tpm2 token, tu rootfs depende de TPM2
# 3. ¿Qué PCRs están enrolled?
sudo systemd-cryptenroll /dev/sdX2
# Busca la línea "PCRs: ..." — esa es tu policy actual
# 4. ¿Qué versión de mkinitcpio tienes?
pacman -Q mkinitcpio
# Si dice 42-1 o superior, este artículo aplica

Si el paso 2 no devuelve nada y el paso 3 muestra sólo “keyring” / “password”, puedes actualizar mkinitcpio sin preocuparte. Si hay un tpm2 token, seguí leyendo.

Para un vistazo rápido del estado de medición actual en runtime, systemd-analyze tiene lo que necesitas:

# Log de mediciones TPM2 del último boot
sudo journalctl -b -u systemd-pcrosseparator.service
sudo cat /run/log/systemd/tpm2-measure.log 2>/dev/null | head -50
# Estado PCR actual (requiere tpm2-tools)
sudo tpm2_pcrread sha256:0,1,2,3,4,5,6,7,9,12,13,14

Si systemd-pcrosseparator.service aparece en el journal y los PCRs listados tienen valor distinto de cero (o distinto del baseline de tu policy), estás exactamente en el escenario que activa el aviso de Arch.

Re-enroll con systemd-cryptenroll (ruta rápida, pinned values)

Si lo que quieres es re-apuntar la policy a los nuevos valores de PCR, systemd-cryptenroll es la opción más directa. El cambio de policy es local: tocás sólo el slot TPM2 de LUKS, no perdés la passphrase, no tocás otras particiones.

# Re-enroll usando los PCRs "seguros" que recomienda la guía de Fedora
sudo systemd-cryptenroll /dev/sdX2 
    --wipe-slot=tpm2 
    --tpm2-device=auto 
    --tpm2-pcrs=7+11
# Si tu setup usa Secure Boot + initrd + cmdline:
sudo systemd-cryptenroll /dev/sdX2 
    --wipe-slot=tpm2 
    --tpm2-device=auto 
    --tpm2-pcrs=7+11+12+14
# Para máxima cobertura estilo "cambia el initrd y no rompe":
sudo systemd-cryptenroll /dev/sdX2 
    --wipe-slot=tpm2 
    --tpm2-device=auto 
    --tpm2-pcrs=0+1+4+5+7+9+11+12+14

La elección de PCRs es un trade-off. 7+11 (Secure Boot + boot phase) es lo que recomienda Lennart Poettering en su post “A brave new trusted boot world” y es el set más estable: cambia menos con cada upgrade. 0+1+4+5+7+9+11+12+14 es la suite “todo” que muchos tutoriales de Fedora recomiendan pero es notoriamente inestable en hardware con cambios sutiles de firmware (incluso conectar un monitor distinto puede mover PCR 1 según reportan en los comentarios de Fedora Magazine).

Después del re-enroll, regenerá el initramfs y reiniciá. Si el boot levanta con auto-unlock, perfecto. Si te pide passphrase, no es drama: tipeala, login, y revisa el journal de cryptsetup para entender qué PCR no coincide.

sudo mkinitcpio -P
sudo reboot
# Si falla el auto-unlock:
sudo journalctl -b -u [email protected]

Re-enroll con systemd-pcrlock (ruta robusta, custom policies)

Si te cansaste de que cada upgrade rompa el auto-unlock, systemd-pcrlock es la respuesta a largo plazo. En vez de pinear a una lista de PCRs, genera una policy firmada que se “predice” contra las mediciones futuras del initramfs. Cuando actualizás systemd o mkinitcpio, corres systemd-pcrlock forecast para regenerar la policy con el nuevo expected state, sin perder auto-unlock.

# 1. Generar la policy inicial (calcula qué PCRs va a medir el sistema actual)
sudo systemd-pcrlock make-policy 
    --public-key=auto 
    --policy-dir=/etc/secureboot/pcrlock 
    /var/lib/systemd/pcrlock.json
# 2. Enrollar la policy en LUKS
sudo systemd-cryptenroll /dev/sdX2 
    --wipe-slot=tpm2 
    --tpm2-device=auto 
    --tpm2-public-key-policyref=initrd
# 3. Cuando actualizás systemd/mkinitcpio/kernel:
sudo systemd-pcrlock forecast
sudo systemd-pcrlock make-policy /var/lib/systemd/pcrlock.json
# 4. Desactivar el auto-generator si quieres control manual
sudo systemctl disable --now systemd-pcrlock-make-policy.service

El paso 4 es importante y es exactamente lo que Arch recomienda en su news: si dejás systemd-pcrlock-make-policy.service activo, cada boot intentará re-generar la policy automáticamente. Útil en workstations, problemático en servers donde quieres control explícito.

El trade-off es operacional: pcrlock requiere disciplina. Si actualizás systemd, regenerás initrd y NO corres make-policy, el auto-unlock falla igual que con la receta de PCRs pinned. La diferencia es que la recovery es un comando en vez de una lista de PCRs a calcular a mano.

Casos donde NO hacer nada es la respuesta correcta

Hay tres perfiles de sistema que pueden ignorar mkinitcpio 42-1 sin consecuencias:

  1. Sin TPM2 físico. VMs en la nube, servidores dedicados sin chip TPM, containers. Si ls /dev/tpm* devuelve vacío, este artículo no aplica a tu setup.
  2. LUKS con passphrase, sin TPM2 token. El paso de unlock automático nunca se activó. La passphrase se sigue pidiendo como siempre.
  3. TPM2 con FIDO2 / Yubikey como factor secundario. Si tu setup usa systemd-cryptenroll --fido2-device=... en vez de --tpm2-device=..., los FIDO tokens no dependen de PCRs y siguen funcionando.

Para el resto, el aviso aplica y re-enroll es obligatorio antes del próximo reinicio. Es la primera vez en años que un upgrade de mkinitcpio rompe auto-unlock de LUKS sin que el admin haya tocado nada — vale la pena recordar el ciclo.

Troubleshooting cuando el auto-unlock sigue fallando

Si ya re-enrollaste y el auto-unlock sigue sin funcionar, los sospechosos habituales son:

# 1. ¿El initrd que se está cargando es el nuevo?
sudo lsinitcpio /boot/initramfs-*.img | grep -i pcrphase
# Debe listar pcrphase + pcrosseparator. Si no, regeneraste mal.
# 2. ¿El TPM está realmente midiendo pcrosseparator?
sudo tpm2_eventlog /sys/kernel/security/tpm0/binary_bios_measurements 
    | grep -i separator
# Esperado: al menos una medición "os-separator"
# 3. ¿El policy de pcrlock está firmado correctamente?
sudo systemd-pcrlock list
sudo systemd-pcrlock verify
# 4. ¿El slot TPM2 en LUKS está actualizado?
sudo cryptsetup luksDump /dev/sdX2 | grep -A6 "tpm2"

Si el paso 2 muestra os-separator medido en los PCRs que usaste para re-enroll y aun así no funciona, es probable que estés pineando a PCRs que el TPM no midió en el boot actual (típico cuando se enchufa un monitor USB que cambia PCR 1). Volvé a systemd-cryptenroll con la lista exacta que tpm2_pcrread reporta en el boot que falla.

Si tu hardware es muy quisquilloso con PCRs (laptops, especialmente), considera mudarte a systemd-pcrlock con la policy calculada dinámicamente. Es más estable a largo plazo.

Vale la pena actualizar igual?

Sí. mkinitcpio 42-1 no es opcional en Arch — es el paquete estable. Si tienes un server con auto-unlock, el costo es un cryptenroll de 30 segundos y un reinicio controlado. Si tienes una workstation con auto-unlock, es la misma operación. Si no usas TPM2, no te enteraste.

La parte interesante es el patrón: cada vez que systemd introduce un nuevo service que mide en PCRs, el universo de setups “auto-unlock con TPM2” se corre un casillero. Es el precio de la seguridad medida, y la herramienta para mantenerse arriba es systemd-pcrlock. Mientras tanto,Arch hizo bien en avisar con tiempo: el 22 de septiembre publicaron el aviso y el paquete, dando margen para planificar.

Si te toca hacerlo en producción, el script es este:

#!/bin/bash
# re-enroll LUKS root con pcrlock-friendly PCRs
set -e
DEVICE="${1:-/dev/sda2}"
echo "==> Re-enrolling $DEVICE con PCRs 7+11+12+14"
sudo systemd-cryptenroll "$DEVICE" 
    --wipe-slot=tpm2 
    --tpm2-device=auto 
    --tpm2-pcrs=7+11+12+14
echo "==> Regenerando initramfs"
sudo mkinitcpio -P
echo "==> Listo. Reiniciar en próximo cambio de ventana."

Resumen

mkinitcpio 42-1 introduce systemd-pcrosseparator.service en el initramfs. Esto mide os-separator en los PCR 0-7, 9 y 12-14, rompiendo cualquier policy TPM2 que tuvieras enrolled. Re-enroll es obligatorio: systemd-cryptenroll --tpm2-pcrs=... para setups simples, systemd-pcrlock para setups serios. Arch publicó el aviso el 22 de septiembre, con tiempo para planificar el reboot. Si no usas TPM2 para auto-unlock, este artículo no aplica.

Preguntas frecuentes

¿Por qué Re-enroll TPM2: lo que cambia en Arch con mkinitcpio 42-1 y el hook systemd es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con Re-enroll TPM2: lo que cambia?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con Re-enroll TPM2: lo que cambia?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar Re-enroll TPM2: lo que cambia y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a Re-enroll TPM2: lo que cambia?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *