注意
本文档适用于 Ceph 的开发版本。
HashiCorp Vault 集成
HashiCorp Vault可用作服务端加密 (SSE-KMS) 的安全密钥管理服务。
下面的一些示例使用 Vault 命令行实用程序与 Vault 交互。您可能需要使用正确的 Vault 服务器地址设置以下环境变量才能使用此实用程序
export VAULT_ADDR='https://vault-server-fqdn:8200'
Vault Secrets Engines
Vault 提供了几种 secrets engines,可以存储、生成和加密数据。目前,对象网关支持
KV Secrets Engine
KV secrets engine 用于在 Vault 中存储任意键值秘密。要在 Vault 中启用 KV engine 版本 2,请使用以下命令
vault secrets enable -path secret kv-v2
对象网关可以使用以下设置配置为使用 KV engine 版本 2
rgw crypt vault secret engine = kv
Transit Secrets Engine
Transit engine 处理传输中数据的加密功能。要在 Vault 中启用它,请使用以下命令
vault secrets enable transit
对象网关可以使用以下设置配置为使用 transit engine
rgw crypt vault secret engine = transit
Vault 身份验证
Vault 支持多种身份验证机制。目前,对象网关可以配置为使用令牌身份验证方法或Vault agent向 Vault 进行身份验证。
Vault 中的大多数令牌都有有限的生命周期和权限。Vault 令牌中唯一没有生命周期的是根令牌。对于所有其他令牌,需要定期刷新它们,要么通过执行初始身份验证,要么通过续订令牌。Ceph 没有执行任何操作的逻辑。将 Vault 令牌与 Ceph 一起使用的最简单方法是同时运行 Vault agent 并让它刷新令牌文件。当 Vault agent 以这种模式使用时,可以使用文件系统权限来限制谁可以使用令牌。
除了让 Vault agent 刷新令牌文件外,还可以告诉它充当代理服务器。在这种模式下,Vault 会在必要时添加一个令牌,并将其添加到传递给它的请求中,然后再将它们转发到实际服务器。Vault agent 仍将处理令牌续订,就像它在文件系统中存储令牌时一样。在这种模式下,有必要正确保护 RGW 用于访问 Vault agent 的网络路径,例如让 Vault agent 只侦听 localhost。
对象网关的令牌策略
所有 Vault 令牌都具有附加到该令牌的策略所指定的权限。多个策略可以与一个令牌相关联。您应该只使用配置所需的策略。
将 KV secret engine 与对象网关一起使用时
vault policy write rgw-kv-policy -<<EOF
path "secret/data/*" {
capabilities = ["read"]
}
EOF
将 transit secret engine 与对象网关一起使用时
vault policy write rgw-transit-policy -<<EOF
path "transit/keys/*" {
capabilities = [ "create", "update" ]
denied_parameters = {"exportable" = [], "allow_plaintext_backup" = [] }
}
path "transit/keys/*" {
capabilities = ["read", "delete"]
}
path "transit/keys/" {
capabilities = ["list"]
}
path "transit/keys/+/rotate" {
capabilities = [ "update" ]
}
path "transit/*" {
capabilities = [ "update" ]
}
EOF
如果您以前使用过较旧版本的 Ceph 和 transit secret engine,您可能需要以下策略
vault policy write old-rgw-transit-policy -<<EOF
path "transit/export/encryption-key/*" {
capabilities = ["read"]
}
EOF
如果您同时使用 SSE-KMS 和 SSE-S3,则应将每个指向单独的容器。您可以要么使用单独的 Vault 实例,要么使用单独挂载的 transit 实例,或者在公共 transit 点下使用不同的分支。如果您不使用单独的 Vault 实例,您可以使用这些来将 SSE-KMS 和 SSE-S3 指向单独的容器:rgw_crypt_vault_prefix 和/或 rgw_crypt_sse_s3_vault_prefix。在授予 SSE-KMS 桶所有者 Vault 权限时,您不应授予他们修改 SSE-S3 密钥的权限;只有 Ceph 本身应该这样做。
令牌身份验证
令牌身份验证方法需要 Vault 令牌存在于纯文本文件中。对象网关可以使用以下设置配置为使用令牌身份验证
rgw crypt vault auth = token
rgw crypt vault token file = /run/.rgw-vault-token
rgw crypt vault addr = https://vault-server-fqdn:8200
调整这些设置以匹配您的配置。出于安全原因,令牌文件必须只能由对象网关读取。
Vault Agent
Vault agent 是一个客户端守护程序,提供对 Vault 的身份验证并管理令牌续订和缓存。它通常与对象网关在同一主机上运行。使用 Vault agent,可以使用其他 Vault 身份验证机制,例如 AppRole、AWS、Certs、JWT 和 Azure。
对象网关可以使用以下设置配置为使用 Vault agent
rgw crypt vault auth = agent
rgw crypt vault addr = http://127.0.0.1:8100
您可以按如下方式设置 Vault agent
vault write auth/approle/role/rgw-ap \
token_policies=rgw-transit-policy,default \
token_max_ttl=60m
更改此处的策略以匹配您的配置。
获取 role-id
vault read auth/approle/role/rgw-ap/role-id -format=json | \
jq -r .data.role_id
将输出存储在某个文件中,例如 /usr/local/etc/vault/.rgw-ap-role-id。
获取 secret-id
vault read auth/approle/role/rgw-ap/role-id -format=json | \
jq -r .data.role_id
将输出存储在某个文件中,例如 /usr/local/etc/vault/.rgw-ap-secret-id。
为 Vault agent 创建配置,例如
pid_file = "/run/rgw-vault-agent-pid"
auto_auth {
method "AppRole" {
mount_path = "auth/approle"
config = {
role_id_file_path ="/usr/local/etc/vault/.rgw-ap-role-id"
secret_id_file_path ="/usr/local/etc/vault/.rgw-ap-secret-id"
remove_secret_id_file_after_reading ="false"
}
}
}
cache {
use_auto_auth_token = true
}
listener "tcp" {
address = "127.0.0.1:8100"
tls_disable = true
}
vault {
address = "https://vault-server-fqdn:8200"
}
然后使用 systemctl 或您选择的另一种方法运行具有以下参数的持久守护程序
/usr/local/bin/vault agent -config=/usr/local/etc/vault/rgw-agent.hcl
一旦 Vault agent 运行,您应该会发现它正在侦听 localhost 上的端口 8100,并且您应该能够使用 vault 命令与其交互。
Vault 命名空间
在企业版中,Vault 支持命名空间的概念,这允许对组织内的团队进行集中管理,同时确保这些团队在称为租户的隔离环境中操作。
可以使用以下配置设置配置对象网关以访问特定命名空间中的 Vault
rgw crypt vault namespace = tenant1
在 Vault 中创建密钥
注意
服务端加密的密钥必须为 256 位长且经过 base-64 编码。
使用 KV 引擎
可以使用命令行实用程序在 KV version 2 engine 中创建服务端加密密钥,如以下示例所示
vault kv put secret/myproject/mybucketkey key=$(openssl rand -base64 32)
示例输出
====== Metadata ======
Key Value
--- -----
created_time 2019-08-29T17:01:09.095824999Z
deletion_time n/a
destroyed false
version 1
请注意,在 KV secrets engine 中,秘密存储为键值对,对象网关要求键名是 key,即秘密必须采用 key=<secret key> 形式。
使用 Transit 引擎
为与 transit engine 一起使用而创建的密钥不应再标记为可导出。它们可以使用以下方式创建
vault write -f transit/keys/mybucketkey
上面的命令创建一个密钥环,默认包含一个类型为 aes256-gcm96 的密钥。要验证密钥是否已正确创建,请使用以下命令
vault read transit/keys/mybucketkey
示例输出
Key Value
--- -----
derived false
exportable false
name mybucketkey
type aes256-gcm96
配置 Ceph 对象网关
编辑 Ceph 配置文件以启用 Vault 作为服务端加密的 KMS 后端
rgw crypt s3 kms backend = vault
选择 Vault 身份验证方法,例如
rgw crypt vault auth = token
rgw crypt vault token file = /run/.rgw-vault-token
rgw crypt vault addr = https://vault-server-fqdn:8200
或者
rgw crypt vault auth = agent
rgw crypt vault addr = http://localhost:8100
选择 secrets engine
rgw crypt vault secret engine = kv
或者
rgw crypt vault secret engine = transit
(可选)设置将从中获取加密密钥的 Vault 命名空间
rgw crypt vault namespace = tenant1
最后,可以通过设置路径前缀来限制对象网关将从中检索加密密钥的 URL。例如,对象网关可以限制为按如下方式获取 KV 密钥
rgw crypt vault prefix = /v1/secret/data
或者,当使用 transit secret engine 时
rgw crypt vault prefix = /v1/transit
在上面的示例中,对象网关将仅获取 https://vault-server:8200/v1/transit 下的 transit 加密密钥。
您可以使用自定义 SSL 证书通过以下选项向 Vault 进行身份验证
rgw crypt vault verify ssl = true
rgw crypt vault ssl cacert = /etc/ceph/vault.ca
rgw crypt vault ssl clientcert = /etc/ceph/vault.crt
rgw crypt vault ssl clientkey = /etc/ceph/vault.key
其中 vault.ca 是 CA 证书,vault.key/vault.crt 是为 RGW 访问 Vault 服务器而生成的私钥和 SSL 证书。强烈建议将此选项设置为 true,设置 false 非常危险,需要避免,因为它在非常安全的环境中运行。
Transit 引擎兼容性支持
Transit engine 对以前版本的 Ceph 具有兼容性支持,这些版本将 transit engine 用作简单的密钥存储。
有一个 compat 选项可以提供给 transit engine 来配置兼容性支持,
要完全禁用向后支持,请使用
rgw crypt vault secret engine = transit compat=0
这将是未来版本中的默认设置。对于使用当前版本的新安装,使用它是安全的。
这是当前版本的正常默认设置
rgw crypt vault secret engine = transit compat=1
这为新创建的对象启用了新引擎,但仍允许旧引擎用于旧对象。为了访问新旧对象,授予 Ceph 的 Vault 令牌必须同时具有旧的和新的 transit 策略。
要强制仅使用旧引擎,请使用
rgw crypt vault secret engine = transit compat=2
如果 Vault 前缀以 export/encryption-key 结尾(这是以前记录的设置),则会自动选择此模式。
上传对象
将对象上传到对象网关时,请在请求中提供 SSE 密钥 ID。例如,对于 KV engine,使用 AWS 命令行客户端
aws --endpoint=http://radosgw:8000 s3 cp plaintext.txt s3://mybucket/encrypted.txt --sse=aws:kms --sse-kms-key-id myproject/mybucketkey
例如,对于 transit engine(新版本),使用 AWS 命令行客户端
aws --endpoint=http://radosgw:8000 s3 cp plaintext.txt s3://mybucket/encrypted.txt --sse=aws:kms --sse-kms-key-id mybucketkey
对象网关将从 Vault 获取密钥,加密对象并将其存储在存储桶中。任何下载对象的请求都将使对象网关自动从 Vault 检索相应的密钥并解密对象。
请注意,将使用由基本地址 (rgw crypt vault addr)、(可选)URL 前缀 (rgw crypt vault prefix) 和最后的密钥 ID 拼接而成的 URL 从 Vault 中获取秘密。
在上面的 KV engine 示例中,对象网关将从以下位置获取秘密
http://vaultserver:8200/v1/secret/data/myproject/mybucketkey
在上面的 transit engine 示例中,对象网关将使用此密钥加密秘密
http://vaultserver:8200/v1/transit/mybucketkey