跳到主要内容
版本:3.9.x

引用 HashiCorp Vault 中的密钥

HashiCorp Vault 是一个集中式平台,用于管理跨不同环境和应用程序的密钥和加密。它为存储和访问(例如 API 密钥、密码、证书等)提供了统一的密钥管理。

本教程演示了如何将 API7 企业版与 HashiCorp Vault 集成,使你能够从 Vault 中安全地存储和引用消费者凭证及插件配置。

下面是一个交互式演示,提供了将 API7 企业版与 HashiCorp Vault 集成存储和检索 key-auth 密钥的动手实践。

前置条件

  1. 安装 API7 企业版
  2. 在你的网关组中至少有一个网关实例
  3. 安装 Docker
  4. 安装 cURL 以向服务发送请求进行验证。
  5. 安装 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"]

在网关组中添加密钥提供商

  1. 从侧边导航栏选择你的网关组下的 Secret 提供商,然后点击 新增 Secret 提供商
  2. 在弹出的对话框中,执行以下操作:
  • Secret 提供商 ID 字段中,输入 my-vault
  • Secret 管理服务 字段中,选择 HashiCorp Vault
  • KV 版本 字段中,选择 KV 版本 1
  • 填写 Vault 服务器 URL字段。例如:127.0.0.1:8200
  • 填写 Secret 前缀字段。例如:kv/api7
  • 认证方式字段中,选择 Token
  • 填写 令牌字段。
  • 点击 新增
  1. 复制 Secret 变量以供将来引用。所有密钥引用均由此生成,例如:$secret://vault/my-vault/$secret_name/$key

引用 SSL 证书的密钥

SSL 证书对象中的敏感字段 certificateprivate 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 证书

  1. 从侧边导航栏选择你的网关组下的 证书,进入 SSL 证书选项卡。
  2. 点击 新增 SSL 证书
  3. 在弹出的对话框中,执行以下操作:
  • 名称字段中,输入 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

  1. 想要全面使用和验证 SSL 证书,请参阅在客户端与 API7 网关之间配置 mTLS

引用密钥创建消费者凭证

消费者凭证中的以下敏感字段可存储在外部密钥管理器(HashiCorp Vault、AWS Secret 管理服务 等)中并在 API7 网关中引用:

  • 密钥认证(Key Authentication)凭证中的 key
  • 基本认证(Basic Authentication)凭证中的 password
  • JWT 认证凭证中的 secretpublic key
  • HMAC 认证凭证中的 secret key

新增消费者

  1. 从侧边导航栏选择你的网关组下的 消费者
  2. 点击 新增消费者
  3. 在弹出的对话框中,执行以下操作:
  • 名称字段中,输入 Alice
  • 点击 新增

存储密钥

为密钥认证凭证创建一个密钥 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)凭证

  1. 从侧边导航栏选择你的网关组下的 消费者
  2. 选择你的目标消费者,例如 Alice
  3. 认证凭据选项卡下,点击 新增 Key Authentication 凭据
  4. 在弹出的对话框中,执行以下操作:
  • 名称字段中,输入 primary-key
  • Key字段中,输入 $secret://vault/my-vault/consumer/alice/key
  • 点击 新增
备注

当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将是 kv/api7/consumer/alice/key

添加基本认证(Basic Authentication)凭证

  1. 从侧边导航栏选择你的网关组下的 消费者
  2. 选择你的目标消费者,例如 Alice
  3. 认证凭据选项卡下,点击 Basic Authentication选项卡,然后点击 新增 Basic Authentication 凭据
  4. 在弹出的对话框中,执行以下操作:
  • 名称字段中,输入 primary-basic
  • 用户名字段中,输入 Alice
  • 密码字段中,输入 $secret://vault/my-vault/consumer/alice/password
  • 点击 新增
备注

当连接到 HashiCorp Vault 时,$secret://vault/my-vault 将被替换为密钥提供商的实际 Secret 前缀。最终,发送到 HashiCorp Vault 的路径将是 kv/api7/consumer/alice/password

添加 JWT 认证凭证

  1. 从侧边导航栏选择你的网关组下的 消费者
  2. 选择你的目标消费者,例如 Alice
  3. 认证凭据选项卡下,点击 JWT 选项卡,然后点击 新增 JWT 凭据
  4. 在弹出的对话框中,执行以下操作:
  • 名称字段中,输入 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

添加 HMAC 认证凭证

  1. 从侧边导航栏选择你的网关组下的 消费者
  2. 选择你的目标消费者,例如 Alice
  3. 认证凭据选项卡下,点击 HMAC Authentication选项卡,然后点击 新增 HMAC Authentication 凭据
  4. 在弹出的对话框中,执行以下操作:
  • 名称字段中,输入 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

验证

验证密钥认证

请参阅为 API 启用密钥认证在服务级别启用 key-auth 插件,然后按照验证密钥认证进行验证。

验证基本认证

请参阅为 API 启用基本认证在服务级别启用 basic-auth 插件,然后按照验证基本认证进行验证。

验证 JWT 认证

请参阅为 API 启用 JWT 认证在服务级别启用 jwt-auth 插件,然后按照验证 JWT 认证进行验证。

验证 HMAC 认证

请参阅为 API 启用 HMAC 认证在服务级别启用 hmac-auth 插件,然后按照验证 HMAC 认证进行验证。

引用密钥来启用插件

插件配置中的以下敏感字段可存储在外部密钥管理器(HashiCorp Vault、AWS Secret 管理服务 等)中并在 API7 网关中引用:

插件字段
Limit Countredis_username, redis_password
Authz-Casdoorclient_id, client_secret
Wolf RBACappid
LDAP Authenticationuser_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 应用限流

将以下配置添加到 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/usernamekv/api7/redis/password

额外资源