使用 MinIO 和 HashiCorp Vault 轻松揭开秘密
企业需要安全性来保护系统,主要关注静态数据和传输中的数据。一个可行的安全程序有很多方面,这篇博文重点介绍加密密钥管理。加密和相关密钥是确保数据安全的因素。例如,网站需要客户端和服务器(在本例中为浏览器和 Web/应用程序服务器)之间的证书握手。在后端,在多语言架构中管理多个环境和许多微服务需要有效管理凭证。存储在对象存储解决方案中的数据可能需要满足合规性要求并受到保护,每个对象都需要加密和存储,并在需要时解密。出于这些原因,基础架构和安全团队需要可靠的保管库解决方案。
产品/应用程序需要加密数据:当产品/应用程序可以仅依靠 Hashicorp 的 Vault 来提供此功能时,他们不需要通过加密来复杂化其实现。Vault 专注于签署和验证数据,而不是存储数据。MinIO 和 Vault 等应用程序的组合将确保满足静态数据的安全要求。
保护数据库和 Web 服务凭证:具有多语言数据库的微服务架构以及与多个 Web 服务或微服务的集成是司空见惯的。此外,总是有多个环境。通过基础设施即代码和自动化,管理凭据和访问密钥变得至关重要,因此有必要拥有高性能的密钥管理和存储解决方案,例如 Vault 和 KES。
传输中数据的证书:无论是从浏览器访问的网站,应用程序和数据库之间的通信,从应用程序到 Web 服务或微服务之间的通信,都必须加密每个之间的通信通道。Vault 可以生成 PKI 证书,这些证书可用于保护这些通道中传输的数据。
为了提供围绕安全锁定和擦除的合规性功能,MinIO通过使用服务器端加密 (SSE) 在存储层加密对象,以保护对象作为写操作的一部分。MinIO 以极高的效率做到这一点——基准测试表明 MinIO 能够以接近线速的速度进行加密/解密。
MinIO 是如何达到这种效率和性能水平的?
MinIO 使用的秘诀是单指令多数据(SIMD)。通常一次只能发送一条CPU指令,等待响应再发送下一条指令。这是非常低效的,尤其是在每秒执行数千(如果不是数百万)的加密和解密指令时。MinIO 利用 SIMD,因此它可以在单个请求中发送多条指令以供 CPU 处理。我们在 GoLang 中用汇编编写了这个,因此我们尽可能接近硬件层,以充分利用通常未充分利用的 CPU 能力来大规模执行加密操作。
HashiCorp 的Vault与 MinIO 共享许多相同的思维过程和设计价值观——从而产生了功能强大且使用愉快的互补软件。例如,Vault 几乎可以在任何环境中运行。它与云无关,这意味着它可以在 AWS、GCP、Azure 甚至裸机上运行。由于 Vault 只是一个二进制文件,因此启动和运行起来非常容易。如果您在笔记本电脑上进行开发,您可以在开发模式下运行它,当您准备好转移到生产环境时,您可以将它扩展到多个节点以形成一个集群。
Vault 在多个用例中也非常通用。一个这样的用例是管理 LUKS(Linux 统一密钥设置)的密钥,它通常将密钥存储在执行加密和解密操作的同一卷上。显然,这是一个巨大的安全问题,因为密钥与数据一起存储。相反,我们可以在启动时查询 Vault 服务以获取 LUKS 执行加密操作所需的密钥。这样即使数据受到威胁,密钥也不会在卷上,因此除了利用 Vault 之外没有其他方法可以解密数据。
MinIO 的密钥加密服务 (KES)将这一切结合在一起。SSE 使用 KES 和 Vault 来执行加密操作。KES 服务本身是无状态的,在将数据存储在 Vault 中时充当中间层。使用 MinIO,您可以设置各种级别的粒度和可自定义的加密。您始终可以选择基于每个对象进行加密,但是,我们强烈建议在存储桶上自动设置 SSE-KMS 加密,以便默认情况下对所有对象进行加密。加密是使用存储在 Vault 中的特定外部密钥 (EK) 完成的,可以使用唯一密钥在每个对象的基础上覆盖它。

在这篇博文中,我们将向您展示如何快速启动并运行 MinIO、KES 和 Vault,以充分了解服务器端加密的功能。
设置基础设施
首先,在您的笔记本电脑或云中启动一个 Linux VM,我们可以在其中安装这些组件。通过 SSH 进入此虚拟机并确保您以 root 用户身份或使用sudo. 在这篇博文中,我们使用的是普通的 Ubuntu VM。
最小IO
我们将设置此配置以启动单节点单驱动器设置,以便我们更好地形象化概念。您可以轻松地将本教程扩展到分布式设置。
下载 MinIO 二进制文件并将其移动到可执行位置
# wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio_20221126224332.0.0_amd64.deb -O minio.deb # dpkg -i minio.deb
同时安装 MinIO 客户端
# wget https://dl.min.io/client/mc/release/linux-amd64/mc # chmod +x mc # mv mc /usr/local/bin/mc
将软件包安装到 VM 后,暂时不要启动 MinIO 服务。在开始之前,我们需要设置一些额外的先决条件。
凯斯
KES 作为自己的服务运行,是 MinIO 和 Vault 服务之间的中介。
在 VM 上设置以下目录以添加我们生成的证书。
# mkdir -p /opt/kes/certs # mkdir -p /opt/kes/config # mkdir -p /opt/minio/certs # mkdir -p /opt/minio/config # mkdir -p ~/minio
从 MinIO KES 存储库中获取 KES 二进制文件
# wget https://github.com/minio/kes/releases/download/v0.22.1/kes-linux-amd64
修改 KES 二进制文件并将其移动到PATH可执行位置
# chmod +x kes-linux-amd64 # mv kes-linux-amd64 /usr/local/bin/kes # kes --version
再次强调,暂时不要启动 KES 服务器,在启动之前我们还需要配置一些东西。
金库
KES 要求 Vault 处于运行状态且未密封,然后才能与之通信。
让我们使用以下步骤安装 Vault
打开一个新的 tmux 会话来运行 Vault 操作
# tmux new -s vault
安装用于添加 apt 密钥的 GPG 包
# apt update && apt install gpg
获取 Hashicorp apt 回购密钥
# wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor | sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg >/dev/null
验证指纹
# gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint
添加 Hashicorp apt repo,以便我们可以安装 Vault 包
# echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
最后但同样重要的是,安装 Vault 本身
# apt update && apt install vault
启动 Vault 服务器,这也会为我们解封它
# vault server -dev
一旦 Vault 启动,记下 Vault Endpoint 和 Vault Root Token。稍后您将需要这些值来在 Vault 中执行操作。
$ export VAULT_ADDR='http://127.0.0.1:8200' [TRUNCATED] Root Token: hvs.rCFo4tdgIdiq5NTRo6VzbBGz
使用以下按键结束 tmux 会话
CTRL+B 然后按 D
配置基础设施
一旦我们设置了基础设施,我们就需要配置各个组件
金库
在 Vault TMUX 会话之外,设置以下环境变量
金库地址
保险柜令牌
这些值可以在 Vault 服务启动时的早期输出中找到。
# export VAULT_ADDR='http://127.0.0.1:8200' # export VAULT_TOKEN="hvs.rCFo4tdgIdiq5NTRjrVzbBGz"
创建一个名为 Vault 的秘密引擎路径kv/
# vault secrets enable -path=kv kv Success! Enabled the kv secrets engine at: kv/
启用 Vault 应用程序角色以支持 KES。这用于 KES 通过分配所需的权限并检索 KES 的 App ID 和 Secret 来对 Vault 应用程序进行身份验证。
# vault auth enable approle Success! Enabled approle auth method at: approle/
创建一个包含kes-policy.hcl以下内容的文件,以便为kv/我们之前创建的引擎提供必要的访问权限。
path "kv/data/*" {
capabilities = [ "create", "read"]
}
path "kv/metadata/*" {
capabilities = [ "list", "delete"]
}应用上面的文件在 Vault 中创建策略
# vault policy write kes-policy kes-policy.hcl Success! Uploaded policy: kes-policy
创建一个名为的应用程序角色kes-role并为其分配我们在上一步中创建的策略
# vault write auth/approle/role/kes-role token_num_uses=0 secret_id_num_uses=0 period=5m Success! Data written to: auth/approle/role/kes-role # vault write auth/approle/role/kes-role policies=kes-policy Success! Data written to: auth/approle/role/kes-role
KES
为 KES 创建 TLS 证书以保护 KES 和 Vault 部署之间的通信
# kes identity new kes_server \ --key /opt/kes/certs/kes-server.key \ --cert /opt/kes/certs/kes-server.cert \ --ip "127.0.0.1" \ --dns localhost
接下来我们为MinIO设置一个TLS证书来对KES进行mTLS认证
# kes identity new minio_server \ --key /opt/minio/certs/minio-kes.key \ --cert /opt/minio/certs/minio-kes.cert \ --ip "127.0.0.1" \ --dns localhost
使用以下内容创建 KES 配置文件/opt/kes/config/kes-config.yaml。我们将解释如何获取填写配置所需的信息。
address: 0.0.0.0:7373 admin: identity: disabled tls: key: /opt/kes/certs/kes-server.key cert: /opt/kes/certs/kes-server.cert policy: minio: allow: - /v1/key/create/* - /v1/key/generate/* # e.g. '/minio-' - /v1/key/decrypt/* identities: - MINIO_IDENTITY_HASH keystore: vault: endpoint: http://localhost:8200 engine: "kv/" # Replace with the path to the K/V Engine version: "v2" # Specify v1 or v2 depending on the version of the K/V Engine approle: id: "VAULTAPPID" # Hashicorp Vault AppRole ID secret: "VAULTAPPSECRET" # Hashicorp Vault AppRole Secret ID retry: 15s status: ping: 10s
以下是您获取必要信息的方法。
MINIO_IDENTITY_HASH使用以下命令获取
# kes identity of /opt/minio/certs/minio-kes.cert
获取VAULTAPPID并VAULTAPPSECRET使用以下命令
我们输出的键看起来像这样
# vault read auth/approle/role/kes-role/role-id Key Value --- ----- role_id 6924d20f-31b3-xxxx-6182-5fce1fd52d37 # vault write -f auth/approle/role/kes-role/secret-id Key Value --- ----- secret_id 0d6d8576-6a74-8f7f-xxx-785a5ec6fb3d secret_id_accessor 16442cd9-8ba6-e730-042a-6ff756f2947f secret_id_num_uses 0 secret_id_ttl 0s
最小IO
最后但同样重要的是,配置 MinIO
在/opt/minio/config/minio添加以下配置
MINIO_KMS_KES_ENDPOINT=https://localhost:7373 MINIO_KMS_KES_CERT_FILE=/opt/minio/certs/minio-kes.cert MINIO_KMS_KES_KEY_FILE=/opt/minio/certs/minio-kes.key MINIO_KMS_KES_CAPATH=/opt/kes/certs/kes-server.cert MINIO_KMS_KES_KEY_NAME=minio-backend-default-key
打开一个新的 tmux 会话以启动 KES 服务
# tmux new -s kes
kes-config.yaml使用我们之前创建的文件启动 KES 服务
# setcap cap_ipc_lock=+ep $(readlink -f $(which kes)) # kes server --auth=off --config=/opt/kes/config/kes-config.yaml
使用以下按键从 tmux 会话中分离出来
CTRL+B 然后按 D
现在我们已经有了 KES 所需的所有附加服务,让我们启动 MinIO 服务。
打开一个新的 tmux 会话以使用我们之前创建的配置文件启动 MinIO 服务
# tmux new -s minio
# export MINIO_CONFIG_ENV_FILE=/opt/minio/config/minio # minio server ~/minio --console-address :9001
启动 MinIO 后,使用以下按键从 tmux 会话中分离
CTRL+B 然后按 D
测试 MinIO、KES 和 Vault
此时,您应该拥有使 SSE 工作所需的组件。做个好网民,测试一下吧。
生成新的加密桶密钥
# export KES_SERVER=https://127.0.0.1:7373 # export KES_CLIENT_KEY=/opt/minio/certs/minio-kes.key # export KES_CLIENT_CERT=/opt/minio/certs/minio-kes.cert # kes key create -k encrypted-bucket-key
在 MinIO 中创建一个桶,并默认为每个添加到桶中的对象启用自动加密。
# mc alias set local http://127.0.0.1:9000 minioadmin minioadmin # mc mb local/encryptedbucket Bucket created successfully `local/encryptedbucket`. # mc encrypt set SSE-KMS encrypted-bucket-key local/encryptedbucket Auto encryption configuration has been set successfully for local/encryptedbucket
将对象添加到桶中使用cp
## mc cp file.txt local/encryptedbucket/file.txt /root/file.txt: 5 B / 5 B ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 161 B/s 0s
最后是 pièce de resistance。验证我们刚刚添加的对象是否已加密。我们可以使用stat命令来做到这一点。
# mc stat local/encryptedbucket/file.txt Name : file.txt Date : 2022-11-28 19:30:05 UTC Size : 5 B ETag : add93d98cf5931d7642118efded8aa20 Type : file Metadata : Content-Type: text/plain Encrypted : X-Amz-Server-Side-Encryption-Aws-Kms-Key-Id: arn:aws:kms:encrypted-bucket-key X-Amz-Server-Side-Encryption : aws:kms
您还可以通过列出kv/引擎中的所有 Vault 密钥来进行验证。
# vault kv list kv/data Keys ---- encrypted-bucket-key minio-backend-default-key
如果您看到类似于上面的输出,那么您已成功配置 SSE。那不是那么难吗?现在你知道为什么以及如何加密存储在 MinIO 中的数据了。
最后的想法
这篇博文主要关注服务器端加密 (SSE)、密钥加密服务 (KES) 和密钥管理系统(KMS,使用 Vault)。我们向您展示了开始使用 SSE 是多么简单,而且加密的好处远远超过设置其他组件所需的工作量 (LOE)。您现在可以“左移”并在开发和规划过程的早期实施安全最佳实践;安全和数据保护永远不应该是事后的想法。通过关注 SSE 及其使用和理解的简单性,我们希望您能够将其作为所有 MinIO 部署的标准来实现。
您刚刚完成的是对 MinIO-KES-Vault 的介绍。要将您的学习环境发展为生产环境,您必须确保通过来自可信 CA(例如LetsEncrypt)的适当有效证书遵循 TLS 最佳实践。使用不同的证书来保护 MinIO -> KES 和 KES -> Vault 之间的通信。与多服务器多驱动设置中的 MinIO 类似,KES 也应该使用此处的说明在多个节点上设置。这同样适用于 Vault,您应该使用行业最佳实践来设置生产分布式设置,该设置与 MinIO 基础架构的其余部分不在同一节点上,因为 Vault 也有可能与其他服务一起使用。
我们希望您发现这篇教程博客文章有助于理解这个重要主题。与往常一样,如果您有任何问题,请随时在Slack上与我们联系!