Как расшифровать зашифрованное с помощью LUKS устройство для каждого пользователя при входе в систему?

Как расшифровать зашифрованное с помощью LUKS устройство для каждого пользователя при входе в систему?

Я создал следующую [email protected]услугу для 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

Идея состоит в том, чтобы расшифровать определенное зашифрованное LUKS xxxустройство xxx.luksтолько для определенного пользователя, который включает услугу, например, с помощью:

systemctl --user enable luks@xxx

К сожалению, даже тестирование с

systemctl --user start luks@xxx

не удается, так как он всегда возвращается с кодом выхода 1без указания фактической причины. Мне было ясно, что проблема, скорее всего, в разрешениях. То есть я точно знаю, что для того, чтобы вручную запустить cryptsetup luksOpen ..., нужно повысить уровень оболочки, например, с помощью sudo. Действительно, если я выдаю

sudo systemctl start luks@xxx

это работает как заклинание и аналогично

sudo systemctl enable luks@xxx

подойдет для фазы загрузки.

ПРИМЕЧАНИЕ:
Для такой общесистемной установки, конечно, необходимо изменить службу, заменив ее %hфактическим домашним каталогом пользователя-получателя, что некрасиво и в любом случае не соответствует конечной цели.

Теперь я знаю, pam_mountчто , способный выполнять аналогичное монтирование (которое я не могу использовать, поскольку он не поддерживает отсоединенные заголовки LUKS и фактически монтирует устройства, чего я не хочу) для каждого пользователя и, по сути, pam_systemdзапускает systemctl --user, так что определенно должен быть способ получить привилегии во время загрузки для каждого пользователя, чтобы выполнить расшифровку устройства.

Кстати, симптомы отказа

systemctl --user enable luks@xxx

даже хуже, чем те, которые испытывают его с

systemctl --user start luks@xxx

(который возвращает только код выхода 1). То есть я даже не могу войти под данным пользователем, так как он жалуется на

Failed to create bus connection: No such file or directory

потому что XDG_RUNTIME_DIRи DBUS_SESSION_BUS_ADDRESSбольше не установлены, хотя они должны были быть установлены службой systemd-logind.service. Очевидно, luks@xxxчто каким-то образом нарушается весь процесс инициализации, но из-за недостаточной информации в журнале я не могу точно определить, почему. Таким образом, мои текущие подозрения об отсутствии разрешений все еще остаются.

Жду обоснованных предложений. Спасибо.

решение1

Альтернативным решением было бы редактирование sudoersфайла с целью добавления разрешений для пользователя, о котором идет речь, на запуск /usr/lib/systemd/systemd-cryptsetupс правами root и включенной опцией NOPASSWD.

Затем вам следует отредактировать ваш (пользовательский) файл службы, указанный выше, следующим образом:

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'

Я не уверен, нужно ли вам также включить!требованиечтобы это работало

Обновлять:

Чтобы повысить безопасность, особенно в многопользовательской системе, я настоятельно рекомендую создать несколько скриптов для выполнения шагов «присоединения» и «отсоединения» от имени пользователя, а не предоставлять доступ sudo /usr/lib/systemd/systemd-cryptsetupнапрямую, так как в противном случае любой пользователь, которому предоставлен доступ для выполнения этой команды, может потенциально помешать работе других зашифрованных томов.

решение2

Я бы предложил создать и включить Type=oneshot RemainAfterExit=yesслужбу для пользователя, которая создает файл с помощью своей ExecStartдирективы и удаляет его с помощью своей ExecStopдирективы, например

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

Затем вы можете создать и включить [email protected]файл модуля для пользователя системы с абсолютным путем:

PathExists="/home/user/.decrypt"

Это позволит проверить путь, созданный пользовательской службой выше, активируя [email protected]блок при его создании и деактивируя его при удалении, тем самым устанавливая косвенную зависимость системной службы от пользовательской службы.

Обратите внимание, что для обеспечения безопасности каталог, в котором создается файл, должен быть доступен для записи только пользователю.

Связанный контент