dm-crypt/系统配置
- 若需要在啟動早期階段遠程解密分區(例如,解密沒有顯示輸出的設備或遠程伺服器),參考Dm-crypt/特殊應用#遠程解鎖分區。
- 使用支持直接將命令輸出插入到所編輯的文本中的文本編輯器,可以便於在修改配置文件時輸入UUID、PARTUUID等內容。例如,對於nano,可使用
Ctrl+t;對於vim或Neovim,可使用:read;對於mcedit,可使用Alt+u。接下來,可使用lsblk、blkid命令及恰當的參數,輸出並插入所需內容。或者,也可以使用終端多路復用器的複製、粘貼功能。
若要從加密的根文件系統啟動,initramfs需要包含能在早期用戶空間(即initramfs階段)解密卷的工具。一般使用內核參數指定要解密的卷。
下列小節介紹了如何配置mkinitcpio以生成所需的initramfs,以及所需的內核參數。
依據具體的配置,需要啟用如下mkinitcpio鉤子中的部分:
| busybox | systemd | Use case |
|---|---|---|
encrypt
|
sd-encrypt
|
若根分區是加密的,或者需要在根分區掛載之前掛載其它加密分區,則需要此鉤子。在其它情況下,初始化腳本(例如,/etc/crypttab )將解鎖非根分區,故無需此鉤子。注意,此鉤子必須放置在udev / systemd鉤子之後。
|
keyboard
|
需要,用於使得在早期用戶空間可以使用鍵盤。
提示:對於外設連接經常改變(即,後續啟動時連接的外設可能和生成initramfs鏡像時不一致)的系統(例如,使用外置鍵盤的筆記本、headless系統),建議將本鉤子放置在
autodetect之前,以便始終包含所有鍵盤驅動。否則,若在生成鏡像時未連接外置鍵盤,但在啟動時連接,則外置鍵盤可能由於缺少驅動而無法正常工作。 |
|
keymap
|
sd-vconsole
|
在輸入密碼時,提供非標準鍵盤布局支持。必須放置在encrypt鉤子之前。在 /etc/vconsole.conf 中設置鍵盤布局,詳見控制台鍵盤配置持久化。
|
consolefont
|
在早期用戶空間加載非默認字體。在 /etc/vconsole.conf 中設置字體,詳見控制台鍵盤配置持久化。
|
|
其它可能需要的鉤子參考相應配置方案的指南。
/etc/mkinitcpio.conf後,應當重新生成 initramfs。對於基於busybox的initramfs,使用encrypt鉤子時,典型的配置如下:
/etc/mkinitcpio.conf
... HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck) ...
對於基於systemd的initramfs,使用sd-encrypt鉤子時,典型的配置如下:
/etc/mkinitcpio.conf
... HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck) ...
encrypt鉤子和sd-encrypt鉤子需要設定的內核參數不同。但root、resume參數的設定方式相同。
root=參數指定了解密後的、實際的根文件系統:
root=device
- 若直接在加密設備上創建根文件系統,則為
/dev/mapper/dmname。 - 若在LVM上層使用加密的邏輯卷,則設置同上。
- 若在加密設備上使用LVM,則為
root=/dev/<卷組名稱>/<邏輯卷名稱>。
- 若使用
sd-encrypt鉤子以及GPT分區自動掛載,則無需指定root=參數。詳見在單一分區上配置LUKS。 - 若使用GRUB,並通過grub-mkconfig生成
grub.cfg配置文件,則無需手動設置root=參數。grub-mkconfig將自動檢測解密後的根文件系統的UUID,並將其添加到grub.cfg中。
resume=device
-
device應當為用於休眠的設備文件或加密後的swap文件系統。對於單獨的swap分區,該參數的值形如/dev/mapper/swap。詳見Dm-crypt/交換分區加密。
encrypt不支持如下功能:
- 解密多個加密設備 (archlinux/mkinitcpio/mkinitcpio#231)。在initramfs中只能解密一個設備。
- 使用分離的LUKS頭 (archlinux/mkinitcpio/mkinitcpio#234)。
- 設置某些crypttab支持的加密選項。
指定在冷啟動時包含加密的根分區的設備(加密容器)。encrypt鉤子通過該參數判斷哪個設備包含了加密的系統。
cryptdevice=device:dmname:options
-
device:包含加密容器的設備。強烈建議使用塊設備持久化命名指定。 -
dmname:解密後產生的設備映射器名稱(device-mapper name),設備解密後,可通過/dev/mapper/dmname訪問解密後的數據。 -
options:(可選),按逗號分隔的選項(例如,啟用TRIM支持)。若無需額外指定選項,省略該參數(即,使用cryptdevice=device:dmname)。 - 若加密的根分區在LVM上,則應當首先激活LVM,並設置
device為/dev/<卷組名稱>/<邏輯卷名稱>。
cryptkey=參數。在啟動時,將提示輸入密碼。該參數指定了encrypt鉤子用於解鎖cryptdevice的密鑰文件。若密鑰放置在默認位置(詳見下),無需手動指定此參數。
取決於密鑰文件的存儲位置,該參數有三種指定方式。
若密鑰文件存儲在某設備上的文件系統中,作為該文件系統中的一個文件:
cryptkey=device:fstype:path
-
device:存儲密鑰文件的設備。強烈建議使用塊設備持久化命名指定。 -
fstype:存儲密鑰文件的設備的文件系統。或者,指定auto表示自動探測文件系統類型。 -
path:在該文件系統中,密鑰文件的絕對路徑。
例如:cryptkey=LABEL=usbstick:vfat:/secretkey
若密鑰文件直接對應某一設備上的一段比特流:
cryptkey=device:offset:size
offset表示比特流起始位置相對於設備首部的偏移量,size表示比特流長度。offset、size的單位都是字節。
例如:cryptkey=UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ:0:512從指定設備開頭處讀取512位元組,作為密鑰文件內容。
:」,需要使用反斜槓「\」轉義。例如,對於ID為usb-123456-0:0的USB設備,可設置cryptkey=/dev/disk/by-id/usb-123456-0\:0:0:512。若密鑰文件已包含在initramfs中[1]:
cryptkey=rootfs:path
例如:cryptkey=rootfs:/secretkey。
注意,若沒有指定cryptkey,將默認嘗試從initramfs中讀取/crypto_keyfile.bin。[2]
該參數專門用於傳遞dm-crypt plain模式的加密選項。
參數格式如下:
crypto=hash:cipher:keysize:offset:skip
參數內容直接與cryptsetup選項有關。參見Dm-crypt/設備加密#plain模式的加密選項。
即使設備採用plain模式的默認選項加密,也必須指定crypto參數。但該參數的每個部分都可以留空:
crypto=::::
該參數的具體例子如下:
crypto=sha512:twofish-xts-plain64:512:0:
systemd-cryptsetup-generator是用於解鎖加密設備的systemd單元生成器。其將讀取部分內核參數、/etc/crypttab以進行生成。關於其的詳細敘述和支持的選項,參見systemd-cryptsetup-generator(8)。
若使用sd-encryptmkinitcpio鉤子、systemd dracut模塊,則systemd-cryptsetup-generator將在initramfs階段運行。
下面將介紹部分systemd-cryptsetup-generator讀取的內核參數。
- 若系統中存在
/etc/crypttab.initramfs文件,則其將被複製到initramfs中的/etc/crypttab,以便指定需要在initramfs階段解密的設備。該文件的語法詳見#crypttab。若不存在/etc/crypttab.initramfs文件,則initramfs中將不包含/etc/crypttab。此時必須通過下面介紹的內核參數指定要解密的設備。 - 與
rd.luks參數不同,/etc/crypttab.initramfs不局限於使用UUID指定設備。可以使用任何塊設備持久化命名方法。 - 若所有前提條件滿足,則可以使用GPT分區自動掛載,在
/etc/crypttab.initramfs中可使用/dev/gpt-auto-root-luks代指加密的根分區,而無需手動指定UUID、PARTUUID等設備標識符。詳見#systemd-gpt-auto-generator。 - 在解密過程中,輸入的密碼將被systemd-cryptsetup(8)緩存到內核鑰匙環中,故若多個設備使用相同的密碼,只需要輸入一次密碼。鑰匙環中緩存的密碼還可用於在後期用戶空間中解鎖crypttab中指定的其它設備。
- 所有
rd.luks相關參數都可多次指定,以解密多個設備。 -
rd.luks相關參數僅支持解密LUKS設備。若要解密dm-crypt plain模式加密的設備,必須在/etc/crypttab.initramfs中指定。語法詳見#crypttab。 - 在修改
/etc/crypttab.initramfs後,需要重新生成 initramfs。
/etc/crypttab//etc/crypttab.initramfs配置文件和luks.*/rd.luks.*內核參數,則只有在內核參數中指定了的設備會被解密。對於crypttab中指定,但內核參數未指定的設備,將不會解密,並顯示Not creating device 'devicename' because it was not specified on the kernel command line.警告。若要解密/etc/crypttab中指定的所有設備,不要設置luks.*內核參數,但仍可使用rd.luks.*內核參數指定initramfs階段要解密的設備。若要解密/etc/crypttab.initramfs中指定的所有設備,不要設置任何luks.*、rd.luks.*內核參數。rd.luks.name,則無需指定rd.luks.uuid。rd.luks.uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
使用此參數指定要在啟動過程中解密的設備的UUID。
默認情況下,解密後的設備將被映射到/dev/mapper/luks-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX,其中XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX是LUKS所在分區的UUID。
rd.luks.uuid。rd.luks.name=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=name
本參數用於指定要解密的設備,並設置解密後設備的映射名稱,其中XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX是LUKS所在分區的UUID。name與encrypt的cryptdevice配置中dmname參數作用相同。
例如,若設置rd.luks.name=12345678-9abc-def0-1234-56789abcdef0=root,則將解密UUID為12345678-9ABC-DEF0-1234-56789ABCDEF0的分區,解密後的分區可在/dev/mapper/root訪問。
指定用於解密特定UUID的分區所需要的密鑰文件。與encrypt鉤子的cryptkey參數不同,密鑰文件位置沒有默認值。
若密鑰文件已包含在initramfs中:
rd.luks.key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=/path/to/keyfile
或者:
rd.luks.key=/path/to/keyfile
/etc/cryptsetup-keys.d/name.key,則無需指定rd.luks.key參數。若密鑰文件在另一設備上:
rd.luks.key=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=/path/to/keyfile:UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ
將UUID=ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ替換為密鑰文件所在設備的UUID。
- 若存儲密鑰文件的設備使用的文件系統與根文件系統不同,則必須在initramfs中包含所需內核模塊。
- 默認情況下,若
rd.luks.key指定了位於另一設備上的密鑰文件,但該設備在啟動過程中不可用,則不會回退到使用密碼解密。若需要回退,在rd.luks.options參數中指定keyfile-timeout=選項。例如,若要等待該設備10秒,使用:rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=keyfile-timeout=10s
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=options
或者:
rd.luks.options=options
指定用於解密特定UUID的分區時的額外選項。若不指定UUID,則指定的選項將用於所有解密過程,除非在其它地方(例如,crypttab)單獨為該解密過程指定了選項。
該參數作用與crypttab的選項欄位相同,和crypttab選項欄位的格式也相同,都使用逗號分隔,使用option=value指定帶有值的選項。該參數與encrypt鉤子的cryptdevice參數類似。
例如:
rd.luks.options=timeout=10s,discard,password-echo=no,tries=1
在啟動時,能用於輸入密碼解密卷的時間受兩個選項影響:
-
rd.luks.options=timeout=mytimeout:詢問密碼的超時時間 -
rootflags=x-systemd.device-timeout=mytimeout:systemd等待根文件系統所在設備出現的時間(默認為90秒)
若要完全關閉超時,將兩個超時時間都設為0:
rd.luks.options=timeout=0 rootflags=x-systemd.device-timeout=0
當輸入密碼時,systemd-cryptsetup默認將對每個輸入的字符回顯星號(*)。而encrypt鉤子在輸入時將不回顯。要禁用回顯,設置password-echo=no選項:
rd.luks.options=password-echo=no
若系統有TPM2晶片,或者使用了FIDO2兼容的安全密鑰。可以使用它們而非密碼、密鑰文件來解密卷。
除了rd.luks.uuid/rd.luks.name外,還需添加如下參數:
- 若使用TPM2晶片:
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=tpm2-device=auto - 若使用FIDO2密鑰:
rd.luks.options=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX=fido2-device=auto
此外,也可以在/etc/crypttab.initramfs中指定上述參數:
/etc/crypttab.initramfs
root UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX none tpm2-device=auto
上述配置中,使用UUID指定加密設備名稱,解密後的設備使用root掛載名稱(解密後的設備可通過/dev/mapper/root訪問),不使用密碼解密,而是從TPM2設備獲取密鑰。
注意,若要使用TPM2解密,在密碼欄位必須填寫none或者-,而不能留空。否則,tpm2-device=auto將被識別為密碼,在啟動時,將嘗試使用該「密碼」解密,並在解密失敗時要求手動輸入密碼,而不嘗試使用TPM2解密。
若通過UUID指定設備,請確保其是在磁碟上實際存在的加密容器的UUID,而不是解密後的根文件系統的UUID。
當使用分離的LUKS頭時,使用該參數可指定存儲加密數據的塊設備。同時必須在rd.luks.options中指定LUKS頭的位置。
詳見Dm-crypt/特殊應用#在加密系統時使用分離的LUKS頭。
若滿足Systemd#GPT分區自動掛載中的所有要求,則可以不設置rd.luks相關內核參數。systemd-cryptsetup-generator將自動探測並嘗試解密LUKS加密的根分區。
udev將創建/dev/gpt-auto-root、/dev/gpt-auto-root-luks符號連結,分別指向解密後的根分區、存儲根分區加密容器的分區。可在相關配置文件中使用,作為對相關分區的持久性引用。
在指定crypttab選項時,可以在/etc/crypttab.initramfs中使用/dev/gpt-auto-root-luks作為設備名稱。例如,一個不設置額外選項、使用自動解密的配置文件如下:
/etc/crypttab.initramfs
root /dev/gpt-auto-root-luks none tpm2-device=auto,fido2-device=auto
與fstab相似,/etc/crypttab(encrypted device table,加密設備表)包含了一系列需要在啟動過程中掛載的文件系統,不同之處在於crypttab中指定的是需要被解密的加密設備。可以使用該文件自動掛載加密的swap設備、非根文件系統。
crypttab在fstab之前處理,以便在嘗試掛載加密容器中的文件系統之前,先解密加密容器。
注意,crypttab在系統啟動後(後期用戶空間,掛載根文件系統後)才被處理,因此在加密了根分區的情況下,不能用於替代mkinitcpio鉤子、內核參數配置。crypttab將由systemd-cryptsetup-generator(8)處理。
該文件語法詳見crypttab(5)。此外,下文還提供了一些例子。在#在啟動時掛載節中還包含了使用UUID掛載加密設備的方法。
- 若設置了
nofail選項,則密碼輸入界面可能會在輸入過程中消失。因此,只應在使用密鑰文件時設置nofail選項。 - 對於dm-crypt plain模式加密的設備,必須指定
plain選項,以便systemd-cryptsetup(8)正確識別。參見systemd issue 442。
/etc/crypttab
# 示例crypttab文件。欄位:名稱、底層設備、密碼、cryptsetup選項 # Mount /dev/lvm/swap re-encrypting it with a fresh key each reboot swap /dev/lvm/swap /dev/urandom swap,cipher=aes-xts-plain64,size=256,sector-size=4096 # Mount /dev/lvm/tmp as /dev/mapper/tmp using plain dm-crypt with a random passphrase, making its contents unrecoverable after it is dismounted. tmp /dev/lvm/tmp /dev/urandom tmp,cipher=aes-xts-plain64,size=256 # Mount /dev/lvm/home as /dev/mapper/home using LUKS, and prompt for the passphrase at boot time. home /dev/lvm/home # Mount /dev/disk/by-uuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx as /dev/mapper/backup using LUKS, with a passphrase stored in a file. backup UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /home/alice/backup.key # Unlock /dev/disk/by-partuuid/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx using the only available TPM, naming it myvolume myvolume PARTUUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx none tpm2-device=auto
修改crypttab後,若要立即測試並應用更改,先使用daemon-reload重新加載systemd配置,然後啟動新生成的systemd-cryptsetup@name.service單元。
# cryptsetup status name
/dev/mapper/name is active. type: ... cipher: ... keysize: ... bits key location: ... device: /dev/sdxN sector size: ... offset: ... sectors size: ... sectors mode: ... flags: ...
有關systemd-cryptsetup@name.service單元的更多信息,詳見#按需掛載。
若要在啟動過程中掛載加密設備,將目標設備的UUID加入到/etc/crypttab。可使用lsblk -f查看目標設備的UUID。
crypttab中的條目形如:
/etc/crypttab
externaldrive UUID=2f9a8428-ac69-478a-88a2-4aa458565431 none timeout=180
若設備使用LUKS2加密,也可以通過LUKS2 label指定:
/etc/crypttab
externaldrive LABEL=encrypted-ext-drive-1 none timeout=180
注意,LUKS2頭中設定的label和加密容器上層的文件系統的label是不同的概念。
上述條目中,第一項為設備解密後的設備映射名。none選項表示在啟動時手動輸入解密密碼。timeout選項指定了輸入密碼的超時時間。
crypttab中的某一條目對應設備的密碼與之前的條目相同,則可設置第三個選項為none,將自動使用緩存的密碼進行解密。crypttab中設置的timeout選項只決定輸入密碼的超時時間。此外,systemd還有等待設備可用的超時時間(默認為90秒)。這兩個超時時間是獨立的。因此,即使crypttab中的timeout選項設置值長於90秒(設置為0表示無限時),systemd仍然只會等待某個設備90秒。要修改systemd的等待時間,可在fstab中,為相應的設備設置x-systemd.device-timeout選項(詳見systemd.mount(5))。建議對於啟動時要掛載的加密設備,將crypttab中的timeout與fstab中的x-systemd.device-timeout設置為相同的值。若根文件系統是加密的,可在其中存儲解密其它設備的密鑰文件。由於根文件系統是加密的,因此在系統關機時,密鑰文件是安全的。存儲密鑰文件的好處在於,在啟動時,可通過設置crypttab,自動通過密鑰文件解密其它設備,而無需輸入密碼。
例如,解密指定UUID的設備:
/etc/crypttab
home-crypt UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /etc/cryptsetup-keys.d/home-crypt.key
- 若沒有指定密鑰文件,systemd-cryptsetup(8)會自動嘗試從
/etc/cryptsetup-keys.d/name.key、/run/cryptsetup-keys.d/name.key讀取密鑰文件。[3] - 若使用dm-crypt plain模式,需要在
/etc/crypttab中指定相關加密選項。參見#crypttab節中提到的systemd相關注意事項。
之後,使用/etc/crypttab中定義的設備映射名稱,添加對應的/etc/fstab條目:
/etc/fstab
/dev/mapper/home-crypt /home ext4 defaults 0 2
/dev/mapper/home-crypt已經是持久性的、唯一的分區映射名,可直接使用,而無需通過UUID指定。若要使用UUID指定,應當注意加密容器中文件系統的UUID和包含加密容器的分區的UUID不同。
在啟動時,systemd的生成器將自動處理多層映射的塊設備。
例如,可以先建立RAID,在此之上創建加密卷,再在加密卷上創建LVM邏輯卷,形成多層映射:
$ lsblk -f
─sdXX linux_raid_member
│ └─md0 crypto_LUKS
│ └─cryptedbackup LVM2_member
│ └─vgraid-lvraid ext4 /mnt/backup
└─sdYY linux_raid_member
└─md0 crypto_LUKS
└─cryptedbackup LVM2_member
└─vgraid-lvraid ext4 /mnt/backup
啟動過程中,將詢問密碼,並自動掛載所有層級的設備。
對於非根分區,只要正確設置了相應crypttab、fstab條目,就無需額外添加mkinitcpio鉤子或修改相關配置。注意/etc/crypttab只適合於處理非根分區的掛載。若在掛載在RAID上的根分區時使用了mdadm_udev鉤子,則需要額外配置/etc/madadm.conf並更新initramfs,以正確加載RAID配置。
若在/etc/crypttab中有如下條目:
/etc/crypttab
externaldrive UUID=... none noauto
則若要打開externaldrive,除了直接使用cryptsetup外:
# cryptsetup open UUID=... externaldrive
還可啟動systemd-cryptsetup@externaldrive.service。這樣,無需在打開加密卷時手動輸入加密選項。若需要密碼進行解鎖,啟動單元時將提示輸入。
有關單元文件由systemd-cryptsetup-generator(8)生成。可通過如下命令查看所有生成的單元文件:
$ systemctl list-unit-files | grep systemd-cryptsetup
若在crypttab中指定了某一設備,即使該設備並不需要在啟動時就完成掛載,在默認情況下,cryptsetup服務仍會阻塞地等待該設備完成掛載,再繼續啟動進程。可以通過指定nofail選項避免阻塞等待。添加該選項後,將從指定設備的掛載服務(systemd mount service)中移除Before=cryptsetup.target,避免啟動過程阻塞。若設備不被啟動過程依賴,且使用密鑰文件解鎖,則可使用nofail選項加快啟動過程。
/etc/crypttab
data UUID=d0d0d110-0a71-4ed6-936a-304969ea36af /etc/cryptsetup-keys.d/data.key nofail
若使用了Plymouth,需要確保使用了正確的模塊(詳見Plymouth#mkinitcpio),否則Plymouth將覆蓋密碼輸入提示符,導致無法解密設備,系統無法啟動。
若需要使用鍵盤輸入密碼(特別是鍵盤通過USB拓展塢連接時),或要從特定文件系統上讀取密鑰文件(且該文件系統在生成initramfs時未掛載),可能需要手動向mkinitcpio的MODULES數組中添加需要的模塊。詳見Mkinitcpio#模塊(MODULES)。鍵盤、文件系統需要的模塊名稱可參見Mkinitcpio/極簡_initramfs#整理模塊。
對於外設連接經常改變(即,後續啟動時連接的外設可能和生成initramfs鏡像時不一致)的系統,需要將keyboard鉤子放置到autodetect鉤子之前,以包含所有鍵盤有關模塊,而不是只包含在生成initramfs時連接到計算機的鍵盤的模塊。詳見Mkinitcpio#常用鉤子。