dm-crypt

设备映射器(Device-Mapper)的“crypt”目标通过内核加密 API 提供块设备的透明加密。

有关支持参数的更详细说明,请参阅:https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt

参数

<cipher> <key> <iv_offset> <device path> \
<offset> [<#opt_params> <opt_params>]
<cipher>

加密算法、加密模式和初始向量 (IV) 生成器。

加密算法规范格式为

cipher[:keycount]-chainmode-ivmode[:ivopts]

示例

aes-cbc-essiv:sha256
aes-xts-plain64
serpent-xts-plain64

加密算法格式也支持直接使用内核加密 API 格式进行指定(通过 capi: 前缀选择)。IV 规范与第一种格式类型相同。此格式主要用于指定认证模式。

加密 API 算法规范格式为

capi:cipher_api_spec-ivmode[:ivopts]

示例

capi:cbc(aes)-essiv:sha256
capi:xts(aes)-plain64

认证模式示例

capi:gcm(aes)-random
capi:authenc(hmac(sha256),xts(aes))-random
capi:rfc7539(chacha20,poly1305)-random

/proc/crypto 包含当前已加载的加密模式列表。

<key>

用于加密的密钥。它编码为十六进制数字,或者对于驻留在内核密钥环服务中的密钥,可以作为以单个冒号字符(‘:’)为前缀的 <key_string> 传递。您只能使用与所选算法和 IV 模式组合有效的密钥大小。请注意,对于某些 IV 模式,密钥字符串可以包含额外的密钥(例如 IV 种子),因此密钥包含多个连接成单个字符串的部分。

<key_string>

内核密钥环密钥由以下格式的字符串标识:<key_size>:<key_type>:<key_description>。

<key_size>

加密密钥大小(以字节为单位)。内核密钥负载大小必须与传递给 <key_size> 的值匹配。

<key_type>

可以是“logon”、“user”、“encrypted”或“trusted”内核密钥类型。

<key_description>

dm-crypt 目标在加载 <key_type> 类型的密钥时应查找的内核密钥环密钥描述。

<keycount>

多密钥兼容模式。您可以定义 <keycount> 个密钥,然后扇区根据其偏移量进行加密(扇区 0 使用 key0;扇区 1 使用 key1 等)。<keycount> 必须是 2 的幂。

<iv_offset>

IV 偏移量是在创建 IV 之前添加到扇区号的扇区计数。

<device path>

这是将用作后端并包含加密数据的设备。您可以将其指定为路径(如 /dev/xxx)或设备号 <major>:<minor>。

<offset>

设备内加密数据开始的起始扇区。

<#opt_params>

可选参数的数量。如果没有可选参数,则可以跳过可选参数部分,或者将 #opt_params 设置为零。否则,#opt_params 是后面参数的数量。

可选参数部分示例

3 allow_discards same_cpu_crypt submit_from_crypt_cpus

allow_discards

块丢弃请求(即 TRIM)通过加密设备传递。默认是忽略丢弃请求。

警告:在启用此选项之前,请仔细评估具体的安全风险。例如,如果丢弃的块以后可以很容易地在设备上定位,则允许在加密设备上丢弃可能会导致有关密文设备的信息泄露(文件系统类型、已用空间等)。

same_cpu_crypt

使用提交 IO 的同一个 CPU 执行加密。默认是使用无绑定工作队列,以便在可用 CPU 之间自动平衡加密工作。

high_priority

将 dm-crypt 工作队列和写入线程设置为高优先级。这可以提高 dm-crypt 的吞吐量和延迟,同时降低系统的整体响应速度。

submit_from_crypt_cpus

禁用加密后将写入操作卸载到单独的线程。在某些情况下,将写入生物(bios)从加密线程卸载到单个线程会显著降低性能。默认是将写入生物卸载到同一个线程,因为这有助于 CFQ 在使用相同上下文提交写入时受益。

no_read_workqueue

绕过 dm-crypt 内部工作队列并同步处理读取请求。

no_write_workqueue

绕过 dm-crypt 内部工作队列并同步处理写入请求。对于主机管理的区域块设备(例如,主机管理的 SMR 硬盘),此选项会自动启用。

integrity:<bytes>:<type>

设备需要每个扇区额外的 <bytes> 元数据,存储在每个生物的完整性结构中。此元数据必须由底层的 dm-integrity 目标提供。

如果元数据仅用于持久 IV,则 <type> 可以是“none”。

对于带有附加数据(AEAD)的认证加密,<type> 是“aead”。AEAD 模式额外计算并验证加密设备的完整性。额外的空间用于存储认证标签(如果需要,还存储持久 IV)。

integrity_key_size:<bytes>

如果完整性密钥大小与摘要大小不同,则可选设置完整性密钥大小。它允许使用密钥大小独立于加密密钥大小的封装密钥算法。

sector_size:<bytes>

使用 <bytes> 作为加密单元,而不是 512 字节扇区。此选项的范围可以在 512 - 4096 字节之间,并且必须是 2 的幂。虚拟设备将宣布此大小为最小 I/O 和逻辑扇区。

iv_large_sectors

IV 生成器将使用以 <sector_size> 单元(而不是默认的 512 字节扇区)计数的扇区号。

例如,如果 <sector_size> 是 4096 字节,则第二个扇区的 plain64 IV 将是 8(不带此标志),如果存在 iv_large_sectors 则为 1。如果指定此标志,<iv_offset> 必须是 <sector_size> 的倍数(以 512 字节为单位)。

integrity_key_size:<bytes>

使用 <bytes> 大小的完整性密钥,而不是使用所用 HMAC 算法摘要大小的完整性密钥大小。

模块参数:
max_read_size

读取请求的最大大小。当接收到大于此大小的请求时,dm-crypt 将拆分请求。拆分可以提高并发性(拆分的请求可以由多个核心并行加密),但也会导致开销。用户应调整此参数以适应实际工作负载。

max_write_size

写入请求的最大大小。当接收到大于此大小的请求时,dm-crypt 将拆分请求。拆分可以提高并发性(拆分的请求可以由多个核心并行加密),但也会导致开销。用户应调整此参数以适应实际工作负载。

示例脚本

LUKS (Linux Unified Key Setup) 现在是使用“cryptsetup”实用程序设置 dm-crypt 磁盘加密的首选方式,请参阅 https://gitlab.com/cryptsetup/cryptsetup

#!/bin/sh
# Create a crypt device using dmsetup
dmsetup create crypt1 --table "0 `blockdev --getsz $1` crypt aes-cbc-essiv:sha256 babebabebabebabebabebabebabebabe 0 $1 0"
#!/bin/sh
# Create a crypt device using dmsetup when encryption key is stored in keyring service
dmsetup create crypt2 --table "0 `blockdev --getsize $1` crypt aes-cbc-essiv:sha256 :32:logon:my_prefix:my_key 0 $1 0"
#!/bin/sh
# Create a crypt device using cryptsetup and LUKS header with default cipher
cryptsetup luksFormat $1
cryptsetup luksOpen $1 crypt1