Dm-crypt

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Dm-crypt and the translation is 87% complete.
Outdated translations are marked like this.
Other languages:


Resources

dm-crypt 是使用内核加密API框架和设备映射器(device mapper)子系统的磁盘加密系统。使用dm-crypt,管理员可以加密整个磁盘,逻辑卷,分区以及单个文件。

dm-crypt子系统支持Linux Unified Key Setup (LUKS)结构,允许多个密钥访问加密数据,以及操作密钥(例如更改密钥,添加额外的密码等)。尽管dm-crypt也支持非LUKS,本文将重点关注LUKS功能,主要是因为它的灵活性,可管理性以及社区中的广泛支持。

配置

在开始使用dm-crypt之前有两个先决条件:

  1. 配置Linux内核
  2. 安装 sys-fs/cryptsetup

内核配置

要使用dm-crypt,有一些必要的配置条目。

首先,必须包括对device mapper基础结构以及'crypt target 的支持:

内核 Enabling device mapper and crypt target
[*] Enable loadable module support
Device Drivers --->
    [*] Multiple devices driver support (RAID and LVM) --->
        <*> Device mapper support
        <*>   Crypt target support

接下来,Linux内核需要支持管理员想要用于加密的一组加密API。这些可以在Cryptographic API部分找到:

内核 Enabling cryptographic API functions
[*] Cryptographic API --->
    <*> XTS support
    <*> SHA224 and SHA256 digest algorithm
    <*> AES cipher algorithms
    <*> AES cipher algorithms (x86_64)
    <*> User-space interface for hash algorithms
    <*> User-space interface for symmetric key cipher algorithms

如果根文件系统也要被加密,则需要创建初始ram文件系统,其中根文件系统在挂载之前被解密。 因此,这也需要initramfs支持:

内核 Enabling initramfs support
General setup  --->
    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support

如果使用tcrypt加密选项(TrueCrypt/tcplay/VeraCrypt兼容模式),则还需要将以下项目添加到内核中。否则,cryptsetup将返回以下错误:"device-mapper: reload ioctl failed: Invalid argument" 和 "Kernel doesn't support TCRYPT compatible mapping"。

内核 Enabling tcrypt (TrueCrypt/tcplay/VeraCrypt compatibility mode) support
Device Drivers --->
    [*] Block Devices ---> 
        <*> Loopback device support 
File systems ---> 
     <*> FUSE (Filesystem in Userspace) support 
[*] Cryptographic API ---> 
     <*> RIPEMD-160 digest algorithm 
     <*> SHA384 and SHA512 digest algorithms 
     <*> Whirlpool digest algorithms 
     <*> LRW support 
     <*> Serpent cipher algorithm 
     <*> Twofish cipher algorithm

安装 Cryptsetup

sys-fs/cryptsetup包提供cryptsetup命令,该命令用于打开或关闭加密存储以及管理与之关联的密码或密钥。

root #emerge --ask sys-fs/cryptsetup

加密存储

Benchmark

cryptsetup provides a benchmarking tool which will help to decide which setup to choose. The output depends on kernel settings as well as USE flags and destination (HDD, SSD etc.).

root #cryptsetup benchmark
# Tests are approximate using memory only (no storage IO).
PBKDF2-sha1      1707778 iterations per second for 256-bit key
PBKDF2-sha256    2131252 iterations per second for 256-bit key
PBKDF2-sha512    1630755 iterations per second for 256-bit key
PBKDF2-ripemd160  882639 iterations per second for 256-bit key
PBKDF2-whirlpool  664496 iterations per second for 256-bit key
argon2i       9 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
argon2id      9 iterations, 1048576 memory, 4 parallel threads (CPUs) for 256-bit key (requested 2000 ms time)
#     Algorithm |       Key |      Encryption |      Decryption
        aes-cbc        128b      1197.2 MiB/s      3788.1 MiB/s
    serpent-cbc        128b               N/A               N/A
    twofish-cbc        128b               N/A               N/A
        aes-cbc        256b       888.2 MiB/s      3011.1 MiB/s
    serpent-cbc        256b               N/A               N/A
    twofish-cbc        256b               N/A               N/A
        aes-xts        256b      3670.7 MiB/s      3708.4 MiB/s
    serpent-xts        256b               N/A               N/A
    twofish-xts        256b               N/A               N/A
        aes-xts        512b      2929.2 MiB/s      2974.0 MiB/s
    serpent-xts        512b               N/A               N/A
    twofish-xts        512b               N/A               N/A

密钥文件或密码

为了开始加密存储,管理员需要决定使用哪种方法作为加密密钥。cryptsetup支持使用密码或密钥文件。对于密钥文件,这可以是任何文件,但建议使用具有适当保护的随机数据的文件(考虑到访问此密钥文件将意味着访问加密数据)。

要创建密钥文件,可以使用dd命令:

root #dd if=/dev/urandom of=/etc/keys/enc.key bs=1 count=4096

在接下来的部分中,我们将显示两种情况的每个命令 - 密码和密钥文件。当然,只需要其中一种方法。

创建加密存储平台

要创建加密存储平台(可以是磁盘,分区,文件......),请使用cryptsetup命令和luksFormat操作。

例如,要将 /dev/vdb2作为加密数据的存储介质:

root #cryptsetup -c aes-xts-plain64 -s 512 -y luksFormat /dev/vdb2
This will overwrite data on /dev/vdb2 irrevocably.
  
Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: ...
Verify passphrase: ...

要使用密钥文件而不是密码:

root #cryptsetup -c aes-xts-plain64 -s 512 -y luksFormat /dev/vdb2 /etc/keys/enc.key
This will overwrite data on /dev/vdb2 irrevocably.
  
Are you sure? (Type uppercase yes): YES

-s 512告诉cryptsetup用于真实加密密钥的密钥长度(与密码或密钥文件不同,这是用于真实加密密钥的)。

重要
If the LUKS header gets damaged, your encrypted data will be lost forever, even if you have a backup of the GPG key and passphrase. Therefore, you may wish to consider backing up this header to a separate device, and storing it securely. See the LUKS FAQ for more details on how to do this.
root #cryptsetup luksHeaderBackup /dev/sdXn --header-backup-file /tmp/efiboot/luks-header.img
Be aware, that if you do keep a LUKS header backup in this fashion and subsequently revoke any of the keyslots, the old keys will still be usable to unlock the LUKS partition for those with an access to that header backup file.

Full disk encryption booting

To boot from a fully encrypted device (including encrypted /boot) using GRUB, encrypt using luks1, since luks2 isn't fully supported yet. Example command:

root #cryptsetup -c aes-xts-plain64 -s 512 -y luksFormat --type luks1 /dev/vdb2

打开加密存储

为了打开加密存储(即通过透明解密使真实数据可访问),请使用luksOpen操作。

root #cryptsetup luksOpen /dev/vdb2 myname
Enter passphrase for /dev/vdb2: ...

如果使用了密钥文件,那么命令将如下所示:

root #cryptsetup luksOpen -d /etc/keys/enc.key /dev/vdb2 myname

命令成功完成后,名为/dev/mapper/myname的新设备文件将可用。

如果这是第一次使用此加密设备,则需要对其进行格式化。以下示例使用Btrfs文件系统,但当然任何其他文件系统都可以:

root #mkfs.btrfs /dev/mapper/myname

格式化文件系统或过去已完成格式化后,可以在系统上挂载这个设备文件:

root #mount /dev/mapper/myname /home

关闭加密存储

为了关闭加密存储(即确保不再通过透明解密访问实际数据),请使用luksClose操作:

root #cryptsetup luksClose myname

当然,请确保设备不再使用。

操作 LUKS 密钥

LUKS密钥用于访问真正的加密密钥。它们存储在(加密)分区,磁盘或文件的标头中的插槽中。

列出插槽

使用luksDump操作,可以显示有关加密分区,磁盘或文件的信息。这包括插槽:

root #cryptsetup luksDump /dev/vdb2
LUKS header information for /dev/vdb2
  
Version:        1
Cipher name:    aes
Cipher mode:    xts-plain64
Hash spec:      sha1
Payload offset: 4096
MK bits:        512
MK digest:      34 3b ec ac 10 af 19 e7 e2 d4 c8 90 eb a8 da 3c e4 4f 2e ce
MK salt:        ff 7c 7f 53 db 53 48 02 a4 32 dc e0 22 fc a3 51
                06 ba b3 48 b3 28 13 a8 7a 68 43 d6 46 79 14 fe
MK iterations:  59375
UUID:           2921a7c9-7ccb-4300-92f4-38160804e08c
  
Key Slot 0: ENABLED
        Iterations:             241053
        Salt:                   90 0f 0f db cf 66 ea a9 6c 7c 0c 0d b0 28 05 2f
                                8a 5c 14 54 98 62 1a 29 f3 08 25 0c ec c2 b1 68
        Key material offset:    8
        AF stripes:             4000
Key Slot 1: ENABLED
        Iterations:             273211
        Salt:                   01 4c 26 ed ff 18 75 31 b9 89 5d a6 e0 b5 f4 14
                                48 d0 23 47 a9 85 78 fb 76 c4 a9 d0 cd 63 fb d7
        Key material offset:    512
        AF stripes:             4000
Key Slot 2: DISABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

在上面的例子中,使用了两个插槽。请注意,luksDump不会泄露任何敏感内容 - 它只是显示LUKS标头内容。不需要提供解密密钥来调用luksDump

添加一个密钥文件或密码

要添加其他密钥文件或密码来访问加密存储,请使用luksAddKey操作:

root #cryptsetup luksAddKey /dev/vdb2
Enter any passphrase: (Enter a valid, previously used passphrase to unlock the key)
Enter new passphrase for key slot: ... 
Verify passphrase: ...

要使用密钥文件解锁密钥(但仍然需要密码):

root #cryptsetup luksAddKey -d /etc/keys/enc.key /dev/vdb2
Enter new passphrase for key slot: ...
Verify passphrase: '''

如果要添加密钥文件(例如/etc/keys/backup.key):

root #cryptsetup luksAddKey /dev/vdb2 /etc/keys/backup.key

或者,使用第一个密钥文件解锁主密钥:

root #cryptsetup luksAddKey -d /etc/keys/enc.key /dev/vdb2 /etc/keys/backup.key

删除一个密钥文件或密码

使用luksRemoveKey操作,可以删除密钥文件或密码(因此它们不能再用于解密存储):

root #cryptsetup luksRemoveKey /dev/vdb2
Enter LUKS passphrase to be deleted: ...

或者删除密钥文件:

root #cryptsetup luksRemoveKey -d /etc/keys/backup.key /dev/vdb2

确保至少有一种访问数据的方法仍然可用。一旦使用的密码或密钥文件被删除,就无法再次恢复。

清空一个插槽

Suppose the passphrase or keyfile is no longer known, then the slot can be freed. Of course, this does require prior knowledge of which slot that the passphrase or keyfile was stored in. 假设密码或密钥文件已遗失,则可以释放插槽。当然,这需要事先知道密码或密钥文件存储在哪个插槽中。

例如,要清空插槽2(这是第3个插槽,因为插槽从0开始编号):

root #cryptsetup luksKillSlot /dev/vdb2 2

此命令将在继续之前要求输入有效的密码。或者可以传递密钥文件以使用:

root #cryptsetup luksKillSlot -d /etc/keys/enc.key /dev/vdb2 2

自动挂载加密文件系统

到目前为止,本文主要关注加密文件系统的手动设置和挂载/卸载。存在一个init服务dmcrypt,它自动解密和挂载加密文件系统。

配置 dm-crypt

编辑/etc/conf.d/dmcrypt文件并为每个文件系统添加条目。支持的条目在文件中有详细记录,下面的示例只是 - 示例:

文件 /etc/conf.d/dmcryptAutomatically enabling two encrypted file systems
# Definition for /dev/mapper/home (for /home)
target=home
source=UUID="abcdef12-321a-a324-a88c-cac412befd98"
key=/etc/keys/home.key
 
# Definition for /dev/mapper/local (for /usr/local)
target=local
source=UUID="fedcba34-4823-b423-a94c-cadbefda2943"
key=/etc/keys/local.key

配置fstab

下一步是将/etc/fstab配置为,在(解密的)文件系统可用时自动挂载。建议首先获取解密(已挂载)文件系统的UUID:

root #blkid /dev/mapper/home
/dev/mapper/home: UUID="4321421a-4321-a6c9-de52-ba6421efab76" TYPE="ext4"

然后,相应的更新/etc/fstab文件。

文件 /etc/fstabAutomounting the decrypted file systems
UUID="4321421a-4321-a6c9-de52-ba6421efab76"   /home        ext4   defaults   0   0
UUID="bdef2432-3bd1-4ab4-523d-badcf234a342"   /usr/local   ext4   defaults   0   0

将initscript添加到bootlevel

不要忘记在boot启动时启动dmcrypt init服务:

root #rc-update add dmcrypt boot


Make decrypted device nodes visible

If you have decrypted/unlocked a device before the services were started for example your root disk in an with an initramfs then it's possible that the mapped device is not visible. In this case you can run the following to recreate it.

root #dmsetup mknodes

挂载 TrueCrypt/tcplay/VeraCrypt 卷

root #cryptsetup --type tcrypt open container-to-mount container-name

使用/dev的设备文件或要打开的文件的路径替换container-to-mount。成功打开后,明文设备将显示为/dev/mapper/container-name,您可以像任何普通设备一样mount

如果您使用的是密钥文件,请使用--key-file选项。打开隐藏卷,使用--tcrypt-hidden选项。对于在系统模式下加密的分区或整个驱动器,请使用--tcrypt-system选项。

完成后,unmount(卸载)卷,然后使用以下命令关闭容器:

root #cryptsetup close container-name

另请参阅

外部资源

  • The cryptsetup FAQ hosted on GitLab covers a wide range of frequently asked questions.