引用 HashiCorp Vault 中的密钥
HashiCorp Vault 是一个集中式平台,用于管理跨不同环境和应用程序的密钥和加密。它为存储和访问(例如 API 密钥、密码、证书等)提供了统一的密钥管理。
本教程演示了如何将 API7 企业版与 HashiCorp Vault 集成,使你能够从 Vault 中安全地存储和引用消费者凭证及插件配置。
下面是一个交互式演示,提供了将 API7 企业版与 HashiCorp Vault 集成 存储和检索 key-auth 密钥的动手实践。
前置条件
- 安装 API7 企业版。
- 在你的网关组中至少有一个网关实例。
- 安装 Docker。
- 安装 cURL 以向服务发送请求进行验证。
- 安装 ZIP 以解压来自官方发布的压缩文件中的 Vault 二进制文件。
配置 Vault 服务器
在 Docker 中以开发模式启动一个名为 api7-quickstart-vault 的 Vault 实例,并使用令牌api7-quickstart-vault-token。暴露的端口将映射到主机的 8200 端口上:
docker run -d --cap-add=IPC_LOCK \
-e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \
-e 'VAULT_ADDR=http://127.0.0.1:8200' \
-e 'VAULT_DEV_ROOT_TOKEN_ID=api7-quickstart-vault-token' \
-e 'VAULT_TOKEN=api7-quickstart-vault-token' \
--name api7-quickstart-vault \
-p 8200:8200 vault:1.13.0
在 Vault 中启用 kv 密钥引擎,作为 API7 SSL 证书的存储路径。
docker exec api7-quickstart-vault vault secrets enable -path=kv -version=1 kv
API7 网关需要有权访问 Vault 并检索密钥。你需要使用 HashiCorp Configuration Language (HCL) 创建一个策略文件,从而为 API7 网关生成一个 Vault 访问令牌。
在 Vault 实例中创建一个名为 api7-policy.hcl 的 Vault 策略文件,以授予 API7 网关对路径 kv/ 的读取权限。你可以将密钥放在 kv/ 路径下以允许 API7 网关读取它们:
docker exec api7-quickstart-vault /bin/sh -c "echo '
path \"secret/data/*\" {
capabilities = [\"read\"]
}
' > /etc/api7-policy.hcl"
将该策略文件应用到 Vault 实例中:
docker exec api7-quickstart-vault vault policy write api7-policy /etc/api7-policy.hcl
接下来,生成附加到新定义的策略的访问令牌,以供 API7 网关访问 Vault:
docker exec api7-quickstart-vault vault token create -policy="api7-policy"
每次执行上述命令都会生成一个不同的令牌。如果成功,输出应类似于以下内容:
Key Value
--- -----
token hvs.CAESIHUznrV4wgcifUia0FROd6iprK7NjipAiHBYwiZDQP9TGh4KHGh2cy5ndHc5dzBPbXd5Y1pzblZXd2ZuQXA3ZHI
token_accessor YY4iCj2lICDNd50ZJDsBjvZK
token_duration 768h
token_renewable true
token_policies ["api7-policy" "default"]
identity_policies []
policies ["api7-policy" "default"]
在网关组中添加密钥提供商
- Dashboard
- ADC
- Ingress Controller
- 从侧边导航栏选择你的网关组下的 Secret 提供商,然后点击 新增 Secret 提供商。
- 在弹出的对话框中,执行以下操作:
- 在 Secret 提供商 ID 字段中,输入
my-vault。 - 在 Secret 管理服务 字段中,选择
HashiCorp Vault。 - 在 KV 版本 字段中,选择
KV 版本 1。 - 填写 Vault 服务器 URL字段。例如:
127.0.0.1:8200。 - 填写 Secret 前缀字段。例如:
kv/api7。 - 在 认证方式字段中,选择
Token。 - 填写 令牌字段。
- 点击 新增。
- 复制 Secret 变量以供将来引用。所有密钥引用均由此生成,例如:
$secret://vault/my-vault/$secret_name/$key。
不适用。
API7 Ingress Controller 目前不支持密钥提供商。
引用 SSL 证书的密钥
SSL 证书对象中的敏感字段 certificate 和 private key 可以安全地存储在外部密钥管理器(例如 HashiCorp Vault 或 AWS Secret 管理服务)中,并在 API7 网关中被引用。
存储密钥
为证书和私钥创建两个密钥,并将它们存储在 Vault 的 kv/api7/ssl 路径下。请确保该路径与你配置的密钥前缀一致:
docker exec api7-quickstart-vault vault kv put kv/api7/ssl crt="MIIDHzCCAgegAwIBAgIUXO7pD7m/P9R9uMh8Y+Q4h1Q+E4YwDQYJKoZIhvcNAQEL\nBQAwRTELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCVhpYW1lbmd4aWExDjAMBgNVBAoM\nBU15Q29tMQ0wCwYDVQQDDARUZXN0MB4XDTI0MDMxMzE1NDkyOFoXDTI1MDMxMzE1\nNDkyOFowRTELMAkGA1UEBhMCQ04xEjAQBgNVBAgMCVhpYW1lbmd4aWExDjAMBgNV\nBAoMBU15Q29tMQ0wCwYDVQQDDARUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\nMIIBCgKCAQEAyYt7Xm4w2T5L/pXJ39j9WzQ13w1/mUa4gC77V9p0+f9w8j+yK0Y\nb/q2/Vb+b/0/vj9s7d38/7Xq+Gq2q8rB+7j1y/6t/d/v/w/q9y+2b7Jv/J38/9r/\nn9u/b/7/x/3f+D9x/z/v/x/3P7D/r/7/8P6/8/+/0/v/7f7z+2/3P7P+7/6/7v+7\nf3/9/8P3P9v9z+7/7v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v\n8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v8v"
docker exec api7-quickstart-vault vault kv put kv/api7/ssl private-key="VGhpcyBpcyBhIHNpbXVsYXRlZCBwcml2YXRlIGtleSBmb3IgZGVtb25zdHJhdGlvbiBwdXJwb3NlcyBPTkxZLiBETyBOT1QgdXNlIHRoaXMgaW4gcHJvZHVjdGlvbiEK"
添加 SSL 证书
- 从侧边导航栏选择你的网关组下的 证书,进入 SSL 证书选项卡。
- 点击 新增 SSL 证书。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
Test SSL Certificate。 - 在 证书字段中,输入
$secret://vault/my-vault/ssl/crt。 - 在 私钥字段中,输入
$secret://vault/my-vault/ssl/private-key。 - 点击 新增。
当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将是 kv/api7/ssl/crt。
- 想要全面使用和验证 SSL 证书,请参阅在客户端与 API7 网关之间配置 mTLS。
引用密钥创建消费者凭证
消费者凭证中的以下敏感字段可存储在外部密钥管理器(HashiCorp Vault、AWS Secret 管理服务 等)中并在 API7 网关中引用:
- 密钥认证(Key Authentication)凭证中的
key - 基本认证(Basic Authentication)凭证中的
password - JWT 认证凭证中的
secret和public key - HMAC 认证凭证中的
secret key
新增消费者
- Dashboard
- ADC
- Ingress Controller
- 从侧边导航栏选择你的网关组下的 消费者。
- 点击 新增消费者。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
Alice。 - 点击 新增。
若使用 ADC 创建消费者,请创建以下配置:
consumers:
- username: Alice
将配置同步到 API7 企业版:
adc sync -f consumer.yaml
API7 Ingress Controller 目前不支持密钥提供商。
存储密钥
为密钥认证凭证创建一个密钥 key=alice-primary-key,并将其存储在 Vault 的 kv/api7/consumer/alice 路径下。请确保该路径与你配置的密钥前缀一致:
docker exec api7-quickstart-vault vault kv put kv/api7/consumer/alice key=alice-primary-key
预期的响应类似于以下内容:
=== Secret Path ===
kv/data/api7/consumer/alice
======= Metadata =======
Key Value
--- -----
created_time 2023-03-15T11:42:17.123175125Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
重复上述操作,在相同路径下为其他消费者凭证创建更多密钥(注意:KV v1 会覆盖现有的密钥):
- 对于基本认证(Basic Authentication)凭证:
docker exec api7-quickstart-vault vault kv put kv/api7/consumer/alice password=alice-password
- 对于 JWT 认证凭证:
docker exec api7-quickstart-vault vault kv put kv/api7/consumer/alice secret=alice-secret
- 对于 HMAC 认证凭证:
docker exec api7-quickstart-vault vault kv put kv/api7/consumer/alice secret-key=alice-secret-key
添加密钥认证(Key Authentication)凭证
- Dashboard
- ADC
- Ingress Controller
- 从侧边导航栏选择你的网关组下的 消费者。
- 选择你的目标消费者,例如
Alice。 - 在 认证凭据选项卡下,点击 新增 Key Authentication 凭据。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
primary-key。 - 在 Key字段中,输入
$secret://vault/my-vault/consumer/alice/key。 - 点击 新增。
当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将是 kv/api7/consumer/alice/key。
若使用 ADC 创建包含 key-auth 的消费者,请更新你的配置:
consumers:
- username: Alice
credentials:
- name: primary-key
type: key-auth
config:
key: $secret://vault/my-vault/consumer/alice/key
将配置同步到 API7 企业版:
adc sync -f consumer.yaml
API7 Ingress Controller 目前不支持密钥提供商。
添加基本认证(Basic Authentication)凭证
- Dashboard
- ADC
- Ingress Controller
- 从侧边导航栏选择你的网关组下的 消费者。
- 选择你的目标消费者,例如
Alice。 - 在 认证凭据选项卡下,点击 Basic Authentication选项卡,然后点击 新增 Basic Authentication 凭据。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
primary-basic。 - 在 用户名字段中,输入
Alice。 - 在 密码字段中,输入
$secret://vault/my-vault/consumer/alice/password。 - 点击 新增。
当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将是 kv/api7/consumer/alice/password。
若使用 ADC 创建包含 basic-auth 的消费者,请更新你的配置:
consumers:
- username: Alice
credentials:
- name: primary-basic
type: basic-auth
config:
password: $secret://vault/my-vault/consumer/alice/password
username: Alice
将配置同步到 API7 企业版:
adc sync -f consumer.yaml
API7 Ingress Controller 目前不支持密钥提供商。
添加 JWT 认证凭证
- Dashboard
- ADC
- Ingress Controller
- 从侧边导航栏选择你的网关组下的 消费者。
- 选择你的目标消费者,例如
Alice。 - 在 认证凭据选项卡下,点击 JWT 选项卡,然后点击 新增 JWT 凭据。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
primary-jwt。 - 在 Key字段中,输入
alice-key。 - 在 算法 字段中,选择
HS256。 - 在 密钥字段中,输入
$secret://vault/my-vault/consumer/alice/secret。 - 点击 新增。
当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将是 kv/api7/consumer/alice/secret。
若使用 ADC 创建包含 jwt-auth 的消费者,请更新你的配置:
consumers:
- username: Alice
credentials:
- name: primary-jwt
type: jwt-auth
config:
algorithm: HS256
key: alice-key
secret: $secret://vault/my-vault/consumer/alice/secret
将配置同步到 API7 企业版:
adc sync -f consumer.yaml
API7 Ingress Controller 目前不支持密钥提供商。
添加 HMAC 认证凭证
- Dashboard
- ADC
- Ingress Controller
- 从侧边导航栏选择你的网关组下的 消费者。
- 选择你的目标消费者,例如
Alice。 - 在 认证凭据选项卡下,点击 HMAC Authentication选项卡,然后点击 新增 HMAC Authentication 凭据。
- 在弹出的对话框中,执行以下操作:
- 在 名称字段中,输入
primary-hmac。 - 在 Key ID 字段中,输入
alice-keyid。 - 在 Secret Key字段中,输入
$secret://vault/my-vault/consumer/alice/secret-key。 - 点击 新增。
当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将是 kv/api7/consumer/alice/secret-key。
若使用 ADC 创建包含 hmac-auth 的消费者,请更新你的配置:
consumers:
- username: Alice
credentials:
- name: primary-hmac
type: hmac-auth
config:
key_id: alice-keyid
secret_key: $secret://vault/my-vault/consumer/alice/secret-key
将配置同步到 API7 企业版:
adc sync -f consumer.yaml
API7 Ingress Controller 目前不支持密钥提供商。
验证
验证密钥认证
请参阅为 API 启用密钥认证在服务级别启用 key-auth 插件,然后按照验证密钥认证进行验证。
验证基本认证
请参阅为 API 启用基本认证在服务级别启用 basic-auth 插件,然后按照验证基本认证进行验证。
验证 JWT 认证
请参阅为 API 启用 JWT 认证在服务级别启用 jwt-auth 插件,然后按照验证 JWT 认证进行验证。
验证 HMAC 认证
请参阅为 API 启用 HMAC 认证在服务级别启用 hmac-auth 插件,然后按照验证 HMAC 认证进行验证。
引用密钥来启用插件
插件配置中的以下敏感字段可存储在外部密钥管理器(HashiCorp Vault、AWS Secret 管理服务 等)中并在 API7 网关中引用:
| 插件 | 字段 |
|---|---|
| Limit Count | redis_username, redis_password |
| Authz-Casdoor | client_id, client_secret |
| Wolf RBAC | appid |
| LDAP Authentication | user_dn |
本节以配置 Limit Count 插件为例进行演示。
创建密钥
创建一个密钥 username=api7,并将其存储在 Vault 的 kv/api7/redis 路径下。请确保该路径与你配置的密钥前缀一致:
docker exec api7-quickstart-vault vault kv put kv/api7/redis username=api7
预期的响应类似于以下内容:
=== Secret Path ===
kv/data/api7/redis
======= Metadata =======
Key Value
--- -----
created_time 2023-03-15T11:42:17.123175125Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 1
为 Redis 密码存储一个密钥(注意:KV v1 会覆盖现有的密钥):
docker exec api7-quickstart-vault vault kv put kv/api7/redis password=redis-api7
配置 Limit Count 插件
有关在何处以及如何启用 Limit Count 插件的信息,请参阅对 API 应用限流。
- Dashboard
- ADC
- Ingress Controller
将以下配置添加到 JSON 编辑器中:
{
"count": 3,
"time_window": 60,
"key_type": "var",
"rejected_code": 429,
"rejected_msg": "Too many requests",
"key": "remote_addr",
"policy": "redis",
"redis_host": "127.0.0.1",
"redis_port": 6379,
"redis_username": "$secret://vault/my-vault/redis/username",
"redis_password": "$secret://vault/my-vault/redis/password",
"redis_database": 1,
"redis_timeout": 1001,
"allow_degradation": false,
"show_limit_quota_header": true
}
当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将 是 kv/api7/redis/username 和 kv/api7/redis/password。
以下仅为插件配置,而不是要同步的完整配置文件。请参阅对 API 应用限流以了解有关在何处以及如何使用 ADC 启用 Limit Count 插件的说明。
limit-count:
count: 3
time_window: 60
key_type: var
rejected_code: 429
rejected_msg: Too many requests
key: remote_addr
policy: redis
redis_host: 127.0.0.1
redis_port: 6379
redis_username: $secret://vault/my-vault/redis/username
redis_password: $secret://vault/my-vault/redis/password
redis_database: 1
redis_timeout: 1001
allow_degradation: false
show_limit_quota_header: true
API7 Ingress Controller 目前不支持密钥提供商。
额外资源
- 核心概念
- API 消费