Red Hat Training

A Red Hat training course is available for Red Hat Enterprise Linux

4.10. 使用基于策略的解密配置加密卷的自动锁定

基于策略的解密(PBD)是技术的集合,允许使用像用户密码、受信任的平台模块(TPM)设备、连接到系统(如智能卡)或特殊网络服务器等不同方法解锁加密的根和硬盘的辅助卷。
PBD 作为技术允许将不同的解锁方法合并到策略中,从而创建以不同方式解锁同一卷的功能。Red Hat Enterprise Linux 中 PBD 的当前实现由 Clevis 框架和名为 pins 的插件组成。每个 pin 都提供单独的解锁功能。现在,唯一可用的 pins 是允许卷使用 TPM 或网络服务器解锁的卷。
Network Bound Disc Encryption (NBDE)是 PBD 技术的一个子类别,允许将加密卷绑定到特殊的网络服务器。NBDE 的当前实现包括 Tang 服务器的 Clevis pin 和 Tang 服务器本身。

4.10.1. network-Bound Disk Encryption

Network-Bound Disk Encryption (NBDE)允许用户加密物理和虚拟机上的硬盘驱动器的根卷,而无需在系统重启时手动输入密码。
在 Red Hat Enterprise Linux 7 中,NBDE 通过以下组件和技术实现:

图 4.2. 使用 Clevis 和 Tang 的 Network-Bound Disk Encryption

使用 Clevis 和 Tang 的 Network-Bound Disk Encryption
Tang 是一个将数据绑定到网络存在的服务器。当系统绑定到某个安全网络时,它会使包含数据的系统变得可用。Tang 是无状态的,不需要 TLS 或身份验证。与基于 escrow 的解决方案不同,服务器存储所有加密密钥并了解以前使用的每个密钥,Tang 从不与任何客户端密钥进行交互,因此不会从客户端获得任何识别信息。
Clevis 是一个自动化解密的可插拔框架。在 NBDE 中,Clevis 提供 LUKS 卷的自动解锁。clevis 软件包提供该功能的客户端。
Clevis pin 是 Clevis 框架的一个插件。其中一个 pins 是实现与 NBDE 服务器进行交互的插件 - Tang。
Clevis 和 Tang 是通用的客户端和服务器组件,提供网络绑定加密。在 Red Hat Enterprise Linux 7 中,它们与 LUKS 一起使用,以加密和解密 root 和非 root 存储卷,以完成网络绑定磁盘加密。
客户端和服务器端组件都使用 José 库来执行加密和解密操作。
当您开始调配 NBDE 时,Tang 服务器的 Clevis pin 获取 Tang 服务器公告的非对称密钥的列表。或者,由于密钥是非对称的,因此 Tang 的公钥列表可以分发到带外,以便客户端能够在不访问 Tang 服务器的情况下进行操作。此模式称为 脱机调配
Tang 的 Clevis pin 使用其中一个公钥来生成唯一的强加密的加密密钥。使用此密钥加密数据后,密钥将被丢弃。Clevis 客户端应将此调配操作生成的状态存储在方便的位置。这种加密数据的过程就是 调配步骤。NBDE 的调配状态利用 luksmeta 软件包存储在 LUKS 标头中。
当客户端准备好访问其数据时,它会加载再调配步骤中生成的元数据,并响应恢复加密密钥。此过程是 恢复步骤
在 NBDE 中,Clevis 使用 pin 绑定 LUKS 卷,以便能自动解锁它。成功完成绑定流程后,可以使用提供的 Dracut 解锁程序解锁磁盘。
所有 LUKS 加密设备,例如 /tmp/var/usr/local/ 目录,其中包含建立网络连接前需要启动的文件系统,被视为是 root 卷。此外,在网络启动前运行的服务使用的所有挂载点,如 /var/log/var/log/audit//opt,需要在切换到 root 设备后提前挂载。您还可以通过在 /etc/fstab 文件中没有 _netdev 选项来识别根卷。

4.10.2. 安装加密客户端 - Clevis

要在带有加密卷(客户端)的机器上安装 Clevis 可插拔框架及其 pins,请以 root 用户身份输入以下命令:
~]# yum install clevis
要解密数据,请使用 clevis decrypt 命令,并提供密码文本(JWE):
~]$ clevis decrypt < JWE > PLAINTEXT
如需更多信息,请参阅内置 CLI 帮助:
~]$ clevis
Usage: clevis COMMAND [OPTIONS]

  clevis decrypt      Decrypts using the policy defined at encryption time
  clevis encrypt http Encrypts using a REST HTTP escrow server policy
  clevis encrypt sss  Encrypts using a Shamir's Secret Sharing policy
  clevis encrypt tang Encrypts using a Tang binding server policy
  clevis encrypt tpm2 Encrypts using a TPM2.0 chip binding policy

~]$ clevis decrypt
Usage: clevis decrypt < JWE > PLAINTEXT

Decrypts using the policy defined at encryption time

~]$ clevis encrypt tang
Usage: clevis encrypt tang CONFIG < PLAINTEXT > JWE

Encrypts using a Tang binding server policy

This command uses the following configuration properties:

  url: <string>   The base URL of the Tang server (REQUIRED)

  thp: <string>   The thumbprint of a trusted signing key

  adv: <string>   A filename containing a trusted advertisement
  adv: <object>   A trusted advertisement (raw JSON)

Obtaining the thumbprint of a trusted signing key is easy. If you
have access to the Tang server's database directory, simply do:

    $ jose jwk thp -i $DBDIR/$SIG.jwk

Alternatively, if you have certainty that your network connection
is not compromised (not likely), you can download the advertisement
yourself using:

    $ curl -f $URL/adv > adv.jws

4.10.3. 在强制模式中使用 SELinux 部署 Tang 服务器

Red Hat Enterprise Linux 7.7 及更新版本提供了 tangd_port_t SELinux 类型,Tang 服务器可以在 SELinux enforcing 模式下部署为受限制的服务。

先决条件

  • 已安装 policycoreutils-python-utils 软件包及其依赖项。

流程

  1. 要安装 tang 软件包及其依赖项,请以 root 用户身份输入以下命令:
    ~]# yum install tang
  2. 选择一个未占用的端口,如 7500/tcp,并允许 tangd 服务绑定到该端口:
    ~]# semanage port -a -t tangd_port_t -p tcp 7500
    请注意,一个端口一次只能由一个服务使用,因此尝试使用已经占用的端口意味着 ValueError: Port already defined 错误消息。
  3. 在防火墙中打开端口:
    ~]# firewall-cmd --add-port=7500/tcp
    ~]# firewall-cmd --runtime-to-permanent
  4. 使用 systemd 启用 tangd 服务:
    ~]# systemctl enable tangd.socket
    Created symlink from /etc/systemd/system/multi-user.target.wants/tangd.socket to /usr/lib/systemd/system/tangd.socket.
  5. 创建覆盖文件:
    ~]# systemctl edit tangd.socket
  6. 在以下编辑器屏幕中,其打开了位于 /etc/systemd/system/tangd.socket.d/ 目录中的一个空 override.conf 文件,通过添加以下行将 Tang 服务器的默认端口从 80 改为之前选择的端口号:
    [Socket]
    ListenStream=
    ListenStream=7500
    保存文件并退出编辑器。
  7. 重新载入更改的配置并启动 tangd 服务:
    ~]# systemctl daemon-reload
  8. 检查您的配置是否正常工作:
    ~]# systemctl show tangd.socket -p Listen
    Listen=[::]:7500 (Stream)
  9. 启动 tangd 服务:
    ~]# systemctl start tangd.socket
由于 tangd 使用了 systemd 套接字激活机制,因此服务器会在第一次连接进来时就立即启动。在第一次启动时会自动生成一组新的加密密钥。
要执行手动生成密钥等加密操作,请使用 jose 工具。输入 jose -h 命令或查看 jose (1) 手册页以了解更多信息。

例 4.4. 轮转 Tang 密钥

定期轮转您的密钥非常重要。轮转它们的确切间隔取决于您的应用程序、密钥大小和机构策略。有关一些常见建议,请参阅 Cryptographic Key Length Recommendation 页面。
要轮转密钥,请从密钥数据库目录中生成新密钥开始,通常为 /var/db/tang。例如,您可以使用以下命令创建新的签名和交换密钥:
~]# DB=/var/db/tang
~]# jose jwk gen -i '{"alg":"ES512"}' -o $DB/new_sig.jwk
~]# jose jwk gen -i '{"alg":"ECMR"}' -o $DB/new_exc.jwk
重命名旧密钥,使其具有前导 . 以将它们隐藏在广告中。请注意,以下示例中的文件名与密钥数据库目录中的实际和唯一的文件名不同。
~]# mv $DB/old_sig.jwk $DB/.old_sig.jwk
~]# mv $DB/old_exc.jwk $DB/.old_exc.jwk
Tang 立即获取所有更改。不需要重启。
此时,新的客户端绑定会获取新密钥,旧客户端可以继续使用旧密钥。当您确定所有旧客户端都使用新密钥时,您可以删除旧的密钥。
警告
请注意,在客户端仍在使用旧密钥时删除旧密钥可能会导致数据丢失。

4.10.3.1. 部署高可用性系统

Tang 提供两种构建高可用性部署的方法:
  1. 客户端冗余(推荐)
    客户端应配置成能够绑定到多个 Tang 服务器。在此设置中,每个 Tang 服务器都有自己的密钥,客户端可以通过联系这些服务器的子集来进行解密。Clevis 已通过其 sss 插件支持此工作流。
    有关此设置的详情,请查看以下手册页:
    • tang (8), 部分高可用性
    • clevis (1), 第 Shamir 的 Secret 共享部分
    • clevis-encrypt-sss(1)
    红帽建议对高可用性部署使用这个方法。
  2. 密钥共享
    出于冗余的目的,可以部署多个 Tang 实例。要设置第二个或后续实例,请安装 tang 软件包,并使用 rsync 通过 SSH 将密钥目录复制到新主机。请注意,红帽不推荐此方法,因为共享密钥会增加密钥的风险,需要额外的自动化基础设施。

4.10.4. 为带有 Tang 的 NBDE 系统部署加密客户端

先决条件

流程

要将 Clevis 加密客户端绑定到 Tang 服务器,请使用 clevis encrypt tang 子命令:
~]$ clevis encrypt tang '{"url":"http://tang.srv"}' < PLAINTEXT > JWE
The advertisement contains the following signing keys:

_OsIk0T-E2l6qjfdDiwVmidoZjA

Do you wish to trust these keys? [ynYN] y
更改上例中的 http://tang.srv URL,使其与安装 tang 的服务器的 URL 匹配。JWE 输出文件包含您的加密密码文本。这个密码文本是从 PLAINTEXT 输入文件中读取的。
要解密数据,请使用 clevis decrypt 命令,并提供密码文本(JWE):
~]$ clevis decrypt < JWE > PLAINTEXT
如需更多信息,请参阅 clevis-encrypt-tang (1) 手册页或使用内置 CLI 帮助:
~]$ clevis
Usage: clevis COMMAND [OPTIONS]

  clevis decrypt      Decrypts using the policy defined at encryption time
  clevis encrypt http Encrypts using a REST HTTP escrow server policy
  clevis encrypt sss  Encrypts using a Shamir's Secret Sharing policy
  clevis encrypt tang Encrypts using a Tang binding server policy
  clevis luks bind    Binds a LUKSv1 device using the specified policy
  clevis luks unlock  Unlocks a LUKSv1 volume

~]$ clevis decrypt
Usage: clevis decrypt < JWE > PLAINTEXT

Decrypts using the policy defined at encryption time

~]$ clevis encrypt tang
Usage: clevis encrypt tang CONFIG < PLAINTEXT > JWE

Encrypts using a Tang binding server policy

This command uses the following configuration properties:

  url: <string>   The base URL of the Tang server (REQUIRED)

  thp: <string>   The thumbprint of a trusted signing key

  adv: <string>   A filename containing a trusted advertisement
  adv: <object>   A trusted advertisement (raw JSON)

Obtaining the thumbprint of a trusted signing key is easy. If you
have access to the Tang server's database directory, simply do:

    $ jose jwk thp -i $DBDIR/$SIG.jwk

Alternatively, if you have certainty that your network connection
is not compromised (not likely), you can download the advertisement
yourself using:

    $ curl -f $URL/adv > adv.jws

4.10.5. 使用 TPM 2.0 策略部署加密客户端

在 64 位 Intel 或 64 位 AMD 架构的系统上,要部署使用受信任的平台模块 2.0 (TPM 2.0)芯片加密的客户端,请使用 clevis encrypt tpm2 子命令,以 JSON 配置对象的形式唯一参数:
~]$ clevis encrypt tpm2 '{}' < PLAINTEXT > JWE
要选择不同的层次结构、哈希和密钥算法,请指定配置属性,例如:
~]$ clevis encrypt tpm2 '{"hash":"sha1","key":"rsa"}' < PLAINTEXT > JWE
要解密数据,请提供密码文本(JWE):
~]$ clevis decrypt < JWE > PLAINTEXT
pin 还支持将数据封装到平台配置寄存器(PCR)状态。这样,只有 PCR 哈希值与密封时使用的策略匹配时,数据才能被解封。
例如,对于 SHA1 银行,使用索引 0 和 1 将数据封装到 PCR:
~]$ clevis encrypt tpm2 '{"pcr_bank":"sha1","pcr_ids":"0,1"}' < PLAINTEXT > JWE
如需更多信息以及可能的配置属性列表,请参阅 clevis-encrypt-tpm2 (1) 手册页。

4.10.6. 配置根卷的手动注册

要自动解锁现有的 LUKS 加密的根卷,请安装 clevis-luks 子软件包并使用 clevis luks bind 命令将卷绑定到 Tang 服务器:
~]# yum install clevis-luks
~]# clevis luks bind -d /dev/sda 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/sda? [yn] y
Enter existing LUKS password:
此命令执行四个步骤:
  1. 使用与 LUKS 主密钥相同的无序状态测量法创建新的密钥。
  2. 使用 Clevis 加密新密钥.
  3. 使用 LUKSMeta 将 Clevis JWE 对象存储在 LUKS 标头中。
  4. 启用与 LUKS 一起使用的新密钥。
现在,可以使用您的现有密码和 Clevis 策略解锁此磁盘。如需更多信息,请参阅 clevis-luks-bind (1) 手册页。
注意
绑定过程假定至少有一个可用的 LUKS 密码插槽。clevis luks bind 命令占用了其中一个插槽。
要验证 Clevis JWE 对象是否已成功放置在 LUKS 标头中,请使用 luksmeta show 命令:
~]# luksmeta show -d /dev/sda
0   active empty
1   active cb6e8904-81ff-40da-a84a-07ab9ab5715e
2 inactive empty
3 inactive empty
4 inactive empty
5 inactive empty
6 inactive empty
7 inactive empty
要启用早期引导系统来处理磁盘绑定,请在已安装的系统中输入以下命令:
~]# yum install clevis-dracut
~]# dracut -f --regenerate-all
重要
要将 NBDE 用于带有静态 IP 配置(没有 DHCP)的客户端,请手动将网络配置传递给 dracut 工具,例如:
~]# dracut -f --regenerate-all --kernel-cmdline "ip=192.0.2.10 netmask=255.255.255.0 gateway=192.0.2.1 nameserver=192.0.2.45"
或者,在 /etc/dracut.conf.d/ 目录中创建 一个带有静态网络信息的.conf 文件。例如:
~]# cat /etc/dracut.conf.d/static_ip.conf
kernel_cmdline="ip=10.0.0.103 netmask=255.255.252.0 gateway=10.0.0.1 nameserver=10.0.0.1"
重新生成初始 RAM 磁盘镜像:
~]# dracut -f --regenerate-all
详情请查看 dracut.cmdline (7) 手册页。

4.10.7. 使用 Kickstart 配置自动注册

Clevis 可以与 Kickstart 集成,以提供完全自动化的注册过程。
  1. 指示 Kickstart 对磁盘进行分区,以便使用临时密码为所有挂载点(除 /boot )启用了 LUKS 加密。注册过程的这一步中的密码是临时密码。
    part /boot --fstype="xfs" --ondisk=vda --size=256
    part / --fstype="xfs" --ondisk=vda --grow --encrypted --passphrase=temppass
    请注意,OSPP-complaint 系统需要更复杂的配置,例如:
    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
  2. 通过在 %packages 部分中列出它们来安装相关的 Clevis 软件包:
    %packages
    clevis-dracut
    %end
  3. %post 部分中调用 clevis luks bind 来执行绑定。之后,删除临时密码:
    %post
    clevis luks bind -f -k- -d /dev/vda2 \
    tang '{"url":"http://tang.srv","thp":"_OsIk0T-E2l6qjfdDiwVmidoZjA"}' \ <<< "temppass"
    cryptsetup luksRemoveKey /dev/vda2 <<< "temppass"
    %end
    在上例中,请注意,我们指定在 Tang 服务器上信任的 thumbprint 作为绑定配置的一部分,从而允许绑定完全非交互式。
    在使用 TPM 2.0 策略而不是 Tang 服务器时,您可以使用类似的流程。
有关 Kickstart 安装的详情,请查看 Red Hat Enterprise Linux 7 安装指南。有关 Linux Unified Key Setup-on-disk-format (LUKS)的详情,请参考 第 4.9.1 节 “使用 LUKS 磁盘加密”

4.10.8. 配置可移动存储设备的自动锁定

要自动解锁 LUKS 加密的可移动存储设备,如 USB 驱动器,请安装 clevis-udisks2 软件包:
~]# yum install clevis-udisks2
重启系统,然后使用 clevis luks bind 命令执行绑定步骤,如 第 4.10.6 节 “配置根卷的手动注册” 所述:
~]# 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 服务器时,您可以使用类似的流程。

4.10.9. 在引导时配置非 root 卷的自动锁定

要使用 NBDE 同时解锁 LUKS 加密的非 root 卷,请执行以下步骤:
  1. 安装 clevis-systemd 软件包:
    ~]# yum install clevis-systemd
  2. 启用 Clevis unlocker 服务:
    ~]# systemctl enable clevis-luks-askpass.path
    Created symlink from /etc/systemd/system/remote-fs.target.wants/clevis-luks-askpass.path to /usr/lib/systemd/system/clevis-luks-askpass.path.
  3. 使用 clevis luks bind 命令执行绑定步骤,如 第 4.10.6 节 “配置根卷的手动注册” 所述。
  4. 要在系统引导过程中设置加密块设备,请将带有 _netdev 选项的对应行添加到 /etc/crypttab 配置文件中。详情请查看 crypttab (5) 手册页。
  5. 将卷添加到 /etc/fstab 文件中可访问文件系统的列表。此配置文件中也使用 _netdev 选项。详情请查看 fstab (5) 手册页。

4.10.10. 在 NBDE 网络中部署虚拟机

clevis luks bind 命令不会改变 LUKS 主密钥。这意味着,如果您创建了一个 LUKS 加密镜像以便在虚拟机或云环境中使用,则运行此镜像的所有实例都将共享主密钥。这极其不安全,应始终避免。
这不是 Clevis 的一个限制,而是 LUKS 的设计原则。如果您希望在云中有一个加密的根卷,则需要确保对云中的每个 Red Hat Enterprise Linux 实例都执行了安装过程(通常使用 Kickstart)。如果没有共享 LUKS 主密钥,就无法共享镜像。
如果要在虚拟化环境中部署自动解锁,红帽强烈建议您将 lorax 或 virt-install 等系统与 Kickstart 文件(请参阅 第 4.10.7 节 “使用 Kickstart 配置自动注册”)或其他自动配置工具一起使用,以确保每个加密的虚拟机都有一个唯一的主密钥。

4.10.11. 使用 NBDE 为云环境构建可自动注册的虚拟机镜像

在云环境中部署可自动注册的加密镜像会带来一系列独特的挑战。与其他虚拟化环境一样,建议减少从一个镜像启动的实例数量,以避免共享 LUKS 主密钥。
因此,最佳实践是创建自定义映像,这些映像不在任何公共存储库中共享,为部署有限数量的实例提供了基础。要创建的实例的确切数量应由部署的安全策略定义,并且基于与 LUKS 主密钥攻击向量关联的风险容错能力。
要构建启用 LUKS 的自动化部署,应当使用 Lorax 或 virt-install 等系统以及一个 Kickstart 文件,来确保镜像构建过程中主密钥的唯一性。
云环境支持我们在这里考虑的两种 Tang 服务器部署选项。首先,Tang 服务器可以在云环境本身中部署。其次,Tang 服务器可以部署在云外的独立的基础架构上,并且这两个基础架构之间有 VPN 连接。
在云中原生部署 Tang 可以轻松部署。但是,考虑到它与其他系统的密文数据持久性层共享基础设施,因此 Tang 服务器的私钥和 Clevis 元数据可以存储在同一个物理磁盘上。对这个物理磁盘的访问允许密文数据的完全泄露。
重要
因此,红帽强烈建议在存储数据的位置和运行 Tang 的系统之间保持物理隔离。在云和 Tang 服务器之间的这种隔离可确保 Tang 服务器的私钥不会被意外与 Clevis 元数据组合。如果云基础设施面临风险,它还提供了对 Tang 服务器的本地控制。

4.10.12. 其它资源

如需更多信息,请参阅以下手册页:
  • tang(8)
  • clevis (1)
  • jose(1)
  • clevis-luks-unlockers(1)
  • tang-nagios(1)