¿Cómo descifrar un dispositivo cifrado con LUKS por usuario al iniciar sesión?

¿Cómo descifrar un dispositivo cifrado con LUKS por usuario al iniciar sesión?

He creado el siguiente [email protected]servicio para systemd:

[Unit]
Description=Cryptography Setup for '%I'
After=cryptsetup-pre.target
After=dev-mapper-%i.device
Before=cryptsetup.target
Before=umount.target
BindsTo=dev-mapper-%i.device
BindsTo=dev-mapper-%i.luks.device
Conflicts=umount.target
DefaultDependencies=no
IgnoreOnIsolate=true
RequiresMountsFor=/home

[Service]
ExecStart=/usr/lib/systemd/systemd-cryptsetup attach '%I.luks' '/dev/mapper/%I' '%h/%I/secret.key' 'luks,header=%h/%I/header'
ExecStop=/usr/lib/systemd/systemd-cryptsetup detach '%I.luks'
KillMode=none
RemainAfterExit=yes
TimeoutSec=0
Type=oneshot

[Install]
WantedBy=default.target

La idea es descifrar ciertos xxxdispositivos cifrados con LUKS xxx.lukssolo para un usuario determinado, que habilita el servicio con, por ejemplo:

systemctl --user enable luks@xxx

Desafortunadamente, incluso probarlo con

systemctl --user start luks@xxx

falla porque siempre regresa con el código de salida 1sin indicar el motivo real. Para mí estaba claro que el problema probablemente esté en los permisos. Es decir, estoy seguro de que para activar manualmente cryptsetup luksOpen ..., hay que elevar el shell, por ejemplo, con sudo. De hecho, si emito

sudo systemctl start luks@xxx

funciona a las mil maravillas y de manera similar

sudo systemctl enable luks@xxx

Funcionaría para la fase de arranque.

NOTA:
Para dicha instalación en todo el sistema, por supuesto es necesario modificar el servicio reemplazándolo %hcon el directorio de inicio real de un usuario dador, lo cual es feo y de todos modos no sirve para el propósito final.

Ahora, soy consciente de pam_mountcuál es capaz de realizar un montaje similar (que no puedo usar porque no admite encabezados LUKS separados y porque en realidad monta dispositivos, algo que no quiero) por usuario y, de hecho. , pam_systemdse inicia systemctl --user, por lo que definitivamente debería haber una manera de obtener privilegios durante el arranque por usuario para realizar el descifrado del dispositivo.

Por cierto, los síntomas de fallo de

systemctl --user enable luks@xxx

son incluso peores que los de probarlo con

systemctl --user start luks@xxx

(que solo devuelve el código de salida 1). Es decir, ni siquiera puedo iniciar sesión con el usuario dado porque se queja

Failed to create bus connection: No such file or directory

porque XDG_RUNTIME_DIRy DBUS_SESSION_BUS_ADDRESSya no están configurados, mientras que deberían haberlo sido por el systemd-logind.serviceservicio. Claramente, luks@xxxde alguna manera interrumpe todo el proceso de inicialización, pero debido a la falta de información en el diario, no puedo identificar exactamente por qué. Por lo tanto, mi sospecha actual sobre la falta de permisos aún persiste.

Esperamos propuestas informadas. Gracias.

Respuesta1

Una solución alternativa sería editar el sudoersarchivo para agregar permisos para que el usuario en cuestión lo ejecute /usr/lib/systemd/systemd-cryptsetupcon permisos de root con la opción NOPASSWD habilitada.

Luego editaría su archivo de servicio (específico del usuario) anterior para que diga:

ExecStart=/usr/bin/sudo /usr/lib/systemd/systemd-cryptsetup attach '%I.luks' '/dev/mapper/%I' '%h/%I/secret.key' 'luks,header=%h/%I/header'
ExecStop=/usr/bin/sudo /usr/lib/systemd/systemd-cryptsetup detach '%I.luks'

No estoy seguro de si también tendrías que habilitar!requisitopara que esto funcione

Actualizar:

Para aumentar la seguridad en torno a esto, especialmente para un sistema de múltiples usuarios, recomiendo encarecidamente crear un par de scripts para realizar los pasos de 'adjuntar' y 'desconectar' en nombre del usuario en lugar de darle acceso a sudo /usr/lib/systemd/systemd-cryptsetupdirectamente, ya que de lo contrario cualquier usuario al que se le dé acceso para ejecutar este comando puede interferir potencialmente con otros volúmenes cifrados.

Respuesta2

Sugeriría crear y habilitar un Type=oneshot RemainAfterExit=yesservicio para el usuario que cree un archivo con su ExecStartdirectiva y lo elimine con su ExecStopdirectiva, por ejemplo.

ExecStart="/usr/bin/touch %h/.decrypt"
ExecStop="/usr/bin/rm %h/.decrypt"

Luego puede crear y habilitar un [email protected]archivo de unidad para el usuario del sistema con una ruta absoluta:

PathExists="/home/user/.decrypt"

Esto verificaría la ruta creada por el servicio de usuario anterior, activando la [email protected]unidad cuando se crea y desactivándola cuando se elimina, estableciendo así una dependencia indirecta del servicio del sistema en el servicio de usuario.

Tenga en cuenta que para que esto funcione de forma segura, por supuesto, sólo el usuario debe poder escribir en el directorio en el que se crea el archivo.

información relacionada