如何在登入時按使用者解密 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_DIRDBUS_SESSION_BUS_ADDRESS不再設置,而它們應該由服務設置systemd-logind.service。顯然,luks@xxx不知何故破壞了整個初始化過程,但由於日誌中的資訊不足,我無法確切地確定原因。因此,我目前對缺乏權限的懷疑仍然存在。

期待有教育意義的建議。謝謝。

答案1

另一個解決方案是編輯該sudoers檔案以新增相關使用者的權限,以便在/usr/lib/systemd/systemd-cryptsetup啟用 NOPASSWD 選項的情況下以 root 權限執行。

然後,您可以編輯上面的(特定於用戶的)服務文件以讀取:

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'

我不確定您是否還必須啟用!要求為了這個工作

更新:

為了提高安全性,特別是對於多用戶系統,我強烈建議創建幾個腳本來代表用戶執行「附加」和「分離」步驟,而不是/usr/lib/systemd/systemd-cryptsetup直接授予 sudo 存取權限,否則任何有權運行此命令的用戶都可能幹擾其他加密磁碟區。

答案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]建立該單元時啟動該單元,並在刪除該單元時停用它,從而建立系統服務對使用者服務的間接依賴關係。

請注意,為了安全運行,建立檔案的目錄當然只能由使用者寫入。

相關內容