web-dev-qa-db-ja.com

ログイン時にユーザーごとにLUKS暗号化デバイスを復号化する方法は?

systemd用に次の[email protected]サービスを作成しました。

[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_systemdsystemctl --userを起動するため、デバイスの復号化を実行するために、ユーザーごとに起動中に特権を取得する方法が確実に必要です。

ちなみに、の故障症状

systemctl --user enable luks@xxx

それをテストするよりもさらに悪いです

systemctl --user start luks@xxx

(これは終了コード1のみを返します)。つまり、特定のユーザーが不満を言っているので、ログインすることすらできません。

Failed to create bus connection: No such file or directory

XDG_RUNTIME_DIRDBUS_SESSION_BUS_ADDRESSはもう設定されていませんが、systemd-logind.serviceサービスによって設定されているはずです。明らかに、luks@xxxはどういうわけか初期化プロセス全体を壊しますが、ジャーナルの情報が不十分なため、正確な理由を特定できません。したがって、許可の欠如についての私の現在の疑惑はまだ残っています。

教育を受けた提案を楽しみにしています。ありがとうございました。

6

別の解決策は、sudoersファイルを編集して、問題のユーザーがNOPASSWDオプションを有効にしてroot権限で/usr/lib/systemd/systemd-cryptsetupを実行するための権限を追加することです。

次に、上記の(ユーザー固有の)サービスファイルを編集して、次のようにします。

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'

これを機能させるには、 !requiretty も有効にする必要があるかどうかはわかりません

更新:

これに関するセキュリティを強化するために、特にマルチユーザーシステムの場合、Sudoに/usr/lib/systemd/systemd-cryptsetupへの直接アクセスを許可するのではなく、ユーザーに代わって「アタッチ」および「デタッチ」ステップを実行するスクリプトをいくつか作成することを強くお勧めします。そうしないと、このコマンドを実行するためのアクセス権が付与されたユーザーが、他の暗号化されたボリュームに干渉する可能性があります。

2
Benjamin

ExecStartディレクティブを使用してファイルを作成し、ExecStopディレクティブを使用してファイルを削除するユーザーに対して、Type=oneshotRemainAfterExit=yesサービスを作成して有効にすることをお勧めします。

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

次に、絶対パスを使用して、システムユーザーの[email protected]ユニットファイルを作成して有効にすることができます。

PathExists="/home/user/.decrypt"

これにより、上記のユーザーサービスによって作成されたパスがチェックされ、作成時に[email protected]ユニットがアクティブになり、削除されると非アクティブになり、システムサービスのユーザーサービスへの間接的な依存関係が確立されます。

もちろん、これが安全に動作するためには、ファイルが作成されるディレクトリはユーザーだけが書き込み可能である必要があることに注意してください。

2
Benjamin