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

API7 网关 AI Agent Skill:mTLS 方案

概览

双向 TLS(mTLS)确保客户端和服务端彼此校验 身份。标准 TLS 只校验服务端;mTLS 会额外校验客户端证书。

通过 API7 企业版和 a7 CLI,你可以配置:

  1. 客户端到 API7 企业版的 mTLS:要求客户端提供有效证书。
  2. API7 企业版到上游的 mTLS:连接后端时提供客户端证书。
  3. 端到端 mTLS:同时启用两个方向的 mTLS。

适用场景

  • 服务间零信任网络。
  • 微服务中的安全服务间通信。
  • 要求双向认证的合规场景。
  • 使用基于证书的认证替代或补充 API Key 认证。
  • 仅授权服务可访问的内部 API。

前提条件

  • API7 企业版控制面和至少一个网关组。
  • 已配置有效 Token 和服务地址的 a7 CLI。
  • PEM 格式的证书和私钥。

第 1 部分:客户端 → API7 企业版 mTLS

要求客户端连接 API7 企业版时提供有效 TLS 证书。

1. 创建带客户端校验 CA 的 SSL 资源

a7 ssl create --gateway-group default -f - <<'EOF'
{
"id": "mtls-domain",
"cert": "<SERVER_CERTIFICATE_PEM>",
"key": "<SERVER_PRIVATE_KEY_PEM>",
"snis": ["api.example.com"],
"client": {
"ca": "<CA_CERTIFICATE_PEM>"
}
}
EOF

字段:

  • cert / key:服务端证书和私钥(提供给客户端)。
  • snis:服务器名称指示(Server Name Indications),即该证书覆盖的域名。
  • client.ca:用于校验客户端证书的 CA 证书。
  • client.depth:(可选)证书链校验的最大深度。

2. 为受保护后端创建服务

a7 service create --gateway-group default -f - <<'EOF'
{
"id": "secure-api-service",
"name": "secure-api-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{
"host": "backend",
"port": 8080,
"weight": 1
}
]
}
}
EOF

3. 在受保护域名上创建路由

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "secure-api",
"paths": ["/api/*"],
"host": "api.example.com",
"service_id": "secure-api-service"
}
EOF

4. 使用客户端证书测试

# 使用有效客户端证书——成功
curl --cert client.crt --key client.key --cacert ca.crt \
https://api.example.com:9443/api/health

# 不使用客户端证书——SSL 握手失败
curl --cacert ca.crt https://api.example.com:9443/api/health

第 2 部分:API7 企业版到上游的 mTLS

配置 API7 企业版,使其连接后端时提供客户端证书。

1. 准备上游客户端证书

先在 API7 企业版中创建上游客户端 SSL 证书和 CA 证书,并记录其 ID/名称。推荐的 API7 企业版工作流如下:

  1. 添加 SSL 证书,使用 API7 企业版应向上游提供的证书。
  2. 添加用于校验上游证书的 CA 证书。
  3. 在已发布服务的上游连接配置中选择这两个证书。

如果使用 a7 ssl create 上传客户端 SSL 证书,请将 PEM 内容保存在不提交到仓库的本地文件中,并通过 -f 传入该文件。

2. 创建使用 HTTPS 上游的服务

a7 service create --gateway-group default -f - <<'EOF'
{
"id": "mtls-backend-service",
"name": "mtls-backend-service",
"upstream": {
"type": "roundrobin",
"scheme": "https",
"nodes": [
{
"host": "secure-backend",
"port": 443,
"weight": 1
}
],
"tls": {
"client_cert_id": "<UPSTREAM_CLIENT_CERTIFICATE_ID>"
}
}
}
EOF

字段:

  • upstream.scheme:连接上游使用 TLS 时必须为 "https"
  • upstream.nodes:后端节点,例如 [{ "host": "...", "port": 443, "weight": 1 }]
  • upstream.tls.client_cert_id:API7 企业版提供给上游的客户端证书对象。
  • upstream.pass_host:如果上游需要特定 Host 请求头,可设为 "pass"(默认)或 "rewrite"

如果 API7 企业版需要校验上游证书,请在已发布服务的上游连接配置中配置上游 CA 证书。

3. 创建使用该服务的路由

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "api",
"paths": ["/api/*"],
"service_id": "mtls-backend-service"
}
EOF

第 3 部分:端到端 mTLS

组合两者:客户端向 API7 企业版证明自身身份,API7 企业版也向 上游证明自身身份。

1. 面向客户端到 API7 企业版的 mTLS SSL

a7 ssl create --gateway-group default -f - <<'EOF'
{
"id": "frontend-mtls",
"cert": "<API7_SERVER_CERT>",
"key": "<API7_SERVER_KEY>",
"snis": ["api.example.com"],
"client": {
"ca": "<CLIENT_CA_CERT>"
}
}
EOF

2. 面向 API7 企业版到后端 mTLS 的服务

a7 service create --gateway-group default -f - <<'EOF'
{
"id": "secure-backend-service",
"name": "secure-backend-service",
"upstream": {
"type": "roundrobin",
"scheme": "https",
"nodes": [
{
"host": "internal-service",
"port": 443,
"weight": 1
}
],
"tls": {
"client_cert_id": "<UPSTREAM_CLIENT_CERTIFICATE_ID>"
}
}
}
EOF

3. 连接两端的路由

a7 route create --gateway-group default -f - <<'EOF'
{
"id": "e2e-mtls-api",
"paths": ["/api/*"],
"host": "api.example.com",
"service_id": "secure-backend-service"
}
EOF

常见模式

使用不同 CA 的多个域名

# 域名 A:内部服务
a7 ssl create --gateway-group default -f - <<'EOF'
{
"id": "internal-mtls",
"cert": "<INTERNAL_CERT>",
"key": "<INTERNAL_KEY>",
"snis": ["internal.example.com"],
"client": {
"ca": "<INTERNAL_CA>"
}
}
EOF

# 域名 B:合作伙伴服务
a7 ssl create --gateway-group default -f - <<'EOF'
{
"id": "partner-mtls",
"cert": "<PARTNER_CERT>",
"key": "<PARTNER_KEY>",
"snis": ["partner.example.com"],
"client": {
"ca": "<PARTNER_CA>"
}
}
EOF

使用 Secret 管理证书

API7 企业版支持将证书存储在外部 Secret 管理器中。请先通过控制台或 a7 CLI 配置 Secret。

# 创建 Secret 引用
a7 secret create --gateway-group default -f - <<'EOF'
{
"id": "vault/mtls-certs",
"uri": "https://vault.example.com/v1/secret/data/mtls"
}
EOF

配置同步示例

version: "1"
gateway_group: default
ssls:
- id: api-mtls
cert: |
-----BEGIN CERTIFICATE-----
<server certificate>
-----END CERTIFICATE-----
key: |
-----BEGIN RSA PRIVATE KEY-----
<server private key>
-----END RSA PRIVATE KEY-----
snis:
- api.example.com
client:
ca: |
-----BEGIN CERTIFICATE-----
<用于客户端校验的 CA 证书>
-----END CERTIFICATE-----
services:
- id: secure-backend-service
name: secure-backend-service
upstream:
type: roundrobin
scheme: https
nodes:
- host: backend
port: 443
weight: 1
tls:
client_cert_id: upstream-client-cert
routes:
- id: mtls-api
paths:
- /api/*
host: api.example.com
service_id: secure-backend-service

故障排查

现象原因修复方式
SSL 握手失败(客户端侧)客户端证书不是由 client.ca 中的 CA 签发校验 CA 链,确认客户端证书由正确 CA 签发
"no required SSL certificate"客户端未发送证书配置客户端提供证书(curl 中使用 --cert
访问上游返回 502上游拒绝 API7 企业版的客户端证书确认 upstream.tls.client_cert_id 指向由上游信任 CA 签发的证书
证书已过期TLS 证书超过有效期使用 a7 ssl update 轮换证书
SNI 不匹配域名不在 snis 列表中将该域名添加到 snis 数组
命令返回 401Token 无效使用 a7 context create 刷新 Token
未找到服务网关组不同确保 --gateway-group 与资源创建位置一致

本页面由 api7/a7 仓库中的 a7-recipe-mtls/SKILL.md 生成。你可以在 AI Agent Skills 页面查看所有技能。