跳至內容

dm-crypt/加密整个系统

出自 Arch Linux 中文维基

本文介紹了幾種常見的使用「dm-crypt」加密整個系統的方式,以及相比正常安裝過程所需的改動。官方安裝鏡像已經包含了加密所需的工具。

若要加密的是已有的未加密的文件系統,見 dm-crypt/設備加密#加密現有的未加密文件系統

概覽

[編輯 | 編輯原始碼]

「dm-crypt」能為為根文件系統提供安全保護,且相比其它方案具更優的性能。相比僅僅加密部分非根文件系統,加密根文件系統可以隱藏許多敏感信息(如已安裝應用列表、用戶名等),並能避免通過locate/var/log/等常見方式洩露數據。此外,由於除了引導加載程序和內核(通常情況下),所有數據都被加密,更難對系統進行未授權的改動。

除了上面提到的共同優點以外,各種加密方案還有如下特有的優缺點:

方案 優點 缺點
#在單一分區上配置LUKS 展示了使用LUKS完全加密的根文件系統的基本方式,最直接。
  • 不靈活;用於加密的整個磁碟空間需要預先分配。
#使用TPM2和安全啟動在單一分區上配置

與上例相似,並通過使用安全啟動、TPM2提高了安全性。

相比上例,本方法還有如下優點:

  • 安全啟動可抵禦邪惡女傭攻擊
  • 在安全啟動被關閉或配置被修改時,TPM2將阻止解密。
  • 與上例缺點相似。
#在LUKS上配置LVM

在LUKS加密的單一分區上配置LVM,實現了分區靈活性。

  • 通過LVM,可簡單地在加密設備上配置多個分區。
  • 只需單一密碼即可解密所有分區。
  • 在未解密時系統的分區結構不可見。
  • 若要使用休眠功能,這是最簡單的方式。
  • LVM增加了系統設備映射結構的複雜性,且需要單獨添加鉤子。
  • 難以對某個分區單獨指定密碼。
  • 若需要配置的LVM卷組包含多個物理卷,則所有物理卷必須分別進行LUKS加密。在系統啟動時,必須分別解鎖所有物理卷後,才能激活並使用卷組。
#在LVM上配置LUKS

在LVM上層使用LUKS。

  • 可通過LVM將(單個)加密分區拓展到多個磁碟上。
  • 可方便地同時配置加密與未加密分區。
  • 若更改了LVM邏輯卷的結構,需要同時更改加密設備與邏輯卷的對應關係,配置複雜。
  • 每個邏輯卷需要單獨設置密碼。
  • LVM中邏輯卷的結構在未解密時也是可見的。
  • 由於每個加密的邏輯卷都需要單獨解密,系統啟動較慢。
#在軟RAID上配置LUKS

在軟RAID上層使用LUKS。

  • 與在LVM上配置LUKS相似。
  • 與在LVM上配置LUKS,並使用加密引導分區類似。
#Plain dm-crypt

使用dm-crypt的plain模式(不使用LUKS頭及LUKS的多密鑰選項)。
此方案還將/boot配置到USB設備上,並通過USB設備儲存密鑰。該思路也適用於其它方案。

  • 在面臨可能損壞LUKS頭的意外情況時,仍能保證數據完整性。
  • 能夠實現可抵賴加密
  • 有助於解決在SSD上應用加密的一些問題
  • 需要尤其關注所有使用的加密參數。
  • 只能使用單個密碼且不能更換密碼。
  • 即使對於常規系統,配置也非常複雜。
#加密boot分區(GRUB)

展示了如何在使用GRUB時加密boot分區。
該方案還使用了EFI系統分區,這也適用於其它方案。

  • 與選擇的加密配置方式相同的優點。(在本例中採用在LUKS上配置LVM)
  • 未加密的數據更少,只有引導加載程序和EFI系統分區(若有)未加密。
  • 與選擇的加密配置方式相同的缺點。(在本例中採用在LUKS上配置LVM)
  • 配置更複雜。
  • 其它引導加載程序不支持此方案。
  • GRUB解密LUKS卷所需的時間較長,將減慢啟動速度。
#Root on ZFS
  • 若將zpool加密,則其中的所有數據集(dataset)都將使用相同的ZFS加密設置加密。同時,由於加密在ZFS層面進行,支持ZFS的系統都可解密,便於配置雙系統或在不同系統間共享數據。
  • 可將加密的文件系統安全地備份到未加密的ZFS中。產生的文件系統快照將保持原生加密狀態
  • ZFS 不會加密有關存儲池結構的文件系統元數據(例如,數據集/快照名稱,數據集結構/屬性/文件大小/文件空洞,deduplication tables(though the deduplicated data itself is encrypted))。
  • 若要追求最佳性能,需要根據磁碟物理屬性創建存儲池時(甚至需要考慮物理塊大小ashift)。
  • ZFS的aes實現存在一些問題;此外,某些加密算法的實現可能存在性能問題
  • 使用zvol作為交換分區或者使用數據集中的文件作為交換文件存在問題。只能通過關閉休眠並設置交換分區到其它分區(詳見下)解決。

雖然對於外界威脅,相比文件系統層面的加密,上述方案提供了好得多的保護。但也有一個共同的缺點:任何擁有密碼的用戶都能解密整個設備,進而訪問其它用戶的數據。若要防範上述風險,可以結合使用塊設備加密和文件系統加密。可參見靜態數據加密進行提前規劃。

對於本文中所有方案的分區策略的概述,參見dm-crypt/準備磁碟#分區

此外,還需考慮是否設置加密的swap分區及設置方式。詳見Dm-crypt/交換分區加密

加密整個系統可在設備失竊時保護數據,但不能抵禦邏輯層面的非法修改(例如,系統上運行的惡意軟體修改未加密的boot分區)。若有相關需求,還應參見dm-crypt/特殊應用#保護未加密的boot分區

在使用固態硬碟時,可能需要啟用TRIM支持。但這可能影響安全性,詳見dm-crypt/特殊應用#固態硬碟的Discard/TRIM支持

警告:
  • 在任何情況下都不要直接在加密卷上運行文件系統修復工具(例如,fsck),否則,加密密鑰將永久丟失,使得所有加密內容無法被解密。只應當在解密後的設備上運行文件系統修復工具。
  • Argon2 密鑰派生函數的設計方式使得其在運行時將占用大量內存(在默認設置下,每個加密卷將占用1GiB內存)。在設備內存較少或啟動時並行解密多個LUKS2分區的情況下,可能導致錯誤。可使用--pbkdf-memory選項控制內存使用。[1]
  • GRUB對LUKS2的支持並不完善,詳見GRUB#加密的/boot。對於需要由GRUB解密的分區,建議使用PBKDF2密鑰派生函數(cryptsetup luksFormat --pbkdf pbkdf2)。
  • 對於ZFS,即使交換分區並沒有放置在zvol上,從休眠中喚醒時也有可能損壞存儲池。因此在配置休眠時需要額外注意。參考

在單一分區上配置LUKS

[編輯 | 編輯原始碼]

本例說明了如何通過「dm-crypt」與LUKS,將安裝在單一分區上的系統進行加密。

+-----------------------+------------------------+-----------------------+
| boot分区              | LUKS加密的根分区      | 可选的用于其它分区的  |
|                       | partition              | 空闲空间              |
|                       |                        |                       | 
| /boot                 | /                      |                       |
|                       |                        |                       |
|                       | /dev/mapper/root       |                       |
|                       |------------------------|                       |
| /dev/sda1             | /dev/sda2              |                       |
+-----------------------+------------------------+-----------------------+

本例的前幾步可在啟動到Arch Linux安裝鏡像後直接進行。

準備磁碟

[編輯 | 編輯原始碼]

在創建分區前,應先查看dm-crypt/準備磁碟,了解安全地擦除整個磁碟的重要性,並掌握相關方法。

接下來,創建本例中的分區(至少需要//dev/sda2)和/boot/dev/sda1),詳見分區

準備非boot分區

[編輯 | 編輯原始碼]

在格式化分區時,不要使用安裝指南中的步驟,而是使用本節及下一節的步驟。

使用如下命令創建並掛載加密的根分區,dm-crypt/設備加密#使用 LUKS 模式加密設備中詳細介紹了進行的操作。若要使用非默認的加密選項(例如,修改加密算法,密鑰長度,扇區大小),在執行如下第一條指令前參見相關加密選項

# cryptsetup -v luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root

在解密的LUKS設備上創建文件系統。例如,要創建Ext4文件系統,執行:

# mkfs.ext4 /dev/mapper/root

將根分區掛載到/mnt

# mount /dev/mapper/root /mnt

確保設備映射正常:

# umount /mnt
# cryptsetup close root
# cryptsetup open /dev/sda2 root
# mount /dev/mapper/root /mnt

若還創建了其它分區(例如,/home),則對於除了/boot的其它分區,執行類似操作。在啟動時解密其它分區的方法可參見dm-crypt/加密非root文件系統#自動解鎖並掛載

注意,對於每個要加密並掛載的塊設備,都需要單獨設置密鑰,這將導致在啟動時需要多次輸入密鑰,造成不便。可通過在根分區中存儲密鑰文件,並通過修改crypttab設置,自動使用密鑰文件解鎖其它設備。詳見dm-crypt/設備加密#使用LUKS來格式化帶有密鑰文件的分區

準備boot分區

[編輯 | 編輯原始碼]

對於加密根分區的配置,需要設置非加密的/boot分區。

對於UEFI啟動的系統,使用如下命令格式化新創建的EFI 系統分區

警告:只有在EFI系統分區是在安裝Arch Linux的分區步驟中創建的情況下,才應當格式化該分區。否則,若EFI系統分區是由其它系統創建的,則重新格式化將導致其它系統的引導程序丟失。
# mkfs.fat -F32 /dev/sda1

對於傳統BIOS啟動的系統:

# mkfs.ext4 /dev/sda1

之後,創建boot分區的掛載點並掛載分區:

# mount --mkdir /dev/sda1 /mnt/boot

掛載分區

[編輯 | 編輯原始碼]

安裝指南#掛載分區步驟時,應當掛載/dev/mapper/*中的相應設備(包含LUKS加密的設備的解密後的版本),而不是LUKS加密的設備自身對應的分區。不過,對於未加密的/boot分區,仍應當直接掛載到/mnt/boot(假設在安裝過程中,根分區被掛載到/mnt)。

配置mkinitcpio

[編輯 | 編輯原始碼]

安裝指南#關於_initramfs步驟前,需要在新安裝的系統中完成如下操作:

若使用基於busybox的initramfs,在mkinitcpio.conf中添加keyboardencrypt鉤子。此外,若要使用非標準鍵盤布局,添加keymap鉤子;若要自定義控制台字體,添加consolefont鉤子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt filesystems fsck)

若使用基於systemd的initramfs,在mkinitcpio.conf中添加keyboardsd-encrypt鉤子。此外,若要使用非標準鍵盤布局,或要自定義控制台字體,添加sd-vconsole鉤子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)

保存上述修改後,重新生成initramfs。其它可能需要用到的鉤子以及配置細節參見Dm-crypt/系統配置#mkinitcpio

配置引導加載程序

[編輯 | 編輯原始碼]

要在啟動時解密已加密的根分區,需配置引導加載程序,設置如下內核參數

cryptdevice=UUID=device-UUID:root root=/dev/mapper/root

若使用的是sd-encrypt,則應該添加如下內核參數:

rd.luks.name=device-UUID=root root=/dev/mapper/root

device-UUID指的是LUKS超級塊的UUID,在本例中為/dev/sda2對應的UUID。詳見塊設備持久化命名

另見Dm-crypt/系統配置#內核參數

提示:若根分區與boot分區在同一硬碟上,並且使用的引導加載程序支持GPT分區自動掛載,則可以修改根分區的分區類型GUID為「Root partition」並通過systemd-gpt-auto-generator(8)自動掛載,而不必設置上述內核參數。

使用TPM2和安全啟動在單一分區上配置

[編輯 | 編輯原始碼]

本例與#在單一分區上配置LUKS相似,但通過使用安全啟動可信平台模塊,使啟動過程更安全。

在本配置方案中,只有EFI 系統分區是未加密的,存儲經過簽名以用於安全啟動的統一內核映像systemd-boot。在本配置中,若安全啟動功能被關閉,或者安全啟動的密鑰資料庫被修改,則TPM將不會釋放用於解密分區的密鑰。此時,仍可以使用配置過程中創建的恢復密鑰解密數據。此外,還可要求在解密數據前必須輸入設置的TPM PIN碼。本配置方案類似Windows中的BitLocker和macOS中的FileVault。

在繼續之前,確保已經詳細閱讀了可信平台模塊#LUKS_數據加密,並著重留意其中的警告。

本例中的分區按照符合Systemd#GPT分區自動掛載的方式創建,因此無需fstab、crypttab文件。

+-----------------------+---------------------------------+
| EFI系统分区             | LUKS加密的根分区                  |
|                       |                                 |
|                       |                                 |
| /boot                 | /                               |
|                       |                                 |
|                       | /dev/mapper/root                |
|                       |---------------------------------|
| /dev/sda1             | /dev/sda2                       |
+-----------------------+---------------------------------+

按照安裝指南#創建硬碟分區前的步驟進行基本配置。之後,按本文下一節的內容進行磁碟分區。

準備磁碟

[編輯 | 編輯原始碼]

在創建分區前,應先查看dm-crypt/準備磁碟,了解安全地擦除整個磁碟的重要性,並掌握相關方法。

使用GUID分區表 (GPT),並創建需要的分區。

創建大小合適的EFI 系統分區(在本例中,使用/dev/sda1)。該分區將被掛載到/boot

在磁碟的剩餘空間上創建根分區(在本例中,使用/dev/sda2)。根分區將被加密,並掛載到/。將根分區的分區類型GUID設置為4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709(在fdisk中,設置為"Linux root (x86-64)"類型;在gdisk中,設置為8304類型)。

準備根分區

[編輯 | 編輯原始碼]

使用如下命令創建並掛載加密的根分區,dm-crypt/設備加密#使用 LUKS 模式加密設備中詳細介紹了進行的操作。

若要使用非默認的加密選項(例如,修改加密算法,密鑰長度,扇區大小),或者不想使用TPM解密,在執行如下第一條指令前參見相關加密選項

創建並掛載LUKS卷(由於在配置完成後將擦除密碼槽位,可以直接使用空密碼):

# cryptsetup luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root

在解密的LUKS設備上創建文件系統。例如,要創建Ext4文件系統,執行:

# mkfs.ext4 /dev/mapper/root

將根分區掛載到 /mnt:

# mount /dev/mapper/root /mnt

準備EFI系統分區

[編輯 | 編輯原始碼]

格式化新創建的EFI系統分區,並掛載:

# mount --mkdir /dev/sda1 /mnt/boot

繼續執行安裝指南#關於_initramfs前的步驟。注意無需執行安裝指南#生成_fstab_文件步驟。

配置mkinitcpio

[編輯 | 編輯原始碼]

修改mkinitcpio.conf中的HOOKS=為如下內容,以構建可用的基於systemd的initramfs:

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt filesystems fsck)

按照統一內核映像#mkinitcpio中的步驟配置統一內核映像

由於/boot/EFI/Linux目錄暫未由啟動加載程序創建,暫時不要重新生成initramfs。

配置引導加載程序

[編輯 | 編輯原始碼]

可以直接通過UEFI啟動內核,而無需引導加載程序。

若仍需使用引導加載程序,可以安裝systemd-boot

# bootctl install

systemd-boot可自動識別mkinitcpio生成的統一內核映像,無需在/boot/loader/entries/手動添加條目。

其它配置參見systemd-boot#更新 EFI 啟動管理器Systemd-boot#配置

完成安裝

[編輯 | 編輯原始碼]

重新生成initramfs,並確保相關鏡像成功生成。

不要忘記設置 root 密碼重啟以完成安裝。

安全啟動

[編輯 | 編輯原始碼]

為了啟用安全啟動,需要為引導加載程序、EFI鏡像簽名。可使用sbctl簡單、快速地實現。

註冊TPM

[編輯 | 編輯原始碼]

在簽名引導加載程序並啟用安全啟動後,可以向TPM註冊密鑰用以解鎖LUKS卷。如下命令將移創建LUKS卷時設置的空密碼,創建綁定到TPM PCR 7安全啟動狀態和已註冊證書)寄存器的密鑰,並創建恢復密鑰,用於在TPM出現問題時解密卷。若安全啟動鏈完好,TPM將自動釋放密鑰。詳見systemd-cryptenroll#Trusted Platform Modulesystemd-cryptenroll(1)

# systemd-cryptenroll /dev/sda2 --recovery-key
# systemd-cryptenroll /dev/sda2 --wipe-slot=empty --tpm2-device=auto --tpm2-pcrs=7
提示:若要求在啟動時需要輸入PIN碼解密卷,可添加--tpm2-with-pin=yes參數。
警告:
  • 在綁定密鑰到PCR7寄存器時,需要確保安全啟動已啟用且處於用戶模式。否則,未授權的啟動設備也可能解鎖加密卷。
  • 若固件證書狀態改變,則PCR7寄存器狀態也可能改變,導致解鎖失敗。例如,使用fwupd[2]可能在不經意間改變固件證書狀態;此外,輪轉安全啟動密鑰也將改變固件證書狀態。


在LUKS上配置LVM

[編輯 | 編輯原始碼]

在加密的單個分區上配置LVM是一種較為直接的方案。該方案將LVM設置在一個大的加密塊設備中,LVM結構只在塊設備解密,掃描並掛載LVM物理卷後才可見。

示例磁碟結構如下:

+-----------------------------------------------------------------------+ +----------------+
| 逻辑卷 1              | 逻辑卷 2              | 逻辑卷 3              | | boot分区       |
|                       |                       |                       | |                |
| [SWAP]                | /                     | /home                 | | /boot          |
|                       |                       |                       | |                |
| /dev/MyVolGroup/swap  | /dev/MyVolGroup/root  | /dev/MyVolGroup/home  | |                |
|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _| | (可能在其他    |
|                                                                       | | 设备上)        |
|                         使用LUKS加密的分区                           | |                |
|                           /dev/sda1                                   | | /dev/sdb1      |
+-----------------------------------------------------------------------+ +----------------+
注意:使用默認的encrypt鉤子時,不能將邏輯卷分配到多個磁碟上。可使用sd-encrypt鉤子或參見dm-crypt/特殊應用#修改encrypt鉤子以用於多個分區
提示:該配置方案有兩種變形:

準備磁碟

[編輯 | 編輯原始碼]

在創建分區前,應先查看dm-crypt/準備磁碟,了解安全地擦除整個磁碟的重要性,並掌握相關方法。

提示:若要在BIOS啟動的設備上使用GPT磁碟,且使用GRUB引導加載程序,需創建BIOS boot partition

創建一個大於1GiB的分區用於/boot

提示:對於UEFI啟動的設備,可將EFI 系統分區用於/boot

創建一個分區,用於存儲整個加密的LVM。

在上述創建的分區上配置LUKS作為LVM的容器(若要修改加密選項,參見dm-crypt/設備加密#LUKS 模式的加密選項):

# cryptsetup luksFormat /dev/sda1

打開創建的容器:

# cryptsetup open /dev/sda1 cryptlvm

現在可通過/dev/mapper/cryptlvm訪問解密的容器。

準備邏輯卷

[編輯 | 編輯原始碼]

在解密的LUKS容器上創建物理卷:

# pvcreate /dev/mapper/cryptlvm

創建卷組(本例中使用MyVolGroup,也可使用其它名稱),並加入先前創建的物理卷:

# vgcreate MyVolGroup /dev/mapper/cryptlvm

在卷組中創建邏輯卷:

提示:若需要使用ext4格式的邏輯卷,應在卷組中預留至少256MiB的空閒空間,以便能正常使用e2scrub(8)。可以在使用-l 100%FREE創建占滿所有剩餘空間的最後一個邏輯卷後,使用類似lvreduce -L -256M MyVolGroup/home的命令減少該邏輯卷的大小。
# lvcreate -L 4G -n swap MyVolGroup
# lvcreate -L 32G -n root MyVolGroup
# lvcreate -l 100%FREE -n home MyVolGroup

在每個邏輯卷上創建文件系統。例如,若根分區和home分區使用Ext4文件系統:

# mkfs.ext4 /dev/MyVolGroup/root
# mkfs.ext4 /dev/MyVolGroup/home
# mkswap /dev/MyVolGroup/swap

掛載文件系統:

# mount /dev/MyVolGroup/root /mnt
# mount --mkdir /dev/MyVolGroup/home /mnt/home
# swapon /dev/MyVolGroup/swap

準備boot分區

[編輯 | 編輯原始碼]

引導加載程序從/boot目錄加載內核、initramfs和自身的配置文件。可使用任何引導加載程序支持的文件系統。

/boot分區創建文件系統。對於UEFI啟動的系統,使用如下命令格式化新創建的EFI 系統分區

警告:只有在EFI系統分區是在安裝Arch Linux的分區步驟中創建的情況下,才應當格式化該分區。否則,若EFI系統分區是由其它系統創建的,則重新格式化將導致其它系統的引導程序丟失。
# mkfs.fat -F32 /dev/sdb1

對於傳統BIOS啟動的系統:

# mkfs.ext4 /dev/sdb1

將上述分區掛載到/mnt/boot

# mount --mkdir /dev/sdb1 /mnt/boot

繼續執行安裝指南#開始安裝系統中的步驟。之後回到本頁,執行修改後的關於 initramfs安裝引導程序步驟。

配置mkinitcpio

[編輯 | 編輯原始碼]

確保已安裝lvm2

若使用基於busybox的initramfs,在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。此外,若要使用非標準鍵盤布局,添加keymap鉤子;若要自定義控制台字體,添加consolefont鉤子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)

若使用基於systemd的initramfs,在mkinitcpio.conf中添加keyboardsd-encryptlvm2鉤子。此外,若要使用非標準鍵盤布局,或要自定義控制台字體,添加sd-vconsole鉤子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)

保存上述修改後,重新生成initramfs。其它可能需要用到的鉤子以及配置細節參見Dm-crypt/系統配置#mkinitcpio

注意:若使用dracut生成mkinitcpio,則其已經包含必要的模塊,無需額外配置。

配置引導加載程序

[編輯 | 編輯原始碼]

要在啟動時解密已加密的根分區,需配置引導加載程序設置如下內核參數

cryptdevice=UUID=device-UUID:cryptlvm root=/dev/MyVolGroup/root

若使用的是sd-encrypt,則應該添加如下內核參數:

rd.luks.name=device-UUID=cryptlvm root=/dev/MyVolGroup/root

device-UUID指的是LUKS超級塊的UUID,在本例中為/dev/sda1對應的UUID。詳見塊設備持久化命名

若使用dracut,一般可使用如下參數:

rd.luks.uuid=device-UUID root=/dev/MyVolGroup/root

有時,需要設置更多參數:

rd.luks.uuid=luks-deviceUUID rd.lvm.lv=MyVolGroup/root  rd.lvm.lv=MyVolGroup/swap  root=/dev/mapper/MyVolGroup-root rootfstype=ext4 rootflags=rw,relatime

詳見Dm-crypt/系統配置#內核參數

在LVM上配置LUKS

[編輯 | 編輯原始碼]

為了在LVM上層設置加密,首先要設置LVM卷,用作加密分區的基礎。在本方案中,可同時創建加密及未加密的分區。

提示:#在LUKS上配置LVM不同,可以使用常規方式將邏輯卷分配到多個磁碟上。

下例展示了在LVM上配置LUKS加密卷,並使用密鑰文件解鎖home分區。對於swap分區,使用臨時加密卷,以確保在每次重啟後,都重新配置swap分區的加密,防止敏感信息洩露,提升安全性。若熟悉LVM配置,可自行修改LVM分區方案。

若要創建橫跨多個磁碟的邏輯卷,或要將已有邏輯卷擴展到其它已配置好的磁碟上,詳見dm-crypt/特殊應用#將LVM拓展到多個磁碟上。注意調整邏輯卷的大小後,LUKS加密容器的大小也需要調整。

準備磁碟

[編輯 | 編輯原始碼]

分區方案如下:

+----------------+-------------------------------------------------------------------------------------------------+
| boot分区       | dm-crypt plain加密的分区        | LUKS加密的分区               | LUKS加密的分区               |
|                |                                 |                               |                               |
| /boot          | [SWAP]                          | /                             | /home                         |
|                |                                 |                               |                               |
|                | /dev/mapper/swap                | /dev/mapper/root              | /dev/mapper/home              |
|                |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|
|                | 逻辑卷 1                        | 逻辑卷 2                      | 逻辑卷 3                      |
|                | /dev/MyVolGroup/cryptswap       | /dev/MyVolGroup/cryptroot     | /dev/MyVolGroup/crypthome     |
|                |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|
|                |                                                                                                 |
|   /dev/sda1    |                                   /dev/sda2                                                     |
+----------------+-------------------------------------------------------------------------------------------------+

按照dm-crypt/準備磁碟#dm-crypt 擦除空設備或分區隨機擦除/dev/sda2

準備邏輯卷

[編輯 | 編輯原始碼]
# pvcreate /dev/sda2
# vgcreate MyVolGroup /dev/sda2
# lvcreate -L 4G -n cryptswap MyVolGroup
# lvcreate -L 32G -n cryptroot MyVolGroup
# lvcreate -l 100%FREE -n crypthome MyVolGroup
# cryptsetup luksFormat /dev/MyVolGroup/cryptroot
# cryptsetup open /dev/MyVolGroup/cryptroot root

在解密後的設備上創建文件系統,並掛載到對應掛載點。例如,要創建Ext4文件系統:

# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

關於加密選項的更多信息,詳見dm-crypt/設備加密#LUKS 模式的加密選項

注意/home的加密會在#加密/home邏輯卷步驟中進行。

提示:若要在Arch ISO中訪問加密的根文件系統,可在LVM邏輯卷出現後執行上述open操作。

準備boot分區

[編輯 | 編輯原始碼]

/boot分區創建文件系統。對於UEFI啟動的系統,使用如下命令格式化新創建的EFI 系統分區

警告:只有在EFI系統分區是在安裝Arch Linux的分區步驟中創建的情況下,才應當格式化該分區。否則,若EFI系統分區是由其它系統創建的,則重新格式化將導致其它系統的引導程序丟失。
# mkfs.fat -F32 /dev/sda1

對於傳統BIOS啟動的系統:

# mkfs.ext4 /dev/sda1

之後,創建boot分區的掛載點並掛在分區:

# mount --mkdir /dev/sda1 /mnt/boot

配置mkinitcpio

[編輯 | 編輯原始碼]

確保已安裝lvm2

若使用基於busybox的initramfs,在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。此外,若要使用非標準鍵盤布局,添加keymap鉤子;若要自定義控制台字體,添加consolefont鉤子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block lvm2 encrypt filesystems fsck)

若使用基於systemd的initramfs,在mkinitcpio.conf中添加keyboardsd-encryptlvm2鉤子。此外,若要使用非標準鍵盤布局,或要自定義控制台字體,添加sd-vconsole鉤子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)

保存上述修改後,重新生成initramfs。其它可能需要用到的鉤子以及配置細節參見Dm-crypt/系統配置#mkinitcpio

配置引導加載程序

[編輯 | 編輯原始碼]

要在啟動時解密已加密的根分區,需配置引導加載程序設置如下內核參數

cryptdevice=UUID=device-UUID:root root=/dev/mapper/root

若使用的是sd-encrypt,則應該添加如下內核參數:

rd.luks.name=device-UUID=root root=/dev/mapper/root

device-UUID指的是LUKS超級塊的UUID,在本例中為/dev/MyVolGroup/cryptroot對應的UUID。詳見塊設備持久化命名

若使用的是dracut,需要一系列更複雜的參數:

kernel_cmdline="rd.luks.uuid=luks-deviceUUID rd.lvm.lv=MyVolGroup/root  rd.lvm.lv=MyVolGroup/swap  root=/dev/mapper/MyVolGroup-root rootfstype=ext4 rootflags=rw,relatime"

詳見Dm-crypt/系統配置#內核參數

配置fstab和crypttab

[編輯 | 編輯原始碼]

crypttab用於解密設備,fstab用於掛載文件系統。如下配置將在每次重啟時用不同的密鑰重新加密swap分區:

/etc/crypttab
swap	/dev/MyVolGroup/cryptswap	/dev/urandom	swap,cipher=aes-xts-plain64,size=256,sector-size=4096
/etc/fstab
/dev/mapper/root                          /     ext4   defaults  0 1
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /boot ext4   defaults  0 2
/dev/mapper/swap                          none  swap   defaults  0 0

加密/home邏輯卷

[編輯 | 編輯原始碼]

由於本方案使用LVM作為第一層,dm-crypt作為第二層,每個加密邏輯卷都需要單獨進行加密解密配置。此外,顯然,和臨時文件系統可採用臨時隨機密鑰加密不同,/home對應的邏輯卷應該採用持久不變的密鑰。下列命令假定你已經重啟進入了安裝好的系統。否則,需要調整相應路徑。

為了避免在系統啟動時輸入兩次密碼,創建密鑰文件

# dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/home.key

/home邏輯卷將採用上述密鑰文件加密:

# cryptsetup luksFormat -v /dev/MyVolGroup/crypthome /etc/cryptsetup-keys.d/home.key
# cryptsetup -d /etc/cryptsetup-keys.d/home.key open /dev/MyVolGroup/crypthome home

在解密後的設備上創建文件系統,並掛載到對應掛載點。例如,要創建Ext4文件系統:

# mkfs.ext4 /dev/mapper/home
# mount /dev/mapper/home /home

解密並掛載該文件系統需要配置crypttabfstab

/etc/crypttab
home	/dev/MyVolGroup/crypthome   none
/etc/fstab
/dev/mapper/home        /home   ext4        defaults        0       2

在軟RAID上配置LUKS

[編輯 | 編輯原始碼]

下例基於真實的工作站筆記本設置,該工作站有兩塊大小相同的SSD及一塊大容量機械硬碟。在本配置中,對所有磁碟採用LUKS加密(包括/boot),並將兩塊SSD組成了RAID0陣列。系統啟動時,在GRUB中輸入正確的密碼後,將用解密出的密鑰文件解密所有分區。

本方案採用的分區配置非常簡單,組成的RAID陣列掛載在/(沒有單獨的/boot 分區),解密後的機械硬碟掛載在/data

注意對於本方案,定期的備份非常重要。若兩塊SSD中的任何一塊損壞,整個RAID陣列中的數據都將丟失。若要求較高的容錯能力,應選擇其它RAID級別

本配置中的加密方式不是可抵賴加密。

在之後的命令中,假定採用如下塊設備設置:

/dev/sda = 第一块SSD
/dev/sdb = 第二块SSD
/dev/sdc = 机械硬盘
+---------------------+---------------------------+---------------------------+ +---------------------+---------------------------+---------------------------+ +---------------------------+
| BIOS boot分区       | EFI系统分区               | LUKS加密的分区           | | BIOS 启动分区       | EFI系统分区               | LUKS加密的分区           | | LUKS加密的分区           |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     | /efi                      | /                         | |                     | /efi                      | /                         | | /data                     |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     |                           | /dev/mapper/root          | |                     |                           | /dev/mapper/root          | |                           |
|                     +---------------------------+---------------------------+ |                     +---------------------------+---------------------------+ |                           |
|                     | RAID1 array (part 1 of 2) | RAID0 array (part 1 of 2) | |                     | RAID1 array (part 2 of 2) | RAID0 array (part 2 of 2) | |                           |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     | /dev/md/ESP               | /dev/md/root              | |                     | /dev/md/ESP               | /dev/md/root              | | /dev/mapper/data          |
|                     +---------------------------+---------------------------+ |                     +---------------------------+---------------------------+ +---------------------------+
| /dev/sda1           | /dev/sda2                 | /dev/sda3                 | | /dev/sdb1           | /dev/sdb2                 | /dev/sdb3                 | | /dev/sdc1                 |
+---------------------+---------------------------+---------------------------+ +---------------------+---------------------------+---------------------------+ +---------------------------+

在之後的操作中,需要根據實際情況替換上述配置。

準備磁碟

[編輯 | 編輯原始碼]

在創建分區前,應先查看dm-crypt/準備磁碟,了解安全地擦除整個磁碟的重要性,並掌握相關方法。

對於使用GPT分區表的BIOS啟動的系統,需創建一個大小為1MiB的BIOS啟動分區,GRUB將在此存儲第二階段的BIOS引導加載程序。不要掛載該分區。

對於UEFI啟動的系統,需創建大小適當的EFI 系統分區,並掛載到/efi

對於設備上的剩餘空間,創建一個用於"Linux RAID"的分區(本例中為/dev/sda3)。對於MBR分區表,選擇fd分區類型ID;對於GPT分區表,選擇A19D880F-05FC-4D3B-A006-743F0F84911E分區類型GUID。

一旦在/dev/sda上創建好了分區,可使用下列命令將它們的配置克隆到/dev/sdb上:

# sfdisk -d /dev/sda > sda.dump
# sfdisk /dev/sdb < sda.dump

對於機械硬碟,創建單個占據整個磁碟的Linux分區(/dev/sdc1)。

構建RAID陣列

[編輯 | 編輯原始碼]

創建用於兩塊SSD的RAID陣列:

注意:
  • 對於兩塊SSD,EFI系統分區必須能在每塊SSD上單獨訪問,因此只能存放在RAID1上。
  • 必須通過--metadata=1.0選項將RAID superblock放置在EFI系統分區的後部,否則固件將不能訪問EFI系統分區。
# mdadm --create --verbose --level=1 --metadata=1.0 --raid-devices=2 /dev/md/ESP /dev/sda2 /dev/sdb2

對於根分區,本例採用了RAID0。可根據實際偏好與需要選擇其它RAID級別。

# mdadm --create --verbose --level=0 --metadata=1.2 --raid-devices=2 /dev/md/root /dev/sda3 /dev/sdb3

準備塊設備

[編輯 | 編輯原始碼]

dm-crypt/準備磁碟中介紹了通過使用隨機密鑰創建加密卷,並向加密卷中寫入/dev/zero產生的全零數據來隨機擦除設備的方法。此外,也可使用dd/dev/random/dev/urandom來擦除,不過速度較慢。

# cryptsetup open --type plain --sector-size 4096 --key-file /dev/urandom /dev/md/root to_be_wiped
# dd if=/dev/zero of=/dev/mapper/to_be_wiped bs=1M status=progress
# cryptsetup close to_be_wiped

對本例中的機械硬碟(/dev/sdc1)也需重複上述操作。

/dev/md/root設置加密:

警告:GRUB對LUKS2的支持並不完善,詳見GRUB#加密的/boot。對於需要由GRUB解密的分區,建議使用PBKDF2密鑰派生函數(cryptsetup luksFormat --pbkdf pbkdf2)。
# cryptsetup -v luksFormat --pbkdf pbkdf2 /dev/md/root
# cryptsetup open /dev/md/root root

在解密後的設備上創建文件系統。例如,要創建Ext4文件系統:

# mkfs.ext4 /dev/mapper/root

將根分區掛載到/mnt

# mount /dev/mapper/root /mnt

對機械硬碟,類似的:

# cryptsetup -v luksFormat /dev/sdc1
# cryptsetup open /dev/sdc1 data
# mkfs.ext4 /dev/mapper/data
# mount --mkdir /dev/mapper/data /mnt/data

對於UEFI啟動的系統,還需設置EFI系統分區:

警告:只有在EFI系統分區是在安裝Arch Linux的分區步驟中創建的情況下,才應當格式化該分區。否則,若EFI系統分區是由其它系統創建的,則重新格式化將導致其它系統的引導程序丟失。
# mkfs.fat -F32 /dev/md/ESP
# mount --mkdir /dev/md/ESP /mnt/efi

配置GRUB

[編輯 | 編輯原始碼]

對於本例中通過LUKS加密的系統,編輯/etc/default/grub以配置GRUB

GRUB_CMDLINE_LINUX="cryptdevice=/dev/md/root:root"
GRUB_ENABLE_CRYPTODISK=y

對於較新的設備,可能需要使用USB鍵盤在GRUB中輸入密碼。這需要啟用固件中的」legacy USB support「,或在/etc/default/grub中添加:

GRUB_TERMINAL_INPUT="usb_keyboard"
GRUB_PRELOAD_MODULES="usb usb_keyboard ohci uhci ehci"

否則在提示輸入LUKS密碼時可能無法使用鍵盤。詳見Dm-crypt/系統配置#內核參數GRUB#加密的/boot

將GRUB安裝到兩塊SSD上(事實上,僅安裝到/dev/sda也是可行的):

# grub-install --target=i386-pc /dev/sda
# grub-install --target=i386-pc /dev/sdb
# grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB
# grub-mkconfig -o /boot/grub/grub.cfg

配置密鑰文件

[編輯 | 編輯原始碼]

進行如下步驟可避免在啟動時需輸入兩次密碼(第一次發生在GRUB解密LUKS設備,第二次發生在initramfs接管系統時)。首先要創建密鑰文件,然後將該密鑰文件加入到initramfs鏡像中以便encrypt鉤子解密根分區。詳見dm-crypt/設備加密#在_initramfs_中嵌入密鑰文件

  • 創建密鑰文件並向其中添加/dev/md/root的密碼。
  • 創建另一個密鑰文件以便於在啟動時解密機械硬碟(/dev/sdc1)。為了便於以後可能的需要恢復的情況,不要移動/刪除上述密鑰文件。接下來編輯/etc/crypttab以在啟動時解密機械硬碟。詳見Dm-crypt/系統配置#使用密鑰文件解密

配置系統

[編輯 | 編輯原始碼]

配置fstab以掛載根分區、data分區、EFI系統分區:

/dev/mapper/root  /	  ext4	rw,noatime 	   0 1
/dev/mapper/data  /data   ext4	defaults           0 2
/dev/md/ESP       /efi     vfat	rw,relatime,codepage=437,iocharset=iso8859-1,shortname=mixed,utf8,tz=UTC,errors=remount-ro  	0 2

保存RAID配置:

# mdadm --detail --scan >> /etc/mdadm.conf

編輯mkinitcpio.conf,包含密鑰文件,並添加所需的鉤子:

FILES=(/crypto_keyfile.bin)
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block mdadm_udev encrypt filesystems fsck)

詳見Dm-crypt/系統配置#mkinitcpio

Plain dm-crypt

[編輯 | 編輯原始碼]

與LUKS不同,dm-crypt的plain模式無需在加密設備前附加LUKS頭,本方案利用該特點在未分區的硬碟上設置加密的系統。對於他人,將無法區分用該方式加密的硬碟與與用隨機數據填充的硬碟,即所謂可抵賴加密。詳見wikipedia:Disk encryption#Full disk encryption

注意,除非需要將整個硬碟全部加密,否則,無論是加密整個系統還是部分分區,使用之前小節中介紹的基於LUKS的方法都是更好的選擇。因為在plain模式中,無法使用LUKS特有的功能,例如支持多個密碼、密鑰文件的密鑰管理,主密鑰備份,原位重新加密。

由於不依賴主密鑰,可避免主密鑰損壞或被銷毀導致的單點故障,plain模式對數據損壞的承受能力更強。此外,若尤為在意對SSD的TRIM支持,也可以使用plain模式。然而,在plain模式下,要到達與LUKS模式相同的加密強度,需要手動配置加密選項。詳見靜態數據加密#加密的元數據

提示:若需要使用無LUKS頭的加密但仍想使用KDF的相關功能,可嘗試如下兩種替代方案:
  • 通過cryptsetup--header選項使用分離的LUKS頭。注意若使用該方案則不能使用標準的"encrypt"鉤子,不過可對該鉤子進行修改。
  • tcplay 在無LUKS頭加密模式下提供了PBKDF2函數。

本方案使用了兩個U盤:

  • 一個用於引導設備,同時存儲用於解密plain加密設備的配置選項;
  • 一個用於密鑰文件,將按原始比特位存儲,故不了解加密方案的攻擊者只能看到一串仿佛隨機的數據,而非可見的普通文件。詳見Wikipedia:Security through obscurity。要準備密鑰文件,參見dm-crypt/Device encryption#Keyfiles

磁碟布局如下:

+----------------------+----------------------+----------------------+ +----------------+ +----------------+
| 逻辑卷 1     | 逻辑卷 2     | 逻辑卷 3     | | 启动设备    | | 密钥 |
|                      |                      |                      | |                | | 存储设备   |
| /                    | [SWAP]               | /home                | | /boot          | | (在本例中 |
|                      |                      |                      | |                | | 未分区)    |
| /dev/MyVolGroup/root | /dev/MyVolGroup/swap | /dev/MyVolGroup/home | | /dev/sdb1      | | /dev/sdc       |
|----------------------+----------------------+----------------------| |----------------| |----------------|
| /dev/sda 使用plain模式加密并配置LVM             | | U盘 1    | | U盘 2    |
+--------------------------------------------------------------------+ +----------------+ +----------------+
提示:
  • 也可以只使用一個U盤,如下為兩種方式:
    • 在U盤(/dev/sdb)的另一個分區(/dev/sdb2)上存儲密鑰。
    • 直接複製密鑰文件到initramfs中。例如,在/etc/mkinitcpio.conf中設置FILES=(/etc/cryptsetup-keys.d/root.key)將複製/etc/cryptsetup-keys.d/root.key密鑰文件到initramfs鏡像中。要使得encrypt鉤子從initramfs鏡像中讀取密鑰文件,在文件名前添加rootfs:前綴,例如,cryptkey=rootfs:/etc/cryptsetup-keys.d/root.key
  • 此外,也可使用足夠安全的密碼解密。

準備磁碟

[編輯 | 編輯原始碼]

向解密後的映射設備中填充隨機數據是非常重要的。尤其是在本例中。

詳見dm-crypt/準備磁碟dm-crypt/準備磁碟#dm-crypt_專用方案

準備分區(除boot)

[編輯 | 編輯原始碼]

詳見dm-crypt/設備加密#plain模式的加密選項

在本例中,使用/dev/sda,並使用aes-xts加密算法,密鑰長度為512位,並使用密鑰文件加密:

 # cryptsetup open --type plain --cipher=aes-xts-plain64 --offset=0 --key-file=/dev/sdc --key-size=512 --sector-size 4096 /dev/sda cryptlvm

與使用LUKS不同,每次要解密設備時必須使用上述「完整」的命令,故一定要牢記加密算法、密鑰文件相關信息。

檢查有關/dev/mapper/cryptlvm的映射條目已建立:

# fdisk -l
提示:
  • 若無需使用LVM提供的功能,cryptsetup FAQ提倡直接在解密後的設備上創建文件系統,而不創建LVM。
  • 若LVM卷組中包含ext4文件系統的邏輯卷,為了便於使用e2scrub(8)工具,至少在卷組中保留256MiB的空閒空間。若使用-l 100%FREE參數創建了最後一個邏輯卷,可以使用lvreduce -L -256M MyVolGroup/home留出256MiB的空閒空間。

接下來,在解密後產生的映射設備上設置LVM邏輯卷,詳見Install Arch Linux on LVM

# pvcreate /dev/mapper/cryptlvm
# vgcreate MyVolGroup /dev/mapper/cryptlvm
# lvcreate -L 32G MyVolGroup -n root
# lvcreate -L 4G MyVolGroup -n swap
# lvcreate -l 100%FREE MyVolGroup -n home

格式化並掛載上述分區並激活swap,詳見文件系統#創建文件系統

# mkfs.ext4 /dev/MyVolGroup/root
# mkfs.ext4 /dev/MyVolGroup/home
# mount /dev/MyVolGroup/root /mnt
# mount --mkdir /dev/MyVolGroup/home /mnt/home
# mkswap /dev/MyVolGroup/swap
# swapon /dev/MyVolGroup/swap

準備boot分區

[編輯 | 編輯原始碼]

可直接將單獨的U盤(通常使用FAT32文件系統)作為/boot分區。或者,若要手動分區,使用分區工具創建大小為1GiB的小分區,並建立文件系統

警告:只有在EFI系統分區是在安裝Arch Linux的分區步驟中創建的情況下,才應當格式化該分區。否則,若EFI系統分區是由其它系統創建的,則重新格式化將導致其它系統的引導程序丟失。
# mkfs.fat -F32 /dev/sdb1
# mount --mkdir /dev/sdb1 /mnt/boot

配置mkinitcpio

[編輯 | 編輯原始碼]

確保已安裝lvm2

若使用基於busybox的initramfs,在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。此外,若要使用非標準鍵盤布局,添加keymap鉤子;若要自定義控制台字體,添加consolefont鉤子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)

保存上述修改後,重新生成initramfs。其它可能需要用到的鉤子以及配置細節參見Dm-crypt/系統配置#mkinitcpio

配置引導加載程序

[編輯 | 編輯原始碼]

要從加密的根分區啟動,需通過引導加載程序設置如下內核參數(注意512位對應64位元組):

cryptdevice=/dev/disk/by-id/disk-ID-of-sda:cryptlvm:sector-size=4096 cryptkey=/dev/disk/by-id/disk-ID-of-sdc:0:64 crypto=:aes-xts-plain64:512:0:

disk-ID-of-disk表示相應磁碟的id,詳見塊設備持久化命名

對於其它可能需要的內核參數,詳見Dm-crypt/系統配置#內核參數

提示:若使用GRUB,可將其安裝到/boot分區所在的U盤上。

對於BIOS啟動的系統:

# grub-install --target=i386-pc --recheck /dev/sdb

對於UEFI啟動的系統:

# grub-install --target=x86_64-efi --efi-directory=/boot --removable

安裝完成後的操作

[編輯 | 編輯原始碼]

或許希望在系統啟動後移除啟動用的U盤。由於/boot分區並不常用,可在/etc/fstab的相應行中添加noauto選項:

/etc/fstab
# /dev/sdb1
UUID=XXXX-XXXX /boot vfat noauto,rw,noatime 0 2

然而,若需要更新initramfs、內核、引導加載程序使用的相關文件時,則必須掛載/boot分區。由於fstab中存在相關條目,只需執行如下命令即可掛載:

# mount /boot

加密的boot分區(GRUB)

[編輯 | 編輯原始碼]

本配置使用與#在LUKS上配置LVM相同的分區結構和配置。但使用了GRUB引導加載程序,其能從LVM邏輯卷和LUKS加密的/boot上啟動系統。詳見GRUB#加密的/boot

本例中的磁碟結構如下:

+---------------------+----------------------+----------------------+----------------------+----------------------+
| BIOS boot分区       | EFI系统分区          | 逻辑卷 1             | 逻辑卷 2             | 逻辑卷 3             |
|                     |                      |                      |                      |                      |
|                     | /efi                 | /                    | [SWAP]               | /home                |
|                     |                      |                      |                      |                      |
|                     |                      | /dev/MyVolGroup/root | /dev/MyVolGroup/swap | /dev/MyVolGroup/home |
| /dev/sda1           | /dev/sda2            |----------------------+----------------------+----------------------+
| 未加密              | 未加密               | /dev/sda3 使用LUKS加密并配置LVM                                   |
+---------------------+----------------------+--------------------------------------------------------------------+
提示:
  • 所有提供的案例僅用作示例。可按需與其它方案結合使用。此外,可參見#在LUKS上配置LVM中介紹的兩種變形。
  • 可以使用cryptbootAUR中的cryptboot腳本簡化加密boot分區的管理(包括掛載、卸載、軟體包更新)。此外,該腳本與UEFI安全啟動配合還可抵禦邪惡女傭攻擊。更多信息及存在的問題見cryptboot project

準備磁碟

[編輯 | 編輯原始碼]

在創建分區前,應先查看dm-crypt/準備磁碟,了解安全地擦除整個磁碟的重要性,並掌握相關方法。

對於UEFI啟動的系統,創建大小合適的EFI 系統分區,將掛載該分區到/efi

對於BIOS + GPT啟動的系統,創建大小為1MiB的BIOS啟動分區,GRUB將在該分區中存儲第二階段引導加載程序,不要手動掛載該分區。

對於BIOS + MBR啟動的系統,無需創建BIOS啟動分區。

創建一個類型為8309的分區用於加密的LVM。

創建LUKS加密容器:

警告:GRUB對LUKS2的支持並不完善,詳見GRUB#加密的/boot。對於需要由GRUB解密的分區,建議使用PBKDF2密鑰派生函數(cryptsetup luksFormat --pbkdf pbkdf2)。
 # cryptsetup luksFormat --pbkdf pbkdf2 /dev/sda3

關於加密選項的更多信息,在執行上述命令前參見dm-crypt/設備加密#LUKS 模式的加密選項

分區結構應與下述相似:

# gdisk -l /dev/sda
...
Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            4095   1024.0 KiB  EF02  BIOS boot partition
   2            4096         2101247   1024.0 MiB  EF00  EFI system partition
   3         2101248        69210111   32.0 GiB    8309  Linux LUKS

打開LUKS加密容器:

# cryptsetup open /dev/sda3 cryptlvm

解密後的容器將在/dev/mapper/cryptlvm

準備邏輯卷

[編輯 | 編輯原始碼]

本例中邏輯卷的結構與#在LUKS上配置LVM中的相同。因此,只需遵循#準備邏輯卷中的步驟並按需調整。

對於UEFI啟動的系統,將EFI 系統分區掛載到/efi,以與接下來的grub-install指令相匹配。

# mount --mkdir /dev/sda2 /mnt/efi

現在,在/mnt下應掛載有如下分區與邏輯卷:

$ lsblk
NAME                  MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda                   8:0      0   200G  0 disk
├─sda1                8:1      0     1M  0 part
├─sda2                8:2      0   550M  0 part  /mnt/efi
└─sda3                8:3      0   100G  0 part
  └─cryptlvm          254:0    0   100G  0 crypt
    ├─MyVolGroup-swap 254:1    0     4G  0 lvm   [SWAP]
    ├─MyVolGroup-root 254:2    0    32G  0 lvm   /mnt
    └─MyVolGroup-home 254:3    0    60G  0 lvm   /mnt/home

繼續執行安裝指南#開始安裝系統及之後的步驟。請使用本文中的對應內容替換安裝指南的Initramfs安裝引導加載程序步驟。

配置mkinitcpio

[編輯 | 編輯原始碼]

確保已安裝lvm2

若使用基於busybox的initramfs,在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。此外,若要使用非標準鍵盤布局,添加keymap鉤子;若要自定義控制台字體,添加consolefont鉤子。

HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block encrypt lvm2 filesystems fsck)

若使用基於systemd的initramfs,在mkinitcpio.conf中添加keyboardsd-encryptlvm2鉤子。此外,若要使用非標準鍵盤布局,或要自定義控制台字體,添加sd-vconsole鉤子。

HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck)

保存上述修改後,重新生成initramfs。其它可能需要用到的鉤子以及配置細節參見Dm-crypt/系統配置#mkinitcpio

配置GRUB

[編輯 | 編輯原始碼]

配置GRUB以從LUKS加密的/boot啟動:

/etc/default/grub
GRUB_ENABLE_CRYPTODISK=y

設置內核參數以便initramfs解密加密的根分區。 若使用encrypt鉤子:

/etc/default/grub
GRUB_CMDLINE_LINUX="... cryptdevice=UUID=device-UUID:cryptlvm ..."

若使用sd-encrypt鉤子:

/etc/default/grub
GRUB_CMDLINE_LINUX="... rd.luks.name=device-UUID=cryptlvm ..."

詳見Dm-crypt/系統配置#內核參數GRUB#加密的/bootdevice-UUID應為LUKS superblock的UUID(在本例中為/dev/sda3,該分區包含了含有根分區的LVM)。詳見塊設備持久化命名

對於UEFI啟動的系統,安裝GRUB到掛載的EFI系統分區:

# grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB --recheck

對於BIOS啟動的系統,安裝GRUB

# grub-install --target=i386-pc --recheck /dev/sda

生成GRUB配置文件

# grub-mkconfig -o /boot/grub/grub.cfg

若上述所有命令都成功執行,在下次重啟後GRUB應提示輸入密碼解鎖/dev/sda3

避免需輸入兩次密碼

[編輯 | 編輯原始碼]

儘管在上述操作後,GRUB會要求輸入密碼解密LUKS加密的分區,但密碼並不會傳遞到initramfs中。因此,需要在啟動時輸入兩次密碼:一次用於GRUB,一次用於initramfs。

可通過在initramfs中嵌入密鑰文件避免輸入兩次密碼。

首先,創建一個密鑰文件,將其添加到LUKS key中:

# dd bs=512 count=4 if=/dev/random iflag=fullblock | install -m 0600 /dev/stdin /etc/cryptsetup-keys.d/cryptlvm.key
# cryptsetup -v luksAddKey /dev/sda3 /etc/cryptsetup-keys.d/cryptlvm.key

將密鑰文件添加到initramfs鏡像:

/etc/mkinitcpio.conf
FILES=(/etc/cryptsetup-keys.d/cryptlvm.key)

重新生成initramfs鏡像。

設置如下內核參數以通過密鑰文件解密LUKS分區。 若使用encrypt鉤子:

GRUB_CMDLINE_LINUX="... cryptkey=rootfs:/etc/cryptsetup-keys.d/cryptlvm.key"

若使用sd-encrypt鉤子,將默認使用/etc/cryptsetup-keys.d/name.key密鑰文件,因此無需手動設置內核參數。

若由於某些原因密鑰文件解密boot分區失敗,systemd會要求手動輸入密碼。輸入正確的密碼後,系統啟動將正常進行。

提示:若想加密/boot分區以抵禦離線攻擊/boot分區的威脅,可使用dm-crypt/特殊應用#mkinitcpio-chkcryptoboot鉤子。

使用USB設備解鎖 /boot

[編輯 | 編輯原始碼]

使用存儲在單獨USB設備上的密鑰文件可避免使用密碼(若密碼太複雜,則難以記憶;若太簡單,則容易被猜中)。從安全性角度考慮,在未使用時,存儲有密鑰文件的USB設備必須與需解密的設備分開保存。

首先,按照#避免需輸入兩次密碼中的步驟創建新的密鑰文件。不要復用initramfs中使用的密鑰文件,否則,若USB設備丟失或密鑰洩露,需要修改嵌入到initramfs中的密鑰文件。

將創建的密鑰文件複製到USB設備,並創建GRUB配置文件:

/boot/grub/grub-pre.cfg
set crypto_uuid=UUID-of-the-luks-volume
set key_disk=UUID-of-the-volume-with-the-key
cryptomount -u $crypto_uuid -k ($key_disk)/the-location-of-the-key-on-your-usb
set root=UUID-of-the-unlocked-volume-as-in-grub.cfg
set prefix=($root)/boot/grub
insmod normal
normal

創建並安裝GRUB鏡像(依文件系統設置而定,可能不需要在鏡像中包含某些模塊):

# grub-mkimage -p /boot/grub -O x86_64-efi -c /boot/grub/grub-pre.cfg -o /tmp/grubx64.efi  part_gpt  part_msdos cryptodisk  luks  gcry_rijndael gcry_sha512 lvm ext2 ntfs fat exfat
# install -v /tmp/grubx64.efi /efi/EFI/GRUB/grubx64.efi

Root on ZFS

[編輯 | 編輯原始碼]

要將dm-crypt與ZFS一同使用,參見ZFS#Encryption in ZFS using dm-crypt

此外,ZFS具有原生加密支持,可用於加密根分區(不包含引導加載程序和文件系統元數據)。詳見:

對於UEFI啟動的系統,在安裝後可通過安全啟動驗證引導加載程序。