用于运行以太坊验证器的 亚马逊云科技 Nitro Enclaves — 第 2 部分

在本系列 的 第 1 部分 中,我们简要介绍了 基于 亚马逊云科技 Nitro Enclaves 的 W eb3Sign er 区块链验证和签名服务 。我们解释了运行区块链验证器的目的,以及为什么 Nitro Enclaves 非常适合运行对安全敏感的加密工作负载。

此外,我们还介绍了高级应用程序架构,并简要解释了安全引导和安全签名流程。

GitHub 上的 演练 中 ,我们举了一个端到端的示例,说明如何部署和配置基于 Nitro Enclave 的 Web3Signer 解决方案。

在这篇文章中,我们深入探讨了三个领域:

  • Web3Signer 集成模式 — 如何将不同的以太坊验证器节点与单个 Web3Signer 节点集成
  • 在 Nitro Enclave 内安全引导 Web3Signer — 如何以安全的方式将私钥等安全敏感配置文件注入 Nitro Enclave,以及如何将这些配置工件用于 HTTPS 端点
  • 通过 vsock 公开 Web3Signer HTTPS API — 如何以透明的方式通过 vsock 连接传送传输层安全 (TLS) 流量,从而与在 Nitro Enclave 内运行的 Web3Signer 服务建立安全通信

与 Web3Signer 集成以进行以太坊验证

为了能够与 Web3Signer 集成,验证器客户端需要支持与 BLS 远程签名者的连接 (EIP-3030)。 L ighthou se 、 Prysm Teku 等流行的验证器客户端已经支持远程签名。多个验证器客户端可以连接到负载均衡器后面的同一 Web3Signer 实例。 至关重要的是,不要将验证器客户端配置为使用相同的验证器密钥,这可能会导致验证器被削减。 当多个验证器客户端同时运行时,验证器客户端削减保护无效。例如,下图显示验证器客户端 1 使用验证器密钥 0xa957cf9 和 0xb821 c 31,这意味着验证器客户端 2 不能再使用这两个密钥。取而代之的是,验证器客户端 2 使用密钥 0x8f1942c ,任何验证器客户端都不使用该密钥。

在随附的 亚马逊云科技 云开发套件 (亚马逊云科技 CDK) 代码 中 ,Web3Signer 未配置为使用客户端身份验证。但是,对于生产部署,应将 Web3Signer 配置为使用以下方法之一的客户端身份验证:

  • 为每个验证器客户端生成证书- 使用证书创建已知的客户端文件并将其加载到 Web3Signer 中。此方法操作复杂,但撤销是可能的,因为我们只需要修改 Web3Signer 中的已知客户端文件即可。
  • 配置 Web3Signer 以允许拥有可信 CA 证书的验证器客户端进行连接- 此方法在操作上更容易;但是,需要维护私有证书颁发机构 (CA) 服务器来为每个验证器客户端颁发证书。在撰写本文时,撤销功能仍在开发中。

有关客户端身份验证的更多信息,请参阅 配置 TLS。

在 Nitro 飞地内安全启动 Web3Signer

要安全地在 Nitro Enclave 内运行 Web3Signer 服务,需要以下两个配置工件:

  • 用于保护 Web3Signer HTTPS API 的 TLS 密钥对
  • EIP-2335 指定的密钥库文件,包含加密的 BLS12-381 验证器私钥

这两个配置项目都需要通过对称的 亚马逊云科技 密钥管理服务 (亚马逊云科技 KMS) 密钥进行加密。

用于对配置工件进行对称加密的 KMS 密钥需要配置密钥策略,以便授权使用加密认证从安全区内部发起的 KMS: Decrypt 操作。有关如何为该解决方案配置 KMS 密钥策略的更多详细信息,请参阅 GitHub 上的 解决方案演练

在这个解决方案中,我们使用两个 亚马逊 Dynamo DB 表来存储配置工件:一个用于 tlsKeys 的表 ( tlsKeytab le) 和一个单独的验证器密 钥表 (validatorKeyTable)。

tlsKeyTable 使用以下架构:

{
	"key_id": "<>",
	“cert_pem”: "<base64 encloded x509 certificate>",
	“encrypted_tls_key_b64”: "<encrypted private key>" 
}

validatorKeyTable 强制执行以下架构:

{
	“Web3Signer_uuid”: “<stack uuid>”,
	“pubkey”: “<public key>”,
	“active”: "<true/false>",
	“chain”: “<ethereum network>”,
	“datetime”: “<time of creation>”,
	“deposit_json_b64”: “<>”,
	“encrypted_key_password_mnemonic_b64”: “<>”
}

正如我们之前指出的那样,为了能够启动引导过程,需要通过对称 KMS 密钥对 TLS 密钥和 EIP-2335 密钥库文件进行加密,生成的密文需要存储在 DynamoDB 表中。

通过协调架构定义,可以启动不同的安全 Web3Signer 进程,每个进程都有一个唯一的 TLS 密钥和不同(>=1)的验证器密钥,只需传递一个 TLS key_id 和 Web3Signer _UUID 密钥数组作为引导过程的 参数即可。

下图描述了引导流程。

该流程包括八个步骤:

  1. n itro-signing-server systemd 服务启动 watchdog.py 进程。 监视程序进程从 DynamoDB 表中读取加密的 Web3Signer 配置资产(TLS 密钥、验证器密钥)。
  2. 监视程序启动 Web3Signer 飞地。一旦安全区启动并运行,监视程序就会通过发送以下负载来调用 安全区的初始化 操作。 encr@@ ypted_tls_key 和 en cry pted_validator_keys 包含从 DynamoDB 表中下载的配置项目。证书代表监视程序收集的临时 AWS 安全证书。
    
    payload = {“操作”:“初始化”,“凭证”:凭据,“encrypted_tls_key”:encrypted_tls_key,“encrypted_validator_key”:encrypted_validator_key,} 
     
    
  3. 在 Web3 Signer 安全区内运行的 enclave_in it 进程会验证传入的初始化请求,确保包含所有必需的参数 。 如果所有必需的参数都存在,则使用 kmstool-enclave-cli 来解密传递给 Web3Signer 安全区的 TLS 和验证器密钥。
  4. kmstool-enclave-cli 通过 vsock-proxy 与 亚马逊云科技 KMS 建立安全的出站连接 ,使用 加密认证来解密配置工件。
  5. 如果使用 加密认证成功执行 KMS: Decr ypt 操作,则解密后的文件将转换为正确的文件格式并写入安全区的内存文件系统。 enclave_init 进程启动 Web3Signer 进程。
  6. Web3Signer 进程读取配置文件,解密密钥库文件中的加密私钥,然后在安全区的本地主机接口上启动 HTTPS 侦听器。
  7. 验证器客户端必须将 Web3Signer 配置为其远程签名解决方案,例如 Lighthouse 远程签名 ,如本文前面所述。
  8. 正确配置后,验证器客户端可以连接到通过 https_proxy 公开的 Web3Signer HTTPS 端点。 有关如何通过 vsock 连接对 HTTPS 流量进行隧道传输的更多详细信息,请参阅本文的下一节。

由于 Nitro Enclave 的内存文件系统的临时性质,每次停止并重启安全区或父 亚马逊弹性计算云 (Amazon EC2) 实例时,都会运行引导过程。

通过 vsock 公开 Web3Signer HTTPS API

Vsock 是 EC2 父实例与其安全区之间的本地通信通道。它是安全区可以用来与外部服务进行交互的唯一通信渠道。

要建立安全连接,例如使用 TLS、从父实例内部或从 亚马逊云科技 Lambda 函数与 EC2 父实例在同一 Amazon VPC 中运行的 亚马逊云科技 Lambda 函数建立安全连接,需要通过 vsock 连接转发加密流量。

以下两节详细解释了如何使用 vsock 代理进程建立 HTTPS (TLS) 入站和出站连接。这些数字与下图中的不同状态相关联。

该图还描述了在 亚马逊云科技 CDK 部署过程中配置的所有相关组件的监听器/端口配置。

像 16:5000 这样的表示形式指的是 vsock 侦听器 , 其中 16 表示 32 位 上下文标识符 (CID),5000 表示端口。像 0.0.0. 0:443 这样的元组指的是 互联网套接字侦听器 , 其中 0.0.0.0 指的是 IPv4 地址,443 指定端口。

HTTPS 入站流

HTTPS 入站流程包含以下步骤:

  1. 在给定的解决方案中, https_prox y 就像一个 TCP 代理,在 AF_INET 和 AF_VSOCK 之间进行转换。 它在 0.0.0. 0:443 上接受来自验证器客户端的传入互联网套接字请求。
  2. https_proxy 与一个单独的 vsock_proxy 进程 建立 vsock 连接,该进程在安全 区内运行,监听 16:5000 。然后,它通过此连接转发所有收到的 TCP 数据包。
  3. 对于每个传入的 vsock 连接, vsock_proxy 都会通过 Web3Signer HTTPS API 建立互联网 TCP 连接,后者在 127.0.0. 1:9000 上进行监听。
  4. Web3Signer 通过已建立的 TCP 连接进行响应。
  5. 收到 Web3Signer 响应后, vsock_proxy 通过已建立的 vsoc k 连接将 TCP 数据包 转发到在父实例上运行的 https_proxy。
  6. https_proxy 关闭 vsock 连接并将 TCP 包转发回请求客户端。

HTTPS 出站流

源自指向 亚马逊云科技 KMS 的 kmstool-enclave-cli 二进制文件的出站 HTTPS 连接使用的机制与前面解释的类似。步骤如下:

  1. kmstool-enclave-cli 与在 EC 2 父实例上运行的 vsock_proxy 进程 建立了 vsock 连接,监听时间为 3 :8000
  2. vsock_proxy 与 AWS KMS 建立 TCP 连接。
  3. 亚马逊云科技 KMS 通过已建立的 TCP 连接响应 vsock_proxy
  4. vsock_proxy 通过开放的 vsock 连接将 亚马逊云科技 KMS 的响应 转发到安全区。 kmstool-enclave-cli 关闭了 vsock 连接

使用这种机制,可以将 HTTPS 请求安全地代理进出安全区。

需要指出的是,用于验证 Web3Signer 端点的 X509 证书需要将父 EC2 实例的主机名设置为 CN,否则主机名验证将失败。

此外,使用这种 HTTPS 隧道机制并让 Web3Signer 在 Nitro Enclave 内停止 TLS 会话可能会由于加密操作而导致 CPU 负载增加。

除了保护 Web3Signer 在 Nitro Enclave 内所需的验证器私钥等敏感配置负载外,还通过公开 Web3Signer HTTPS API 引入了新的潜在攻击向量。由于 HTTPS 端点暴露在 私有子网 中,身份验证变得至关重要 。在本文前面我们已经详细阐述了 Web3Signer 支持的两种不同的身份验证选项。此外,重要的是要注意用于构建 Web3Signer 的下游依赖关系,以避免利用 He artb leed OpenSSL 错误等问题。

您可以使用不同的工具和开源库通过 vsock 对 TLS 连接进行隧道传输:

  • traffic-forwarder.py 亚马逊云科技 Nitro Enclaves 研讨 会中使用的脚本
  • viproxy — GitHub 上的开源 Go(lang)库
  • socat — 一款多功能 Linux 网络实用程序

结论

在这篇文章中,我们深入解释了如何将 Web3Signer 与验证器客户端集成。我们还深入探讨了安全的引导过程,最后详细解释了如何通过 vsock 公开 Web3Signer HTTPS API。

您可以自定义 解决方案 并在 A W S 上部署自己的 Nitro Enclave 安全验证器节点!


作者简介

David-Paul Dornseifer 是 亚马逊云科技 全球专业解决方案架构师组织的一名区块链架构师。他专注于帮助客户设计、部署和扩展端到端的区块链解决方案。

Aldred Hal im 是 亚马逊云科技 全球专业解决方案架构师组织的解决方案架构师。他与客户紧密合作,设计架构和构建组件,以确保在 亚马逊云科技 上成功运行区块链工作负载。