dm-crypt/加密整个系统

出自 Arch Linux 中文维基

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

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

概覽[編輯 | 編輯原始碼]

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

下面所述的所有方案都有上述優點。此外,各種方案的優缺點總結如下:

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

通過在LUKS加密的單一分區上配置LVM來達到分區靈活性。

  • 通過LVM可簡單地在加密設備上配置多個分區。
  • 只需一個密碼即可解密所有分區。
  • 在未解密時系統的分區結構不可見。
  • 若要使用休眠到硬碟功能,這是最簡單的方式。
  • LVM增加了系統設備mapping結構的複雜性,且需要單獨添加鉤子。
  • 難以對某個分區單獨指定密碼。
#在LVM上配置LUKS

只在LVM上層使用LUKS。

  • 可通過LVM將加密分區拓展到多個磁碟上。
  • 可方便地同時配置加密與未加密分區。
  • 複雜;若更改了LVM邏輯卷的結構,可能需要同時更改encryption mappers。
  • 每個分區需要單獨配置密碼。
  • 即使未加密時,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)
  • 配置更複雜。
  • 其它引導加載程序不支持此方案。
#Root on ZFS

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

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

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

加密整個系統可在設備失竊時保護數據,若還要針對logical tampering提供額外的保護,在完成選擇的方案後,還應參見dm-crypt/Specialties#Securing the unencrypted boot partition

若使用固態硬碟,或許需要啟用TRIM支持。然而,這可能影響安全性,詳見dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD)

警告:
  • 無論選擇何種方案,絕對不能直接在未解密的分區上運行文件系統修復軟體(如fsck),否則解密數據所用的密鑰將永久丟失!相關軟體只能用於解密後的分區。
  • 對於LUKS2格式:
    • GRUB對LUKS2的支持並不完善,詳見GRUB#加密的/boot。對於需要由GRUB解密的分區,建議使用LUKS1(cryptsetup luksFormat --type luks1)。
    • LUKS2採用了占用內存較多的設計方式,默認情況下每個encrypted mapper將占用1GB內存。若設備的內存容量較少或要同時解密較多的LUKS2分區,可能導致系統啟動失敗。可通過--pbkdf-memory選擇控制內存用量,詳見[1]

在單一分區上配置LUKS[編輯 | 編輯原始碼]

本例說明了通過「dm-crypt」與LUKS在單一分區上進行配置以加密整個系統。

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

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

準備磁碟[編輯 | 編輯原始碼]

在創建任何分區前,應先查看dm-crypt/準備磁碟,明確安全地擦除整個磁碟的重要性及相關方法。

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

準備非boot分區[編輯 | 編輯原始碼]

下列命令創建並掛載加密的根分區。dm-crypt/加密非root文件系統#分區中對相關命令有詳細解釋(只要正確配置了mkinitcpio引導加載程序,其中的內容同樣適用於根分區。)

若要使用自定義的加密選項(如cipher、key length),在執行第一條命令前參看 加密選項。若要改變默認扇區大小,參見dm-crypt/設備加密#扇區大小

# cryptsetup -y -v luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root
# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

確保設備mapper已正確設置:

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

若為不同目錄(如/home)創建了單獨的分區,則需要對除了boot分區的所有要加密的分區重複上述步驟。為了在啟動時掛載上述分區,見dm-crypt/加密非root文件系統#自動解鎖並掛載

注意對於每個加密分區都需要單獨設置密碼,並且導致啟動時需要依次輸入每個分區密碼的不便。可通過在根分區存儲一個keyfile並配置crypttab來自動解密其它分區,詳見dm-crypt/設備加密#使用LUKS來格式化帶有密鑰文件的分區

準備boot分區[編輯 | 編輯原始碼]

對於加密根分區的方案,需創建一個未加密的boot分區。對於傳統BIOS啟動的系統上,執行:

# mkfs.ext4 /dev/sda1

或者,在UEFI啟動的系統上可將EFI 系統分區用作/boot

# mkfs.fat -F32 /dev/sda1

之後創建掛載用的目錄並掛載boot分區:

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

掛載分區[編輯 | 編輯原始碼]

在執行安裝指南#掛載分區中的步驟時,注意需要掛載解密後創建的設備mapper而非硬碟上的實際分區。當然,未加密的boot分區需要直接掛載。

配置mkinitcpio[編輯 | 編輯原始碼]

mkinitcpio.conf中添加keyboardencrypt鉤子。若要使用非標準的鍵盤布局,還需添加keymap鉤子;若要修改控制台字體,還需添加consolefont鉤子:

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

若使用基於sysyemd的initramfs,需添加的應為keyboardsd-encrypt鉤子。若要使用非標準鍵盤布局或修改控制台字體,還需添加sd-vconsole鉤子:

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

在保存上述修改後,重新生成initramfs。對於可能需要的其它鉤子,詳見dm-crypt/System configuration#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。詳見塊設備持久化命名

另見dm-crypt/System configuration#Kernel parameters

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

在LUKS上配置LVM[編輯 | 編輯原始碼]

在加密的單個分區上配置LVM是一種較為直接的方案。該方案將LVM設置在一個大的加密的塊設備中。因此,在該塊設備解密、卷結構被掃描、分區在啟動時被掛載前,整個LVM都是不可見的。

以下為示例磁碟結構:

+-----------------------------------------------------------------------+ +----------------+
| 逻辑卷 1              | 逻辑卷 2              | 逻辑卷 3              | | boot分区       |
|                       |                       |                       | |                |
| [SWAP]                | /                     | /home                 | | /boot          |
|                       |                       |                       | |                |
| /dev/MyVolGroup/swap  | /dev/MyVolGroup/root  | /dev/MyVolGroup/home  | |                |
|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _| | (可能在其他    |
|                                                                       | | 设备上)        |
|                         使用LUKS2加密的分区                           | |                |
|                           /dev/sda1                                   | | /dev/sdb1      |
+-----------------------------------------------------------------------+ +----------------+
注意: 若使用默認的encrypt鉤子,則不能將邏輯卷分配到多個磁碟上。可使用sd-encrypt鉤子或參見dm-crypt/Specialties#Modifying the encrypt hook for multiple partitions
提示:該配置方案有兩個變體:

準備磁碟[編輯 | 編輯原始碼]

在創建任何分區前,應先查看dm-crypt/Drive preparation,明確安全地擦除整個磁碟的重要性及相關方法。

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

創建一個大於200MiB的分區用於/boot

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

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

在上述創建的分區上配置LUKS作為LVM的容器:

# cryptsetup luksFormat /dev/sda1

若要自定義cryptsetup的選項,在執行上述命令參考LUKS加密選項

打開創建的容器:

# 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 8G MyVolGroup -n swap
# lvcreate -L 32G MyVolGroup -n root
# lvcreate -l 100%FREE MyVolGroup -n home

格式化邏輯卷:

# 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的分區上創建文件系統

# mkfs.ext4 /dev/sdb1
提示:若要將EFI 系統分區用於/boot},則推薦使用Fat32格式:
# mkfs.fat -F32 /dev/sdb1

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

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

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

配置mkinitcpio[編輯 | 編輯原始碼]

確保安裝了lvm2,之後在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。若要使用非標準的鍵盤布局,還需添加keymap鉤子;若要修改控制台字體,還需添加consolefont鉤子:

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

若使用基於sysyemd的initramfs,需添加的應為keyboardlvm2sd-encrypt鉤子。若要使用非標準鍵盤布局或修改控制台字體,還需添加sd-vconsole鉤子:

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

在保存上述修改後,重新生成initramfs。對於可能需要的其它鉤子,詳見dm-crypt/System configuration#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。詳見塊設備持久化命名

若使用的是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/System configuration#Kernel parameters

在LVM上配置LUKS[編輯 | 編輯原始碼]

為了在LVM上層設置加密,首先要設置LVM卷,將它們用作加密分區的基礎。在這種配置方案下,可同時創建加密及未加密的分區。

提示:#在LUKS上配置LVM不同,本方案允許以普通的方式將邏輯卷分配到多個磁碟上。

下例展示了在LVM上配置LUKS的方法,並且對不同邏輯卷採用了不同的加密方式:/home卷採用keyfile,/tmp/swap則採用臨時隨機密鑰。採用臨時隨機密鑰是基於安全性考慮,每次重啟後加密都將重新配置,使得臨時數據不會在重啟後保留。若你熟悉LVM,可根據自己的方案修改下述案例。

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

準備磁碟[編輯 | 編輯原始碼]

分區方案如下:

+----------------+-------------------------------------------------------------------------------------------------+
| boot分区       | dm-crypt plain加密的分区        | LUKS2加密的分区               | LUKS2加密的分区               |
|                |                                 |                               |                               |
| /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/Drive preparation#dm-crypt wipe on an empty disk or partition]]隨機擦除/dev/sda2

準備邏輯卷[編輯 | 編輯原始碼]

# pvcreate /dev/sda2
# vgcreate MyVolGroup /dev/sda2
# lvcreate -L 32G -n cryptroot MyVolGroup
# lvcreate -L 500M -n cryptswap MyVolGroup
# lvcreate -L 500M -n crypttmp MyVolGroup
# lvcreate -l 100%FREE -n crypthome MyVolGroup
# cryptsetup luksFormat /dev/MyVolGroup/cryptroot
# cryptsetup open /dev/MyVolGroup/cryptroot root
# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

關於加密選項的更多信息,詳見dm-crypt/Device encryption#Encryption options for LUKS mode

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

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

準備boot分區[編輯 | 編輯原始碼]

# dd if=/dev/zero of=/dev/sda1 bs=1M status=progress
# mkfs.ext4 /dev/sda1
# mount --mkdir /dev/sda1 /mnt/boot

配置mkinitcpio[編輯 | 編輯原始碼]

確保安裝了lvm2,之後在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。若要使用非標準的鍵盤布局,還需添加keymap鉤子;若要修改控制台字體,還需添加consolefont鉤子:

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

若使用基於sysyemd的initramfs,需添加的應為keyboardsd-encrypt鉤子。若要使用非標準鍵盤布局或修改控制台字體,還需添加sd-vconsole鉤子:

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

在保存上述修改後,重新生成initramfs。對於可能需要的其它鉤子,詳見dm-crypt/System configuration#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。詳見塊設備持久化命名

若使用的是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/System configuration#Kernel parameters

配置fstab和crypttab[編輯 | 編輯原始碼]

解密設備和掛載其上的文件系統分別需要編輯crypttabfstab。下列配置將在每次重啟時重新加密臨時文件系統:

/etc/crypttab
swap	/dev/MyVolGroup/cryptswap	/dev/urandom	swap,cipher=aes-xts-plain64,size=256
tmp	/dev/MyVolGroup/crypttmp	/dev/urandom	tmp,cipher=aes-xts-plain64,size=256
/etc/fstab
/dev/mapper/root        /       ext4            defaults        0       1
/dev/sda1               /boot   ext4            defaults        0       2
/dev/mapper/tmp         /tmp    tmpfs           defaults        0       0
/dev/mapper/swap        none    swap            sw              0       0

加密/home邏輯卷[編輯 | 編輯原始碼]

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

為了在系統啟動時無需輸入兩次密碼,創建了keyfile

# mkdir -m 700 /etc/luks-keys
# dd if=/dev/random of=/etc/luks-keys/home bs=1 count=256 status=progress

該邏輯卷將採用上述keyfile加密:

# cryptsetup luksFormat -v /dev/MyVolGroup/crypthome /etc/luks-keys/home
# cryptsetup -d /etc/luks-keys/home open /dev/MyVolGroup/crypthome home
# mkfs.ext4 /dev/mapper/home
# mount /dev/mapper/home /home

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

/etc/crypttab
home	/dev/MyVolGroup/crypthome   /etc/luks-keys/home
/etc/fstab
/dev/mapper/home        /home   ext4        defaults        0       2

在軟RAID上配置LUKS[編輯 | 編輯原始碼]

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

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

注意對於該方案,定期的備份非常重要。若兩塊SSD中的任何一塊損壞,整個RAID陣列中的數據將在實踐上不可能被恢復。若對硬體錯誤的容忍能力對你來說非常重要,應選擇其它的RAID級別

The encryption is not deniable in this setup.

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

/dev/sda = 第一块SSD
/dev/sdb = 第二块SSD
/dev/sdc = 机械硬盘
+---------------------+---------------------------+---------------------------+ +---------------------+---------------------------+---------------------------+ +---------------------------+
| BIOS boot分区       | EFI系统分区               | LUKS1加密的分区           | | BIOS 启动分区       | EFI系统分区               | LUKS1加密的分区           | | LUKS2加密的分区           |
|                     |                           |                           | |                     |                           |                           | |                           |
|                     | /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/Drive preparation,明確安全地擦除整個磁碟的重要性及相關方法。

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


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

對於設備上的剩餘空間,創建一個用於"Linux RAID"的分區(本例中為/dev/sda3)。對於MBR分區表,選擇fd分區type ID;對於GPT分區表,選擇A19D880F-05FC-4D3B-A006-743F0F84911E分區type 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上單獨訪問,因此ESP只能被存放在RAID1上。
  • RAID superblock必須通過--metadata=1.0選項放置在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/Drive preparation中介紹了如何使用/dev/zero與隨機密鑰加密來用隨機數據擦除設備。此外,也可使用dd/dev/random/dev/urandom,不過比前者慢得多。

# cryptsetup open --type plain /dev/md/root container --key-file /dev/random
# dd if=/dev/zero of=/dev/mapper/container bs=1M status=progress
# cryptsetup close container

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

/dev/md/root設置加密:

警告: GRUB對LUKS2的支持並不完善,詳見[GRUB#加密的/boot]]。對於需要由GRUB解密的分區,建議使用LUKS1(cryptsetup luksFormat --type luks1)。
# cryptsetup -y -v luksFormat --type luks1 /dev/md/root
# cryptsetup open /dev/md/root root
# mkfs.ext4 /dev/mapper/root
# mount /dev/mapper/root /mnt

對機械硬碟,相似的:

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

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

# mkfs.fat -F32 /dev/md/ESP
# mount --mkdir /dev/md/ESP /mnt/efi

配置GRUB[編輯 | 編輯原始碼]

對於本例中通過LUKS1加密的系統,編輯/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/System configuration#Kernel parametersGRUB#Encrypted /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

配置keyfile[編輯 | 編輯原始碼]

下面進行的步驟可避免在啟動時需輸入兩次密碼的情況(第一次發生在GRUB解密LUKS1設備,第二次發生在initramfs接管系統時)。首先要創建一個keyfile,然後將該keyfile加入到initramfs鏡像中以便encrypt鉤子解密根分區。詳見dm-crypt/Device encryption#With a keyfile embedded in the initramfs

  • 創建keyfile並向其中添加/dev/md/root的密碼。
  • 創建另一個keyfile以便於在啟動時解密機械硬碟(/dev/sdc1)。為了便於以後可能的需要恢復的情況,不要移動/刪除上述keyfile。接下來編輯/etc/crypttab以在啟動時解密機械硬碟。詳見dm-crypt/System configuration#Unlocking with a keyfile

配置系統[編輯 | 編輯原始碼]

配置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以包含keyfile,並添加所需的鉤子:

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

詳見dm-crypt/System configuration#mkinitcpio

Plain dm-crypt[編輯 | 編輯原始碼]

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

注意若不需要全盤(可抵賴)加密,無論對於加密整個系統還是加密某個分區,之前介紹的使用LUKS的方法都更好。在plain 模式下將無法使用多密碼/keyfile的密鑰管理、就地重新加密一個設備等LUKS的特色功能。

因為無需依賴單個加密的master-key,可避免因master-key損壞造成單點故障,plain dm-crypt加密對數據錯誤的容忍性較LUKS強。然而,使用plain模式也需要更多的手動配置以達到與LUKS相同的加密強度(詳見Data-at-rest encryption#Cryptographic metadata)。此外,若擔心dm-crypt/Specialties#Discard/TRIM support for solid state drives (SSD)中提到的問題,也可使用plain模式。

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

本方案使用了兩個U盤:

  • 一個用於引導設備,同時存儲用於解密plain加密設備的配置選項;
  • 一個用於keyfile,將存儲為raw bits,故對於不不知道配置方案的攻擊者而言,只能看到一串仿佛隨機的數據而非可見的普通文件。詳見Wikipedia:Security through obscurity。要準備keyfile,見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盤:
    • 可以將keyfile放到U盤(/dev/sdb)的另一個分區(/dev/sdb2)上。
    • 或直接將keyfile複製到initramfs上例如,對於keyfile /etc/keyfile,可在/etc/mkinitcpio.conf中設置FILES=(/etc/keyfile)。要使encrypt鉤子讀取initramfs鏡像中的keyfile,在文件名前指定rootfs:前綴,如cryptkey=rootfs:/etc/keyfile
  • 另一種配置方法是結合密碼與良好的熵源

準備磁碟[編輯 | 編輯原始碼]

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


詳見dm-crypt/準備磁碟、[dm-crypt/準備磁碟#dm-crypt 專用方案]]

準備分區(除boot)[編輯 | 編輯原始碼]

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

在本例中,使用/dev/sda,並使用aes-xts cipher,512位的key size,使用keyfile加密:

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

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

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

# fdisk -l
提示:與使用LVM相比,一個簡單的方法是直接在解密的設備上創建單獨一個文件系統。這也是cryptsetup FAQ中對於無需使用LVM時推薦的方法。

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

# pvcreate /dev/mapper/cryptlvm
# vgcreate MyVolGroup /dev/mapper/cryptlvm
# lvcreate -L 32G MyVolGroup -n root
# lvcreate -L 10G 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盤默認的vfat分區用作/boot分區。但若要手動分區,僅需配置一個200MiB的分區用於/boot。通過分區工具進行分區。

/boot創建文件系統

# mkfs.fat -F32 /dev/sdb1
# mount --mkdir /dev/sdb1 /mnt/boot

配置mkinitcpio[編輯 | 編輯原始碼]

確保安裝了lvm2,之後在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。若要使用非標準的鍵盤布局,還需添加keymap鉤子;若要修改控制台字體,還需添加consolefont鉤子:

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

在保存上述修改後,重新生成initramfs。對於可能需要的其它鉤子,詳見dm-crypt/System configuration#mkinitcpio

配置引導加載程序[編輯 | 編輯原始碼]

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

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

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

對於其它可能需要的內核參數,詳見dm-crypt/System configuration#Kernel parameters

提示:若使用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
/dev/sdb1 /boot vfat noauto,rw,noatime 0 2

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

# mount /boot

加密的boot分區(GRUB)[編輯 | 編輯原始碼]

本配置使用與#在LUKS上配置LVM相同的分區結構和配置,除了使用了GRUB引導加載程序,其能夠從LVM邏輯卷和LUKS1加密的/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 使用LUKS1加密并配置LVM                                   |
+---------------------+----------------------+--------------------------------------------------------------------+
提示:
  • 所有案例僅用作示例。當然也可以與其它案例結合使用。此外,可參見#在LUKS上配置LVM中介紹的兩種變體。
  • 可以使用cryptbootAUR中的cryptboot腳本簡化加密boot分區的管理(包括掛載、卸載、軟體包更新)。此外,該腳本與UEFI安全啟動配合還可抵禦Evil Maid攻擊。更多信息及缺陷見cryptboot project

準備磁碟[編輯 | 編輯原始碼]

在創建任何分區前,應先查看dm-crypt/Drive preparation,明確安全地擦除整個磁碟的重要性及相關方法。

對於BIOS啟動,GUID分區表的系統,需創建大小1MiB的BIOS啟動,GUID分區表的系統|BIOS boot分區用於GRUB存儲第二階段引導加載程序。不要掛載該分區。BIOS啟動,MBR分區表的系統無須上述操作。

對於UEFI啟動的系統,創建大小合適的[EFI 系統分區]],其會被掛載到/efi

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

創建LUKS加密容器:

警告: GRUB對LUKS2的支持並不完善,詳見[GRUB#加密的/boot]]。對於需要由GRUB解密的分區,建議使用LUKS1(cryptsetup luksFormat --type luks1)。
# cryptsetup luksFormat --type luks1 /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         1130495   550.0 MiB   EF00  EFI System
   3         1130496        68239360   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     8G  0 lvm   [SWAP]
    ├─MyVolGroup-root 254:2    0    32G  0 lvm   /mnt
    └─MyVolGroup-home 254:3    0    60G  0 lvm   /mnt/home

配置mkinitcpio[編輯 | 編輯原始碼]

確保安裝了lvm2,之後在mkinitcpio.conf中添加keyboardencryptlvm2鉤子。若要使用非標準的鍵盤布局,還需添加keymap鉤子;若要修改控制台字體,還需添加consolefont鉤子:

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

若使用基於sysyemd的initramfs,需添加的應為keyboardsd-encrypt鉤子。若要使用非標準鍵盤布局或修改控制台字體,還需添加sd-vconsole鉤子:

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

在保存上述修改後,重新生成initramfs。對於可能需要的其它鉤子,詳見dm-crypt/System configuration#mkinitcpio

配置GRUB[編輯 | 編輯原始碼]

配置GRUB以從LUKS1加密的/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/System configuration#Kernel parametersGRUB#加密的/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會要求輸入密碼解密LUKS1加密的分區,該信息並未傳遞到initramfs。因此,需要在啟動時輸入兩次密碼:一次用於GRUB,一次用於initramfs。

本節介紹了配置啟動過程僅需輸入一次密碼(在GRUB中)的額外操作。可通過在initramfs中嵌入密鑰文件達成。

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

# dd bs=512 count=4 if=/dev/random of=/root/cryptlvm.keyfile iflag=fullblock
# chmod 000 /root/cryptlvm.keyfile
# cryptsetup -v luksAddKey /dev/sda3 /root/cryptlvm.keyfile

將keyfile添加到initramfs鏡像:

/etc/mkinitcpio.conf
FILES=(/root/cryptlvm.keyfile)

重新生成initramfs鏡像。 之後,對keyfile進行安全保護:

# chmod 600 /boot/initramfs-linux*

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

GRUB_CMDLINE_LINUX="... cryptkey=rootfs:/root/cryptlvm.keyfile"

若使用sd-encrypt鉤子:

GRUB_CMDLINE_LINUX="... rd.luks.key=device-UUID=/root/cryptlvm.keyfile"

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

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

Btrfs子卷,帶swap[編輯 | 編輯原始碼]

譯註:原文採用的部分方法已過時,從內核版本5.0開始,btrfs已支持swapfile。

本例通過在LUKS1上使用Btrfs來加密整個系統,並使用Btrfs子捲來模擬分區

對於UEFI啟動的設備,需要EFI 系統分區(ESP),不能加密該分區。/boot則可以與/為同一個子卷並配置加密。在本例中,/dev/sda1作為ESP並被掛載到/efi/boot/在同一個分區(/dev/sda2)上。

由於/boot位於LUKS1加密的/上,引導加載程序必須使用GRUB,因為只有GRUB可加載相應的模塊(如crypto.mod,cryptodisk.mod和luks.mod)以解密/boot

此外, 本例還展示了一個可選的,以plain模式加密的swap分區:

+----------------------+----------------------+----------------------+
| EFI系统分区          | 根分区               | Swap分区             |
| 未加密               | LUKS1模式加密        | plain模式加密        |
|                      |                      |                      |
| /efi                 | /                    | [SWAP]               |
| /dev/sda1            | /dev/sda2            | /dev/sda3            |
+----------------------+----------------------+----------------------+

準備磁碟[編輯 | 編輯原始碼]

注意: 在使用LUKS時,不能使用Btrfs#無分區 Btrfs 磁碟中介紹的方法。即使只打算創建一個分區,也要使用傳統的分區方式。

在創建任何分區前,應先查看dm-crypt/Drive preparation,明確安全地擦除整個磁碟的重要性及相關方法。若使用UEFI,需創建大小合適的EFI 系統分區。若要創建加密的swap分區,可以先建立分區結構,但因為將使用plain模式加密該分區,不要將其直接標記為swap分區。

創建需要的分區,至少要創建根分區(本例中為/dev/sda2)。詳見分區

準備根分區[編輯 | 編輯原始碼]

創建LUKS容器[編輯 | 編輯原始碼]

警告: GRUB對LUKS2的支持並不完善,詳見[GRUB#加密的/boot]]。對於需要由GRUB解密的分區,建議使用LUKS1(cryptsetup luksFormat --type luks1)。

按照dm-crypt/設備加密#使用 LUKS 模式加密設備中的步驟對/dev/sda2設置LUKS。在設置之前,可以在dm-crypt/設備加密#LUKS 模式的加密選項查看可用的加密選擇。

解鎖LUKS容器[編輯 | 編輯原始碼]

按照dm-crypt/設備加密#使用設備映射器解鎖/映射 LUKS分區中的步驟解密並映射LUKS容器。

格式化映射後的設備[編輯 | 編輯原始碼]

按照Btrfs#單一設備上的文件系統中的步驟格式化映射後的設備。在格式化時,注意/dev/分區名應為映射後的設備(在本例中,即/dev/mapper/root),而非/dev/sda2

掛載映射後的設備[編輯 | 編輯原始碼]

最後,掛載已格式化的映射後的設備(在本例中,即/dev/mapper/root)到/mnt

創建btrfs子卷[編輯 | 編輯原始碼]

布局[編輯 | 編輯原始碼]

子卷將用於模擬分區,但除此之外還將創建嵌套子卷。如下是本例配置的部分展示:

subvolid=5
  |
  ├── @ -|
  |     包含如下目录:
  |       ├── /usr
  |       ├── /bin
  |       ├── /.snapshots
  |       ├── ...
  |
  ├── @home
  ├── @snapshots
  ├── @var_log
  └── @...

本例遵循了Snapper#Suggested filesystem layout的配置,有助於與Snapper配合使用。有關子卷布局,還可參考Btrfs Wiki SysadminGuide#Layout

為第一次掛載準備子卷[編輯 | 編輯原始碼]

依據慣例,對於用作掛載點的子卷,本例在子卷名稱前加上@@對應於掛載到/的子卷。

按照Btrfs#創建子卷,在/mnt/@/mnt/@snapshots/mnt/@home創建子卷。

此外,根據你的配置,現在還應創建用作掛載點的其它子卷。

創建例外子卷[編輯 | 編輯原始碼]

對於在為/製作快照時欲排除的目錄,可創建相應子卷。例如,可能需要排除/var/cache/pacman/pkg目錄。這些子卷會嵌套在@子卷下,但根據不同的設置,也可能已在上一步創建,並與@同級。

常見的需創建例外子卷的有:/var/abs/var/tmp/srv

掛載頂層子卷[編輯 | 編輯原始碼]

卸載已掛載到{{ic|/mnt}的根文件系統。

之後,通過subvol=掛載選項將創建的用於/@子卷掛載到/mnt。假設解密產生的映射設備為root,執行的命令與與如下的相似:

# mount -o compress=zstd,subvol=@ /dev/mapper/root /mnt

詳見Btrfs#掛載子卷

此外,將其它子卷掛載到相應的位置:@home掛載到/mnt/home@snapshots掛載到/mnt/.snapshots

掛載ESP[編輯 | 編輯原始碼]

若之前準備了EFI系統分區,創建相應掛載點並掛載。

注意: 由於/efi不是btrfs文件系統的一部分,btrfs快照將忽略它。

在執行pacstrap安裝步驟時,除base元軟體包外,還必須安裝btrfs-progs

配置mkinitcpio[編輯 | 編輯原始碼]

創建keyfile[編輯 | 編輯原始碼]

為了允許GRUB解密LUKS分區,同時無需輸入兩次密碼,本例將keyfile嵌入initramfs中。執行dm-crypt/設備加密#在 initramfs 中嵌入密鑰文件中的步驟。在luksAddKey步驟時,確保目標為/dev/sda2

編輯mkinitcpio.conf[編輯 | 編輯原始碼]

按上述步驟創建、添加並嵌入keyfile後,將encrypt連同其它需要的鉤子一同加入mkinitcpio.conf

在保存上述修改後,重新生成initramfs。對於可能需要的其它鉤子,詳見dm-crypt/System configuration#mkinitcpio

提示:可能還需向/etc/mkinitcpio.conf中加入BINARIES=(btrfs)。詳見Btrfs#損壞恢復

配置引導加載程序[編輯 | 編輯原始碼]

安裝GRUB,並按GRUB#額外的參數GRUB#加密的/bootdm-crypt/System configuration#Using encrypt hook中的步驟編輯/etc/default/grub,注意要遵循有關加密的根分區、加密的boot分區兩方面的內容。最後,生成GRUB配置文件。注意還需按照Btrfs#掛載子卷為根掛載點中的要求設定內核參數。

配置swap[編輯 | 編輯原始碼]

若創建了用於加密的swap的分區,按照dm-crypt/Swap encryption中的步驟進行配置。

Root on ZFS[編輯 | 編輯原始碼]

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

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

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

使用TPM2和安全啟動的簡單根分區加密[編輯 | 編輯原始碼]

本例介紹了通過dm-crypt + LUKS以及TPM2、安全啟動配置的全系統加密。

僅有包含Unified kernel imagesystemd-boot的ESP是未加密的。可將Unified kernel imagesystemd-boot簽名並與安全啟動一同使用,TPM會檢測安全啟動狀態,所以若安全啟動被關閉或其密鑰資料庫被修改,加密的分區將不會被自動解密。這提供了合理的安全啟動鏈(與Windows的BitLocker,macOS的FileVault相似)。

本例中,分區按照systemd#GPT分區自動掛載的要求創建,故無需配置fstab或crypttab。

+-----------------------+------------------------+-----------------------+
| ESP                   | 根分区                                         |
| 未加密                | 加密                                           |
|                       |                                                |
| /efi                  | /                                              |
|                       |                                                |
|                       | /dev/mapper/root                               |
|                       |------------------------------------------------|
| /dev/sda1             | /dev/sda2                                      |
+-----------------------+------------------------+-----------------------+

遵循安裝指南中的步驟直到創建硬碟分區

對硬碟分區[編輯 | 編輯原始碼]

在創建任何分區前,應先查看dm-crypt/Drive preparation,明確安全地擦除整個磁碟的重要性及相關方法。

此外,確保硬碟報告的扇區大小是正確的,詳見sector size

確保分區表類型為GPT。之後創建相關分區(如/dev/sda2用於//dev/sda1用於/efi)。詳見分區

格式化分區[編輯 | 編輯原始碼]

根分區[編輯 | 編輯原始碼]

下列命令創建並掛載加密的根分區,並通過TPM存儲密鑰。詳見dm-crypt/加密非root文件系統(只要正確配置了mkinitcpio引導加載程序其中的內容也可用於加密根分區)、Trusted Platform Module#systemd-cryptenroll

若要使用非默認的加密選項(如cipher、key length),或要求不使用基於TPM的解密,在執行下列命令前參見encryption options

創建所需的LUKS卷(創建時可使用空密碼,之後該密碼將被擦除):

# cryptsetup luksFormat /dev/sda2
# cryptsetup open /dev/sda2 root
# mkfs.ext4 /dev/mapper/root

ESP[編輯 | 編輯原始碼]

詳見EFI 系統分區#格式化分區

掛載文件系統[編輯 | 編輯原始碼]

安裝指南#掛載分區步驟時,注意應掛載解密後產生的映射設備,而不是對應的物理分區,即:

# mount /dev/mapper/root /mnt
# mount --mkdir /dev/sda1 /mnt/efi

繼續按照指南進行安裝,直到安裝指南#關於 initramfs。可以跳過安裝指南#生成 fstab 文件步驟。

Initramfs[編輯 | 編輯原始碼]

要構建可用的基於systemd的initramfs,修改mkinitcpio.conf中的HOOKS=行:

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

接下來配置需Unified kernel image,詳見Unified kernel image#mkinitcpio

由於/efi/EFI/Linux文件夾需在引導加載程序的安裝過程中創建,此時不要重新生成initramfs。

引導加載程序[編輯 | 編輯原始碼]

通過以下命令安裝systemd-boot

# bootctl install

由mkinitcpio創建的Unified kernel image會被自動識別,故無需手動配置/efi/loader/entries

詳見systemd-boot#更新 EFI 啟動管理器systemd-boot#啟動選單配置

完成安裝[編輯 | 編輯原始碼]

首先,[[mkinitcpio#創建和啟用鏡像|重新生成initramfs],確保鏡像成功生成。

確保設置了root密碼重啟以完成安裝。

安全啟動[編輯 | 編輯原始碼]

若要啟用安全啟動,應對引導加載程序和EFI二進位文件進行簽名。Unified Extensible Firmware Interface/Secure Boot#Assisted process with sbctl提供了一種簡單快捷的方法。

使用TPM[編輯 | 編輯原始碼]

在對引導加載程序進行簽名並啟用安全啟動後,可使用TPM來解密LUKS卷。下列命令將移除在格式化LUKS卷時使用的空密碼,並創建綁定到TPM PCR 7(默認,UEFI/安全啟動#安全啟動狀態)的密鑰。此外,還將創建恢復密鑰以在需要時使用。只要啟動鏈未被非法修改,TPM將自動釋放密鑰。詳見Trusted Platform Module#systemd-cryptenrollsystemd-cryptenroll(1)

# systemd-cryptenroll /dev/sda2 --recovery-key
# systemd-cryptenroll /dev/sda2 --wipe-slot=empty --tpm2-device=auto