dm-crypt/加密整个系统 - Arch Linux 中文维基

跳至內容

# dm-crypt/加密整个系统

出自 Arch Linux 中文维基
< Dm-crypt

翻譯狀態：

- 本文（或部分內容）譯自 dm-crypt/Encrypting an entire system，最近一次同步於 2025-07-10，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

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

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

## 概覽

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

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

方案 | 優點 | 缺點
--- | --- | ---
#在單一分區上配置LUKS 展示了使用LUKS完全加密的根文件系統的基本方式，最直接。 | 分區與配置簡單。 在使用GPT的磁碟上，systemd可自動掛載根分區。 | 不靈活；用於加密的整個磁碟空間需要預先分配。
#使用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中添加`keyboard`和`encrypt`鉤子。此外，若要使用非標準鍵盤布局，添加`keymap`鉤子；若要自定義控制台字體，添加`consolefont`鉤子。

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

若使用基於systemd的initramfs，在mkinitcpio.conf中添加`keyboard`和`sd-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 Module、systemd-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/特殊應用#在加密系統時使用分離的LUKS頭介紹了如何將LUKS頭單獨存放於USB設備上，實現兩步驗證。
- dm-crypt/Specialties#Encrypted /boot and a detached LUKS header on USB則將LUKS頭、加密的boot分區、加密的密鑰文件都存放在USB設備上。

### 準備磁碟

在創建分區前，應先查看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中添加`keyboard`、`encrypt`、`lvm2`鉤子。此外，若要使用非標準鍵盤布局，添加`keymap`鉤子；若要自定義控制台字體，添加`consolefont`鉤子。

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

若使用基於systemd的initramfs，在mkinitcpio.conf中添加`keyboard`、`sd-encrypt`、`lvm2`鉤子。此外，若要使用非標準鍵盤布局，或要自定義控制台字體，添加`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中添加`keyboard`、`encrypt`、`lvm2`鉤子。此外，若要使用非標準鍵盤布局，添加`keymap`鉤子；若要自定義控制台字體，添加`consolefont`鉤子。

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

若使用基於systemd的initramfs，在mkinitcpio.conf中添加`keyboard`、`sd-encrypt`、`lvm2`鉤子。此外，若要使用非標準鍵盤布局，或要自定義控制台字體，添加`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

解密並掛載該文件系統需要配置crypttab和fstab：

    /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中添加`keyboard`、`encrypt`、`lvm2`鉤子。此外，若要使用非標準鍵盤布局，添加`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中添加`keyboard`、`encrypt`、`lvm2`鉤子。此外，若要使用非標準鍵盤布局，添加`keymap`鉤子；若要自定義控制台字體，添加`consolefont`鉤子。

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

若使用基於systemd的initramfs，在mkinitcpio.conf中添加`keyboard`、`sd-encrypt`、`lvm2`鉤子。此外，若要使用非標準鍵盤布局，或要自定義控制台字體，添加`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#加密的/boot。`device-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具有原生加密支持，可用於加密根分區（不包含引導加載程序和文件系統元數據）。詳見：

- OpenZFS上的Arch Linux Root on ZFS指南。
- Install Arch Linux on ZFS#Installation.

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

分類：​

- 靜態數據加密
- 安裝過程

dm-crypt/加密整个系统
新增話題