18.14. 使用基于策略的解密配置加密卷的自动解锁
基于策略的解密(PBD)是技术的一种集合,可在物理和虚拟上解锁加密的根和硬盘的辅助卷。PBD 使用各种解锁方法,如用户密码、受信任的平台模块(TPM)设备、连接到系统的 PKCS #11 设备,如智能卡或特殊的网络服务器。
PBD 允许将不同的解锁方法合并成一个策略,从而可以以不同的方式解锁同一个卷。RHEL 中 PBD 的当前实现由 Clevis 框架和称为 pins 的插件组成。每个 pin 都提供单独的解锁功能。目前,可提供以下 pins :
tang
- 允许使用网络服务器解锁卷。
tpm2
- 允许使用 TPM2 策略解锁卷。
sss
- 允许使用 Shamir 的 Secret 共享(SSS)加密方案部署高可用性系统。
18.14.1. 网络绑定磁盘加密
网络绑定加密 (NBDE) 是基于策略的解密 (PBD) 的子类别,允许将加密的卷绑定到特殊的网络服务器。NBDE 的当前实现包括 Tang 服务器的 Clevis pin 和 Tang 服务器本身。
在 RHEL 中,NBDE 通过以下组件和技术实现:
图 18.1. 使用 LUKS1 加密的卷时的 NBDE 方案。luksmeta 软件包不用于 LUKS2 卷。

Tang 是一个将数据绑定到网络状态的服务器。当系统绑定到某个安全网络时,它会使包含数据的系统变得可用。Tang 是无状态的,不需要 TLS 或身份验证。与基于 escrow 的解决方案不同,服务器存储所有加密密钥并了解以前使用的每个密钥,Tang 从不与任何客户端密钥进行交互,因此不会从客户端获得任何识别信息。
Clevis 是一个自动化解密的可插拔框架。在 NBDE 中,Clevis 提供 LUKS 卷的自动解锁。clevis
软件包提供了该功能的客户端。
Clevis pin 是 Clevis 框架的一个插件。其中一个 pins 是实现与 NBDE 服务器进行交互的插件 - Tang。
Clevis 和 Tang 是通用的客户端和服务器组件,提供网络绑定加密。在 RHEL 中,它们与 LUKS 一起使用,以加密和解密 root 和非 root 存储卷,以完成网络绑定磁盘加密。
客户端和服务器端组件都使用 José 库来执行加密和解密操作。
当您开始调配 NBDE 时,Tang 服务器的 Clevis pin 将获得 Tang 服务器发布的非对称密钥的列表。或者,由于密钥是非对称的,因此 Tang 的公钥列表可以分发到带外,以便客户端能够在不访问 Tang 服务器的情况下进行操作。此模式称为 脱机调配。
Tang 的 Clevis pin 使用其中一个公钥来生成唯一的强加密的加密密钥。使用此密钥加密数据后,密钥将被丢弃。Clevis 客户端应将此调配操作生成的状态存储在方便的位置。这种加密数据的过程就是 调配步骤。
LUKS 版本 2(LUKS2)是 RHEL 中的默认磁盘加密格式,因此 NBDE 的调配状态作为令牌存储在 LUKS2 标头中。luksmeta
软件包对 NBDE 的调配状态的利用仅用于使用 LUKS1 加密的卷。
Tang 的 Clevis pin 支持 LUKS1 和 LUKS2,不需要规范。Clevis 可以加密纯文本文件,但您必须使用 cryptsetup
工具加密块设备。如需更多信息,请参阅使用 LUKS 加密块设备。
当客户端准备好访问其数据时,它会加载再调配步骤中生成的元数据,并响应恢复加密密钥。此过程是 恢复步骤。
在 NBDE 中,Clevis 使用 pin 绑定 LUKS 卷,以便能自动解锁它。成功完成绑定流程后,可以使用提供的 Dracut 解锁程序解锁磁盘。
如果将 kdump
内核崩溃转储机制设置为将系统内存的内容保存到 LUKS 加密的设备中,则会在第二次内核引导时提示您输入密码。
其它资源
- NBDE (网络绑定磁盘加密)技术知识库文章
-
tang (8)
,clevis (1)
,jose (1)
, jose (1), 和clevis-luks-unlockers (7)
man page - 如何设置多个 LUKS 设备(Clevis + Tang 解锁)的网络绑定磁盘加密 知识库文章
18.14.2. 部署 SELinux 处于 enforcing 模式的 Tang 服务器
您可以使用 Tang 服务器在启用了 Clevis 的客户端上自动解锁 LUKS 加密的卷。在最简单的场景中,您可以通过安装 tang
软件包,并输入 systemctl enable tangd.socket --now
命令将 Tang 服务器部署在端口 80 上。以下示例流程演示了将运行在自定义端口上的 Tang 服务器部署为 SELinux enforcing 模式下受限制的服务。
先决条件
-
policycoreutils-python-utils
包及其依赖项已经安装。 -
firewalld
服务在运行。
流程
要安装
tang
软件包及其依赖项,请以root
用户身份输入以下命令:# yum install tang
选择一个未被占用的端口,例如 7500/tcp,并允许
tangd
服务绑定到该端口:# semanage port -a -t tangd_port_t -p tcp 7500
请注意,一个端口一次只能被一个服务使用,因此试图使用已占用的端口意味着
ValueError:端口已定义
错误消息。在防火墙中打开端口:
# firewall-cmd --add-port=7500/tcp # firewall-cmd --runtime-to-permanent
启用
tangd
服务:# systemctl enable tangd.socket
创建覆盖文件:
# systemctl edit tangd.socket
在以下编辑器屏幕中,其打开了位于
/etc/systemd/system/tangd.socket.d/
目录中的一个空override.conf
文件,通过添加以下行将 Tang 服务器的默认端口从 80 改为之前选择的端口号:[Socket] ListenStream= ListenStream=7500
重要在以
# Anything between here
和# Lines below this
开头的行之间插入之前的代码片段,否则系统会丢弃您的更改。- 按 Ctrl+O ,并按 Enter 保存更改。按 Ctrl+X 退出编辑器。
重新载入更改的配置:
# systemctl daemon-reload
检查您的配置是否正常工作:
# systemctl show tangd.socket -p Listen Listen=[::]:7500 (Stream)
启动
tangd
服务:# systemctl restart tangd.socket
由于
tangd
使用了systemd
套接字激活机制,因此服务器会在第一次连接进来时就立即启动。在第一次启动时会自动生成一组新的加密密钥。要执行手动生成密钥等加密操作,请使用jose
工具。
验证
在您的 NBDE 客户端上,使用以下命令验证您的 Tang 服务器是否正常工作。该命令必须返回您传递的与加密和解密相同的消息:
# echo test | clevis encrypt tang '{"url":"<tang.server.example.com:7500>"}' -y | clevis decrypt test
其它资源
-
tang (8)
,semanage (8)
,firewall-cmd (1)
,jose (1)
,systemd.unit (5)
, 和systemd.socket (5)
man page
18.14.3. 轮转 Tang 服务器密钥并更新客户端上的绑定
为安全起见,轮转 Tang 服务器密钥,并定期更新客户端上的现有绑定。轮转它们的确切间隔取决于您的应用程序、密钥大小以及机构策略。
或者,您可以使用 nbde_server
RHEL 系统角色来轮转 Tang 密钥。如需更多信息,请参阅 使用 nbde_server 系统角色来设置多个 Tang 服务器。
先决条件
- Tang 服务器在运行。
-
clevis
和clevis-luks
软件包已安装在您的客户端上。 -
请注意,RHEL 8.2 中已引入了
clevis luks list
、clevis luks report
和clevis luks regen
。
流程
重命名
/var/db/tang
密钥数据库目录中的所有密钥,使其前面有一个.
,将它们隐藏起来,以防被看到。请注意,以下示例中的文件名与 Tang 服务器的密钥数据库目录中的独特文件名不同:# cd /var/db/tang # ls -l -rw-r--r--. 1 root root 349 Feb 7 14:55 UV6dqXSwe1bRKG3KbJmdiR020hY.jwk -rw-r--r--. 1 root root 354 Feb 7 14:55 y9hxLTQSiSB5jSEGWnjhY8fDTJU.jwk # mv UV6dqXSwe1bRKG3KbJmdiR020hY.jwk .UV6dqXSwe1bRKG3KbJmdiR020hY.jwk # mv y9hxLTQSiSB5jSEGWnjhY8fDTJU.jwk .y9hxLTQSiSB5jSEGWnjhY8fDTJU.jwk
检查是否重命名了,是否隐藏了 Tang 服务器中的所有密钥:
# ls -l total 0
使用
/usr/libexec/tangd-keygen
命令,在Tang 服务器上的/var/db/tang
中生成新的密钥:# /usr/libexec/tangd-keygen /var/db/tang # ls /var/db/tang 3ZWS6-cDrCG61UPJS2BMmPU4I54.jwk zyLuX6hijUy_PSeUEFDi7hi38.jwk
检查您的 Tang 服务器是否可以显示新密钥对的签名密钥,例如:
# tang-show-keys 7500 3ZWS6-cDrCG61UPJS2BMmPU4I54
在 NBDE 客户端上,使用
clevis luks report
命令检查 Tang 服务器显示的密钥是否保持不变。您可以使用clevis luks list
命令识别带有相关绑定的插槽,例如:# clevis luks list -d /dev/sda2 1: tang '{"url":"http://tang.srv"}' # clevis luks report -d /dev/sda2 -s 1 ... Report detected that some keys were rotated. Do you want to regenerate luks metadata with "clevis luks regen -d /dev/sda2 -s 1"? [ynYN]
要为新密钥重新生成 LUKS 元数据,在上一个命令提示时按
y
,或使用clevis luks regen
命令:# clevis luks regen -d /dev/sda2 -s 1
当您确定所有旧客户端都使用新密钥时,您可以从 Tang 服务器中删除旧密钥,例如:
# cd /var/db/tang # rm .*.jwk
在客户端仍在使用旧密钥时删除旧密钥可能会导致数据丢失。如果您意外删除了这些密钥,请在客户端上使用 clevis luks regen
命令,并手动提供您的 LUKS 密码。
其它资源
-
tang-show-keys (
1)、clevis-luks-list (
1)、clevis-luks-report (1)
和您系统上的clevis-luks-regen (1)
手册页
18.14.4. 在 web 控制台中使用 Tang 密钥配置自动解锁
您可以使用 Tang 服务器提供的密钥配置 LUKS 加密存储设备的自动解锁。
先决条件
已安装 RHEL 8 web 控制台。
具体步骤请参阅安装并启用 Web 控制台。
-
cockpit-storaged
和clevis-luks
软件包已安装在您的系统上。 -
cockpit.socket
服务运行在9090端口。 - Tang 服务器可用。详情请参阅 部署 SELinux 处于 enforcing 模式的 Tang 服务器。
-
您有
root
权限或使用sudo
输入管理命令的权限。
流程
登录到 RHEL 8 web 控制台。
详情请参阅 登录到 web 控制台。
- 切换到管理访问权限,提供您的凭据,然后单击 Storage 表中,点包含您计划添加的加密卷的磁盘,来自动解锁。 。在
在以下带有所选磁盘详情的页面中,点 Keys 部分中的 来添加 Tang 密钥:
选择
Tang keyserver
作为Key source
,提供 Tang 服务器的地址,以及解锁 LUKS 加密设备的密码。点击 确认:以下对话框窗口提供了一个命令来验证密钥哈希是否匹配。
在 Tang 服务器上的终端中,使用
tang-show-keys
命令来显示密钥哈希以进行比较。在本例中,Tang 服务器运行在端口 7500 上:# tang-show-keys 7500 x100_1k6GPiDOaMlL3WbpCjHOy9ul1bSfdhI3M08wO0
当 web 控制台中的密钥哈希与之前列出的命令的输出中的密钥哈希相同时,请点击
:-
在 RHEL 8.8 及更高版本中,选择加密的根文件系统和 Tang 服务器后,您可以跳过在内核命令行中添加
rd.neednet=1
参数,安装clevis-dracut
软件包,以及重新生成一个初始 RAM 磁盘(initrd
)。对于非 root 文件系统,web 控制台现在启用remote-cryptsetup.target
和clevis-luks-akspass.path
systemd
单元,安装clevis-systemd
软件包,并将_netdev
参数添加到fstab
和crypttab
配置文件中。
验证
检查新添加的 Tang 密钥现在是否在 Keys 部分中列出,且类型为
Keyserver
:验证绑定是否在早期引导时可用,例如:
# lsinitrd | grep clevis-luks lrwxrwxrwx 1 root root 48 Jan 4 02:56 etc/systemd/system/cryptsetup.target.wants/clevis-luks-askpass.path -> /usr/lib/systemd/system/clevis-luks-askpass.path …
其它资源
18.14.5. 基本 NBDE 和 TPM2 加密客户端操作
Clevis 框架可以加密纯文本文件,并使用 JSON Web 加密(JWE)格式和 LUKS 加密块设备解密这两个密码文本。Clevis 客户端可以使用 Tang 网络服务器或受信任的平台模块 2.0(TPM 2.0)芯片进行加密操作。
以下命令在包含纯文本文件的示例上演示 Clevis 提供的基本功能。您还可以使用它们来对 NBDE 或 Clevis+TPM 部署进行故障排除。
绑定到 Tang 服务器的加密客户端
要检查 Clevis 加密客户端是否绑定到 Tang 服务器,请使用
clevis encrypt tang
子命令:$ clevis encrypt tang '{"url":"http://tang.srv:port"}' < input-plain.txt > secret.jwe The advertisement contains the following signing keys: _OsIk0T-E2l6qjfdDiwVmidoZjA Do you wish to trust these keys? [ynYN] y
更改上例中的
http://tang.srv:port
URL,使其与安装了tang
的服务器的 URL 匹配。secret.jwe
输出文件包含您的加密密码文本,格式为 JWE。这个密码文本是从input-plain.txt
输入文件中读取的。另外,如果您的配置需要与 Tang 服务器进行非互动通信而无需 SSH 访问,您可以下载公告并将其保存到文件中:
$ curl -sfg http://tang.srv:port/adv -o adv.jws
将
adv.jws
文件中的公告用于任何以下任务,如文件或消息的加密:$ echo 'hello' | clevis encrypt tang '{"url":"http://tang.srv:port","adv":"adv.jws"}'
要解密数据,请使用
clevis decrypt
命令,并提供密码文本(JWE):$ clevis decrypt < secret.jwe > output-plain.txt
使用 TPM 2.0 加密客户端
要使用 TPM 2.0 芯片加密,请使用
clevis encrypt tpm2
子命令以及 JSON 配置对象的唯一参数:$ clevis encrypt tpm2 '{}' < input-plain.txt > secret.jwe
要选择不同的层次结构、哈希和密钥算法,请指定配置属性,例如:
$ clevis encrypt tpm2 '{"hash":"sha256","key":"rsa"}' < input-plain.txt > secret.jwe
要解密数据,请提供 JSON Web 加密(JWE)格式的密码文本:
$ clevis decrypt < secret.jwe > output-plain.txt
pin 还支持将数据封装到平台配置寄存器(PCR)状态。这样,只有 PCR 哈希值与密封时使用的策略匹配,数据才能被取消密封。
例如,对于 SHA-256 块要将数据密封到索引为 0 和 7 的 PCR:
$ clevis encrypt tpm2 '{"pcr_bank":"sha256","pcr_ids":"0,7"}' < input-plain.txt > secret.jwe
可以重写 PCR 中的哈希值,您无法再解锁加密的卷。因此,添加了一个强大的密码短语,以便您手动解锁加密的卷,即使 PCR 中的值有变化也是如此。
如果在升级 shim-x64
软件包后系统无法自动解锁加密的卷,请参阅红帽知识库解决方案 Clevis TPM2 不再重启后解密 LUKS 设备。
其它资源
-
clevis-encrypt-tang (
1)、clevis-luks-unlockers (
7)、clevis (1)
和clevis-encrypt-tpm2 (1)
手册页 不带任何参数的
clevis
、clevis decrypt
和clevis encrypt tang
命令会显示内置 CLI 帮助信息,例如:$ clevis encrypt tang Usage: clevis encrypt tang CONFIG < PLAINTEXT > JWE ...
18.14.6. 配置 NBDE 客户端以自动解锁 LUKS 加密卷
使用 Clevis 框架,您可以在所选的 Tang 服务器可用时配置客户端来自动解锁 LUKS 加密卷。这创建一个 NBDE (网络绑定磁盘加密)部署。
先决条件
- Tang 服务器正在运行且可用。
流程
要自动解锁现有的 LUKS 加密卷,请安装
clevis-luks
子软件包:# yum install clevis-luks
识别 PBD 的 LUKS 加密卷。在以下示例中,块设备是指 /dev/sda2 :
# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 12G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 11G 0 part └─luks-40e20552-2ade-4954-9d56-565aa7994fb6 253:0 0 11G 0 crypt ├─rhel-root 253:0 0 9.8G 0 lvm / └─rhel-swap 253:1 0 1.2G 0 lvm [SWAP]
使用
clevis luks bind
命令将卷绑定到 Tang 服务器:# clevis luks bind -d /dev/sda2 tang '{"url":"http://tang.srv"}' The advertisement contains the following signing keys: _OsIk0T-E2l6qjfdDiwVmidoZjA Do you wish to trust these keys? [ynYN] y You are about to initialize a LUKS device for metadata storage. Attempting to initialize it may result in data loss if data was already written into the LUKS header gap in a different format. A backup is advised before initialization is performed. Do you wish to initialize /dev/sda2? [yn] y Enter existing LUKS password:
此命令执行四个步骤:
- 使用与 LUKS 主密钥相同的无序状态测量法创建新的密钥。
- 使用 Clevis 加密新密钥.
- 将 Clevis JWE 对象存储在 LUKS2 标头令牌中,或者使用 LUKSMeta(如果使用非默认的 LUKS1 标头)。
- 启用与 LUKS 一起使用的新密钥。
注意绑定过程假定至少有一个可用的 LUKS 密码插槽。
clevis luks bind
命令占用了其中一个插槽。现在可以使用您的现有密码和 Clevis 策略来解锁卷。
要启用早期引导系统来处理磁盘绑定,请在已安装的系统上使用
dracut
工具。在 RHEL 中,Clevis 生成一个没有特定于主机配置选项的通用initrd
(初始 RAM 磁盘),没有向内核命令行自动添加rd.neednet=1
等参数。如果您的配置依赖于在早期引导期间需要网络的 Tang pin ,请在检测到 Tang 绑定时使用--hostonly-cmdline
参数和dracut
addrd.neednet=1
:安装
clevis-dracut
软件包:# yum install clevis-dracut
重新生成初始 RAM 磁盘:
# dracut -fv --regenerate-all --hostonly-cmdline
或者,在
/etc/dracut.conf.d/
目录中创建 .conf 文件,并将hostonly_cmdline=yes
选项添加到该文件中。然后,您可以使用 without-hostonly-cmdline
的dracut
,例如:# echo "hostonly_cmdline=yes" > /etc/dracut.conf.d/clevis.conf # dracut -fv --regenerate-all
您还可以通过使用安装 Clevis 的系统中的
grubby
工具,确保在早期引导时可用的 Tang pin 网络可用:# grubby --update-kernel=ALL --args="rd.neednet=1"
验证
验证 Clevis JWE 对象是否已成功放入 LUKS 标头中,使用
clevis luks list
命令:# clevis luks list -d /dev/sda2 1: tang '{"url":"http://tang.srv:port"}'
检查绑定是否在早期引导时可用,例如:
# lsinitrd | grep clevis-luks lrwxrwxrwx 1 root root 48 Jan 4 02:56 etc/systemd/system/cryptsetup.target.wants/clevis-luks-askpass.path -> /usr/lib/systemd/system/clevis-luks-askpass.path …
其它资源
-
在您的系统上
clevis-luks-bind (1)
和dracut.cmdline (7)
手册页 - 在初始 ramdisk (initrd) (Red Hat 启用 Sysadmin)中查找 Linux 网络配置
18.14.7. 使用静态 IP 配置配置 NBDE 客户端
要将 NBDE 用于带有静态 IP 配置(没有 DHCP)的客户端,您必须手动将网络配置传递给 dracut
工具。
先决条件
- Tang 服务器正在运行且可用。
NBDE 客户端配置为由 Tang 服务器自动解锁加密卷。
详情请参阅 配置 NBDE 客户端以自动解锁 LUKS 加密卷。
流程
您可以在
dracut
命令中提供静态网络配置作为kernel-cmdline
选项的值,例如:# dracut -fv --regenerate-all --kernel-cmdline "ip=192.0.2.10::192.0.2.1:255.255.255.0::ens3:none nameserver=192.0.2.100"
或者,在
/etc/dracut.conf.d/
目录中创建带有静态网络信息的 .conf 文件,然后重新生成初始 RAM 磁盘镜像:# cat /etc/dracut.conf.d/static_ip.conf kernel_cmdline="ip=192.0.2.10::192.0.2.1:255.255.255.0::ens3:none nameserver=192.0.2.100" # dracut -fv --regenerate-all
18.14.8. 使用 TPM 2.0 策略配置 LUKS 加密的卷的手动注册
您可以使用受信任的平台模块 2.0 (TPM 2.0)策略配置 LUKS 加密卷的解锁。
先决条件
- 兼容 TPM 2.0 的设备。
- 具有 64 位 Intel 或 64 位 AMD 架构的系统。
流程
要自动解锁现有的 LUKS 加密卷,请安装
clevis-luks
子软件包:# yum install clevis-luks
识别 PBD 的 LUKS 加密卷。在以下示例中,块设备是指 /dev/sda2 :
# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 12G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 8:2 0 11G 0 part └─luks-40e20552-2ade-4954-9d56-565aa7994fb6 253:0 0 11G 0 crypt ├─rhel-root 253:0 0 9.8G 0 lvm / └─rhel-swap 253:1 0 1.2G 0 lvm [SWAP]
使用
clevis luks bind
命令将卷绑定到 TPM 2.0 设备,例如:# clevis luks bind -d /dev/sda2 tpm2 '{"hash":"sha256","key":"rsa"}' ... Do you wish to initialize /dev/sda2? [yn] y Enter existing LUKS password:
此命令执行四个步骤:
- 使用与 LUKS 主密钥相同的无序状态测量法创建新的密钥。
- 使用 Clevis 加密新密钥.
- 将 Clevis JWE 对象存储在 LUKS2 标头令牌中,或者使用 LUKSMeta(如果使用非默认的 LUKS1 标头)。
启用与 LUKS 一起使用的新密钥。
注意绑定过程假定至少有一个可用的 LUKS 密码插槽。
clevis luks bind
命令占用了其中一个插槽。或者,如果您要将数据封装到特定的平台配置寄存器(PCR)状态,请在
clevis luks bind
命令中添加pcr_ Bank
值,例如:和
pcr_ids# clevis luks bind -d /dev/sda2 tpm2 '{"hash":"sha256","key":"rsa","pcr_bank":"sha256","pcr_ids":"0,1"}'
重要由于只有 PCR 哈希值与密封时使用的策略匹配并且可以重写哈希时,数据才会被取消密封,因此添加一个强大的密码短语,以便您可以在 PCR 中更改值时手动解锁加密的卷。
如果在升级
shim-x64
软件包后系统无法自动解锁加密的卷,请参阅红帽知识库解决方案 Clevis TPM2 不再在重启后解密 LUKS 设备。
- 现在可以使用您的现有密码和 Clevis 策略来解锁卷。
要启用早期引导系统来处理磁盘绑定,请在已安装的系统上使用
dracut
工具:# yum install clevis-dracut # dracut -fv --regenerate-all
验证
要验证 Clevis JWE 对象是否已成功放入 LUKS 标头中,请使用
clevis luks list
命令:# clevis luks list -d /dev/sda2 1: tpm2 '{"hash":"sha256","key":"rsa"}'
其它资源
-
在系统上的
clevis-luks-bind(1)
、clevis-encrypt-tpm2(1)
和dracut.cmdline (7)
手册页
18.14.9. 手动从 LUKS 加密卷中删除 Clevis pin
使用以下步骤手动删除 clevis luks bind
命令创建的元数据,以及擦除包含 Clevis 添加的密码短语的密钥插槽。
从 LUKS 加密卷中删除 Clevis pin 的建议方法是通过 clevis luks unbind
命令。使用 clevis luks unbind
的删除过程只包含一个步骤,适用于 LUKS1 和 LUKS2 卷。以下示例命令删除绑定步骤创建的元数据,并擦除了 /dev/sda2
设备上的密钥插槽 1
:
# clevis luks unbind -d /dev/sda2 -s 1
先决条件
- 具有 Clevis 绑定的 LUKS 加密卷。
流程
检查卷(如
/dev/sda2)
是使用哪个 LUKS 版本加密的,并标识绑定到 Clevis 的插槽和令牌:# cryptsetup luksDump /dev/sda2 LUKS header information Version: 2 ... Keyslots: 0: luks2 ... 1: luks2 Key: 512 bits Priority: normal Cipher: aes-xts-plain64 ... Tokens: 0: clevis Keyslot: 1 ...
在上例中,Clevis 令牌标识为
0
,关联的密钥插槽是1
。如果是 LUKS2 加密,请删除令牌:
# cryptsetup token remove --token-id 0 /dev/sda2
如果您的设备由 LUKS1 加密,这由
Version 表示:1
字符串在cryptsetup luksDump
命令的输出结果中,使用luksmeta wipe
命令执行这个额外步骤:# luksmeta wipe -d /dev/sda2 -s 1
擦除包含 Clevis 密码短语的密钥插槽:
# cryptsetup luksKillSlot /dev/sda2 1
其它资源
-
在系统中
clevis-luks-unbind
(8)和(
1)、cryptsetupluksmeta (8)
手册页
18.14.10. 使用 Kickstart 配置 LUKS 加密的卷的自动注册
按照以下步骤配置使用 Clevis 注册 LUKS 加密卷的自动安装过程。
流程
指示 Kickstart 对磁盘进行分区,以便使用临时密码为所有挂载点(除
/boot
)启用了 LUKS 加密。注册过程的这一步中的密码是临时密码。part /boot --fstype="xfs" --ondisk=vda --size=256 part / --fstype="xfs" --ondisk=vda --grow --encrypted --passphrase=temppass
请注意,兼容 OSPP 的系统需要更复杂的配置,例如:
part /boot --fstype="xfs" --ondisk=vda --size=256 part / --fstype="xfs" --ondisk=vda --size=2048 --encrypted --passphrase=temppass part /var --fstype="xfs" --ondisk=vda --size=1024 --encrypted --passphrase=temppass part /tmp --fstype="xfs" --ondisk=vda --size=1024 --encrypted --passphrase=temppass part /home --fstype="xfs" --ondisk=vda --size=2048 --grow --encrypted --passphrase=temppass part /var/log --fstype="xfs" --ondisk=vda --size=1024 --encrypted --passphrase=temppass part /var/log/audit --fstype="xfs" --ondisk=vda --size=1024 --encrypted --passphrase=temppass
通过在
%packages
部分中列出它们来安装相关的 Clevis 软件包:%packages clevis-dracut clevis-luks clevis-systemd %end
- 可选:为确保您可以在需要时手动解锁加密的卷,请在删除临时密码短语前添加强大的密码短语。如需更多信息,请参阅红帽知识库解决方案 如何将密码短语、密钥或密钥文件添加到现有 LUKS 设备。
在
%post
部分中调用clevis luks bind
来执行绑定。之后,删除临时密码:%post clevis luks bind -y -k - -d /dev/vda2 \ tang '{"url":"http://tang.srv"}' <<< "temppass" cryptsetup luksRemoveKey /dev/vda2 <<< "temppass" dracut -fv --regenerate-all %end
如果您的配置依赖于在早期引导过程中需要网络的 Tang pin,或者使用带有静态 IP 配置的 NBDE 客户端,则必须修改带有静态 IP 配置的 NBDE 客户端,
如
配置 LUKS 加密卷手动注册 中所述。请注意,RHEL 8.3 提供了
clevis luks bind
命令的-y
选项。在 RHEL 8.2 及更旧版本中,在clevis luks bind
命令中将-y
替换为 -f%post curl -sfg http://tang.srv/adv -o adv.jws clevis luks bind -f -k - -d /dev/vda2 \ tang '{"url":"http://tang.srv","adv":"adv.jws"}' <<< "temppass" cryptsetup luksRemoveKey /dev/vda2 <<< "temppass" dracut -fv --regenerate-all %end
警告cryptsetup luksRemoveKey
命令可以防止对应用该命令的 LUKS2 设备进行任何进一步的管理。您只能对 LUKS1 设备使用dmsetup
命令恢复删除的主密钥。
在使用 TPM 2.0 策略而不是 Tang 服务器时,您可以使用类似的流程。
其它资源
-
clevis (1)
,clevis-luks-bind (1)
,cryptsetup (8)
, 和dmsetup (8)
man page - 自动安装 RHEL
18.14.11. 配置 LUKS 加密的可移动存储设备的自动解锁
您可以设置 LUKS 加密的 USB 存储设备的自动解锁过程。
流程
要自动解锁 LUKS 加密的可移动存储设备,如 USB 驱动器,请安装
clevis-udisks2
软件包:# yum install clevis-udisks2
重启系统,然后使用
clevis luks bind
命令执行绑定步骤,如 配置 LUKS 加密卷的手动注册 中所述,例如:# clevis luks bind -d /dev/sdb1 tang '{"url":"http://tang.srv"}'
现在,可以在 GNOME 桌面会话中自动解锁 LUKS 加密的可移动设备。绑定到 Clevis 策略的设备也可以通过
clevis luks unlock
命令解锁:# clevis luks unlock -d /dev/sdb1
在使用 TPM 2.0 策略而不是 Tang 服务器时,您可以使用类似的流程。
其它资源
-
您系统上的
clevis-luks-unlockers (7)
手册页
18.14.12. 部署高可用性 NBDE 系统
Tang 提供两种构建高可用性部署的方法:
- 客户端冗余(推荐)
-
客户端应配置成能够绑定到多个 Tang 服务器。在此设置中,每个 Tang 服务器都有自己的密钥,客户端可以通过联系这些服务器的子集来进行解密。Clevis 已通过其
sss
插件支持此工作流。红帽建议对高可用性部署使用这个方法。 - 密钥共享
-
出于冗余的目的,可以部署多个 Tang 实例。要设置第二个或后续的实例,请安装
tang
软件包,并使用rsync
,通过SSH
将密钥目录复制到新主机上。请注意,红帽不推荐此方法,因为共享密钥会增加密钥的风险,需要额外的自动化基础设施。
使用 Shamir 的 Secret 共享的高可用性 NBDE
Shamir 的 Secret 共享(SSS)是一种加密方案,可将Secret 分成多个独特的部分。要重建 secret,需要几个部分。数字称为阈值,SSS 也被称为阈值方案。
Clevis 提供 SSS 的实施。它创建一个密钥,并将其分为若干个片。每片都使用另一个 pin 进行加密,甚至包括递归 SSS。另外,您可以定义阈值 t
。如果 NBDE 部署至少解密了 t
片,那么它将恢复加密密钥,并且解密过程会成功。当 Clevis 检测到比阈值中指定的部分少时,它会打印错误消息。
示例 1:带有两个 Tang 服务器的冗余
当两个 Tang 服务器中至少有一个可用时,以下命令会解密 LUKS 加密设备:
# clevis luks bind -d /dev/sda1 sss '{"t":1,"pins":{"tang":[{"url":"http://tang1.srv"},{"url":"http://tang2.srv"}]}}'
上一命令使用以下配置方案:
{ "t":1, "pins":{ "tang":[ { "url":"http://tang1.srv" }, { "url":"http://tang2.srv" } ] } }
在此配置中,SSS 阈值 t
设置为 1
,如果列出的两个 tang
服务器中至少有一台可用,则 clevis luks bind
命令可以成功重建 secret。
示例 2:Tang 服务器和 TPM 设备中的共享 secret
当 tang
服务器和 tpm2
设备都可用时,以下命令可成功解密 LUKS 加密设备:
# clevis luks bind -d /dev/sda1 sss '{"t":2,"pins":{"tang":[{"url":"http://tang1.srv"}], "tpm2": {"pcr_ids":"0,7"}}}'
现在 SSS 阀值 't' 设置为 '2' 的配置方案是:
{ "t":2, "pins":{ "tang":[ { "url":"http://tang1.srv" } ], "tpm2":{ "pcr_ids":"0,7" } } }
其它资源
-
tang (8)
(高可用性
部分)、clevis (1)
(Shamir's Secret Sharing
)以及您系统上的clevis-encrypt-sss (1)
手册页
18.14.13. NBDE 网络中虚拟机的部署
clevis luks bind
命令不会改变 LUKS 主密钥。这意味着,如果您创建了一个在虚拟机或云环境中使用的 LUKS 加密镜像,则所有运行此镜像的实例都会共享一个主密钥。这极其不安全,应始终避免。
这不是 Clevis 的一个限制,而是 LUKS 的设计原则。如果您的场景需要在云中有加密的根卷,请对云中的每个 Red Hat Enterprise Linux 实例执行安装过程(通常使用 Kickstart)。如果没有共享 LUKS 主密钥,就无法共享镜像。
要在虚拟环境中部署自动解锁,请将诸如 lorax
或 virt-install
的系统与 Kickstart 文件一起使用(请参阅 使用 Kickstart 配置 LUKS 加密卷的自动注册)或其它自动配置工具来确保每个加密的虚拟机都有一个唯一的主密钥。
其它资源
-
系统上的
clevis-luks-bind (1)
手册页
18.14.14. 使用 NBDE 为云环境构建可自动注册的虚拟机镜像
在云环境中部署可自动注册的加密镜像会带来一系列独特的挑战。与其他虚拟化环境一样,建议减少从一个镜像启动的实例数量,以避免共享 LUKS 主密钥。
因此,最佳实践是创建自定义映像,这些映像不在任何公共存储库中共享,为部署有限数量的实例提供了基础。要创建的实例的确切数量应当由部署的安全策略定义,并且基于与 LUKS 主密钥攻击向量相关联的风险容忍度。
要构建启用 LUKS 的自动化部署,应当使用 Lorax 或 virt-install 等系统以及一个 Kickstart 文件,来确保镜像构建过程中主密钥的唯一性。
云环境支持我们在这里考虑的两种 Tang 服务器部署选项。首先,Tang 服务器可以在云环境本身中部署。其次,Tang 服务器可以部署在云外的独立的基础架构上,并且这两个基础架构之间有 VPN 连接。
在云中原生部署 Tang 可以轻松部署。但是,考虑到它与其他系统的密文数据持久性层共享基础设施,因此 Tang 服务器的私钥和 Clevis 元数据可以存储在同一个物理磁盘上。对这个物理磁盘的访问允许密文数据的完全泄露。
始终在存储数据的地方和运行 Tang 的系统之间保持物理隔离。在云和 Tang 服务器之间的这种隔离可确保 Tang 服务器的私钥不会被意外与 Clevis 元数据组合。如果云基础设施面临风险,它还提供了对 Tang 服务器的本地控制。
18.14.15. 将 Tang 部署为容器
tang
容器镜像为在 OpenShift Container Platform(OCP)集群中或独立虚拟机运行的 Clevis 客户端提供 Tang-server 解密功能。
先决条件
-
podman
软件包及其依赖项已安装在系统上。 -
你可以使用
podman login registry.redhat.io
命令登录到registry.redhat.io
容器目录。如需更多信息,请参阅 红帽容器注册表身份验证。 - Clevis 客户端安装在包含 LUKS 加密卷的系统上,您希望使用 Tang 服务器自动解锁这些卷。
流程
从
registry.redhat.io
registry 中拉取tang
容器镜像:# podman pull registry.redhat.io/rhel8/tang
运行容器,指定其端口,并指定到 Tang 密钥的路径。前面的示例运行
tang
容器,指定端口 7500,并指示到/var/db/tang
目录的 Tang 密钥的路径:# podman run -d -p 7500:7500 -v tang-keys:/var/db/tang --name tang registry.redhat.io/rhel8/tang
请注意,Tang 默认使用端口 80,但这可能与其他服务冲突,如 Apache HTTP 服务器。
可选:为提高安全性,请定期轮转 Tang 密钥。您可以使用
tangd-rotate-keys
脚本,例如:# podman run --rm -v tang-keys:/var/db/tang registry.redhat.io/rhel8/tang tangd-rotate-keys -v -d /var/db/tang Rotated key 'rZAMKAseaXBe0rcKXL1hCCIq-DY.jwk' -> .'rZAMKAseaXBe0rcKXL1hCCIq-DY.jwk' Rotated key 'x1AIpc6WmnCU-CabD8_4q18vDuw.jwk' -> .'x1AIpc6WmnCU-CabD8_4q18vDuw.jwk' Created new key GrMMX_WfdqomIU_4RyjpcdlXb0E.jwk Created new key _dTTfn17sZZqVAp80u3ygFDHtjk.jwk Keys rotated successfully.
验证
在包含 LUKS 加密卷的系统上,通过 Tang 服务器自动解锁,检查 Clevis 客户端是否可以使用 Tang 加密和解密纯文本消息:
# echo test | clevis encrypt tang '{"url":"http://localhost:7500"}' | clevis decrypt The advertisement contains the following signing keys: x1AIpc6WmnCU-CabD8_4q18vDuw Do you wish to trust these keys? [ynYN] y test
在 localhost URL 上的 Tang 服务器可用并通过端口 7500 进行通信时,上一示例命令在其输出的末尾显示
test
字符串。
其它资源
-
podman (1)
、clevis (1)
和tang (8)
man page - 有关使用 Clevis 和 Tang 自动解锁 LUKS 加密卷的详情,请参考 使用基于策略的解密配置加密卷的自动解锁 章节。
18.14.16. 使用 RHEL 系统角色配置 NBDE
您可以使用 nbde_client
和 nbde_server
RHEL 系统角色使用 Clevis 和 Tang 自动部署基于策略的解密(PBD)解决方案。rhel-system-roles
包中包含了这些系统角色、相关的例子以及参考文档。
18.14.16.1. 使用 nbde_server
RHEL 系统角色设置多个 Tang 服务器
通过使用 nbde_server
系统角色,您可以部署和管理 Tang 服务器作为自动磁盘加密解决方案的一部分。此角色支持以下功能:
- 轮转 Tang 密钥
- 部署和备份 Tang 密钥
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
用于连接到受管节点的帐户具有
sudo
权限。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:--- - name: Deploy a Tang server hosts: tang.server.example.com tasks: - name: Install and configure periodic key rotation ansible.builtin.include_role: name: rhel-system-roles.nbde_server vars: nbde_server_rotate_keys: yes nbde_server_manage_firewall: true nbde_server_manage_selinux: true
此示例 playbook 确保部署 Tang 服务器和密钥轮转。
示例 playbook 中指定的设置包括以下内容:
nbde_server_manage_firewall: true
-
使用
firewall
系统角色管理nbde_server
角色使用的端口。 nbde_server_manage_selinux: true
使用
selinux
系统角色管理nbde_server
角色使用的端口。有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.nbde_server/README.md
文件。
验证 playbook 语法:
$ ansible-playbook --syntax-check ~/playbook.yml
请注意,这个命令只验证语法,不会防止错误但有效的配置。
运行 playbook:
$ ansible-playbook ~/playbook.yml
验证
在您的 NBDE 客户端上,使用以下命令验证您的 Tang 服务器是否正常工作。该命令必须返回您传递的与加密和解密相同的消息:
# ansible managed-node-01.example.com -m command -a 'echo test | clevis encrypt tang '{"url":"<tang.server.example.com>"}' -y | clevis decrypt' test
其它资源
-
/usr/share/ansible/roles/rhel-system-roles.nbde_server/README.md
文件 -
/usr/share/doc/rhel-system-roles/nbde_server/
目录
18.14.16.2. 使用 nbde_client
RHEL 系统角色使用 DHCP 设置 Clevis 客户端
nbde_client
系统角色使您能够以自动化的方式部署多个Clevis客户端。
此角色支持将 LUKS 加密卷绑定到一个或多个网络绑定(NBDE)服务器 - Tang 服务器。您可以使用密码短语保留现有的卷加密,或者将其删除。删除密码短语后,您只能使用 NBDE 解锁卷。当卷最初是使用在置备系统后会删除的临时密钥或密码进行加密时,这非常有用,
如果您同时提供密语和密钥文件,角色将使用您首先提供的那一个。如果找不到任何有效密语或密码,它将尝试从现有的绑定中检索密码短语。
基于策略的解密(PBD)将绑定定义为设备到插槽的映射。这意味着对同一个设备你可以有多个绑定。默认插槽是插槽 1。
nbde_client
系统角色只支持 Tang 绑定。因此,您无法将其用于 TPM2 绑定。
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
用于连接到受管节点的帐户具有
sudo
权限。 - 已使用 LUKS 加密的卷。
流程
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:--- - name: Configure clients for unlocking of encrypted volumes by Tang servers hosts: managed-node-01.example.com tasks: - name: Create NBDE client bindings ansible.builtin.include_role: name: rhel-system-roles.nbde_client vars: nbde_client_bindings: - device: /dev/rhel/root encryption_key_src: /etc/luks/keyfile nbde_client_early_boot: true state: present servers: - http://server1.example.com - http://server2.example.com - device: /dev/rhel/swap encryption_key_src: /etc/luks/keyfile servers: - http://server1.example.com - http://server2.example.com
这个示例 playbook 配置 Clevis 客户端,以便在两个 Tang 服务器中至少有一个可用时自动解锁两个 LUKS 加密卷。
示例 playbook 中指定的设置包括以下内容:
state: present
-
state
的值表示运行 playbook 后的配置。使用present
值来创建新绑定或更新现有绑定。与clevis luks bind
命令不同,您可以使用state: present
来覆盖其设备插槽中的现有绑定。absent
的值会删除指定的绑定。 nbde_client_early_boot: true
nbde_client
角色可确保 Tang pin 的网络默认在早期引导时可用。如果您需要禁用此功能,请在 playbook 中添加nbde_client_early_boot: false
变量。有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.nbde_client/README.md
文件。
验证 playbook 语法:
$ ansible-playbook --syntax-check ~/playbook.yml
请注意,这个命令只验证语法,不会防止错误但有效的配置。
运行 playbook:
$ ansible-playbook ~/playbook.yml
验证
在 NBDE 客户端中,检查您的 Tang 服务器是否应自动解锁的加密卷,其中包含其 LUKS pin 中对应的信息:
# ansible managed-node-01.example.com -m command -a 'clevis luks list -d /dev/rhel/root' 1: tang '{"url":"<http://server1.example.com/>"}' 2: tang '{"url":"<http://server2.example.com/>"}'
如果不使用
nbde_client_early_boot: false
变量,请验证绑定可用于早期引导,例如:# ansible managed-node-01.example.com -m command -a 'lsinitrd | grep clevis-luks' lrwxrwxrwx 1 root root 48 Jan 4 02:56 etc/systemd/system/cryptsetup.target.wants/clevis-luks-askpass.path -> /usr/lib/systemd/system/clevis-luks-askpass.path …
其它资源
-
/usr/share/ansible/roles/rhel-system-roles.nbde_client/README.md
文件 -
/usr/share/doc/rhel-system-roles/nbde_client/
目录
18.14.16.3. 使用 nbde_client
RHEL 系统角色设置 static-IP Clevis 客户端
nbde_client
RHEL 系统角色只支持使用动态主机配置协议(DHCP)的情况。在带有静态 IP 配置的 NBDE 客户端中,您必须将网络配置作为内核引导参数传递。
通常,管理员希望重复使用 playbook,且不会为 Ansible 在早期引导过程中为其分配静态 IP 地址的每个主机维护单独的 playbook。在这种情况下,您可以在 playbook 中使用变量并在外部文件中提供设置。因此,您只需要一个 playbook 和一个带有设置的文件。
先决条件
- 您已准备好控制节点和受管节点
- 以可在受管主机上运行 playbook 的用户登录到控制节点。
-
用于连接到受管节点的帐户具有
sudo
权限。 - 已使用 LUKS 加密的卷。
流程
使用主机的网络设置创建文件,如
static-ip-settings-clients.yml
,并添加您要动态分配给主机的值:clients: managed-node-01.example.com: ip_v4: 192.0.2.1 gateway_v4: 192.0.2.254 netmask_v4: 255.255.255.0 interface: enp1s0 managed-node-02.example.com: ip_v4: 192.0.2.2 gateway_v4: 192.0.2.254 netmask_v4: 255.255.255.0 interface: enp1s0
创建一个包含以下内容的 playbook 文件,如
~/playbook.yml
:- name: Configure clients for unlocking of encrypted volumes by Tang servers hosts: managed-node-01.example.com,managed-node-02.example.com vars_files: - ~/static-ip-settings-clients.yml tasks: - name: Create NBDE client bindings ansible.builtin.include_role: name: rhel-system-roles.network vars: nbde_client_bindings: - device: /dev/rhel/root encryption_key_src: /etc/luks/keyfile servers: - http://server1.example.com - http://server2.example.com - device: /dev/rhel/swap encryption_key_src: /etc/luks/keyfile servers: - http://server1.example.com - http://server2.example.com - name: Configure a Clevis client with static IP address during early boot ansible.builtin.include_role: name: rhel-system-roles.bootloader vars: bootloader_settings: - kernel: ALL options: - name: ip value: "{{ clients[inventory_hostname]['ip_v4'] }}::{{ clients[inventory_hostname]['gateway_v4'] }}:{{ clients[inventory_hostname]['netmask_v4'] }}::{{ clients[inventory_hostname]['interface'] }}:none"
此 playbook 为
~/static-ip-settings-clients.yml
文件中列出的每个主机动态读取某些值。有关 playbook 中使用的所有变量的详情,请查看控制节点上的
/usr/share/ansible/roles/rhel-system-roles.network/README.md
文件。验证 playbook 语法:
$ ansible-playbook --syntax-check ~/playbook.yml
请注意,这个命令只验证语法,不会防止错误但有效的配置。
运行 playbook:
$ ansible-playbook ~/playbook.yml
其它资源
-
/usr/share/ansible/roles/rhel-system-roles.nbde_client/README.md
文件 -
/usr/share/doc/rhel-system-roles/nbde_client/
目录 - 在初始 ramdisk (initrd) (Red Hat 启用 Sysadmin)中查找 Linux 网络配置