API 通信的安全性对于系统可靠性至关重要。本文将详细介绍如何使用 Kong API Gateway 配置 mTLS(双向 TLS/相互 TLS)。重点讲解"Client -> Kong"和"Kong -> Upstream API"这两条通信路径的 mTLS 配置方法。

mTLS 基础知识

mTLS 是 TLS(传输层安全协议)的扩展,通信双方(客户端和服务器)都会用证书进行相互认证。普通 TLS 只验证服务器,mTLS 还增加了如下流程:

  1. 服务器认证:客户端确认服务器持有可信证书。
  2. 客户端认证:服务器确认客户端持有可信证书。

image.png

这种双向认证实现了更安全的通信。

用 Kong API Gateway 实现 mTLS 通信

通过 Kong API Gateway,可以轻松实现如下两条通信路径的 mTLS:

  • 客户端 → Kong API Gateway
  • Kong API Gateway → 上游 API

image.png

Client->Kong 的 mTLS 配置

要在客户端到 Kong API Gateway 的通信中实现 mTLS,需使用 Kong 的"mTLS 插件"。主要步骤如下:

  1. 管理员在 Kong 中设置客户端认证用的 CA 证书
  2. 客户端请求时向 Kong 提交自己的证书
  3. Kong 验证客户端证书,允许安全通信

注册 CA 证书

在 Kong 中注册 CA 证书,用于验证客户端证书

1
2
3
4
5
6
7
8
9
curl http://localhost:8001/ca_certificates -F cert=@ca.crt

{
  "cert": "<PEM_CERT>",
  "id": "c383d81a-bffc-4e2a-b0d3-ac56b441a07b",
  "cert_digest": "3e9099b5015e8f486c00bcea9d111ee721faba355a89bcf1df69561e3dc6325c",
  "tags": null,
  "created_at": 1607347576
}

启用 mTLS 插件

用上面创建的 ca_certificate 启用 mTLS 插件。这里以全局范围为例。

1
2
3
4
5
curl --request POST \
  --url http://localhost:8001/plugins \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data name=mtls-auth \
  --data config.ca_certificates=c383d81a-bffc-4e2a-b0d3-ac56b441a07b

此时如果不带客户端证书访问,会返回 HTTP/1.1 401 Unauthorized 错误。

带客户端证书访问

mTLS 意味着双向 TLS 认证,访问时必须用 HTTPS 协议。如果 Kong 的 TLS 证书是自签名的,建议加 -k 跳过证书校验。

1
curl https://<PROXY_URL>:8443/mtls --key client.key --cert client.crt -k
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 752
Content-Type: application/json
Date: Fri, 20 Dec 2024 15:14:38 GMT
Server: gunicorn/19.9.0
Via: 1.1 kong/3.9.0.0-enterprise-edition
X-Kong-Proxy-Latency: 9
X-Kong-Request-Id: ada6f204577fe50a144706292a01f421
X-Kong-Upstream-Latency: 8

{
    "args": {},
    "data": "",
    "files": {},
    "form": {},
    "headers": {
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate",
        "Connection": "keep-alive",
        "Host": "httpbin.backends:8080",
        "Kong-Request-Id": "e8560956-1bdf-491b-aa05-f962db06adcd",
        "User-Agent": "HTTPie/3.2.4",
        "X-Consumer-Custom-Id": "[email protected]",
        "X-Consumer-Id": "35cfdf1b-11ef-4582-b80f-a0cfb1d67b07",
        "X-Consumer-Username": "[email protected]",
        "X-Forwarded-Host": "localhost",
        "X-Forwarded-Path": "/mtls-auth",
        "X-Forwarded-Prefix": "/mtls-auth",
        "X-Kong-Request-Id": "ada6f204577fe50a144706292a01f421"
    },
    "json": null,
    "method": "GET",
    "origin": "192.168.65.1",
    "url": "https://localhost/anything"
}

Kong->上游 API 的 mTLS 配置

Kong 作为客户端访问 API 时,上游 API 需要客户端证书。因此需在 Kong 侧注册客户端证书。注册方式有两种:全局注册和 Service 级注册。

Kong 全局注册

在配置文件中添加如下三项。Kong 向 API 发起请求时会带上客户端证书。

1
2
3
client_ssl = on
client_ssl_cert = /etc/secrets/my-kong-certificate/kong.crt
client_ssl_cert_key = /etc/secrets/my-kong-certificate/kong.key

Service 级注册

创建 Service 时可用 client_certificate 添加客户端证书。 优先级为:Service 级 > 全局。如果都设置,优先用 Service 级证书。

总结

正确配置 mTLS 能极大提升 API 通信安全。本文介绍了"Client -> Kong"和"Kong -> 上游 API"两条通信路径的 mTLS 配置方法。

为实现安全的 API 通信,请注意:

  • 妥善管理客户端认证用 CA 证书
  • 正确配置 Kong 与上游 API 间的客户端证书
  • 按需选择全局或 Service 级配置

结合文中示意图,欢迎在自己的环境中实践 mTLS!