3. Kong 网关 TLS 架构:证书存储、SNI 与监听器配置
Kong 网关作为南北向流量的统一入口,其 TLS 架构直接决定了 HTTPS 服务的可用性、安全性与性能。本章深入剖析 Kong 的证书存储机制、SNI(服务器名称指示)工作原理以及监听器配置策略,帮助你在升级窗口内精准完成证书更新并优化 TLS 握手性能。
3.1 证书存储机制:从数据库到内存的路径
Kong 将 TLS 证书与私钥存储在自身的数据库中(PostgreSQL 或 Cassandra),而非依赖操作系统或外部密钥管理服务(KMS)。这种设计使得证书管理完全融入 Kong 的声明式配置体系,支持通过 Admin API、Konga 或声明式配置文件(declarative config)进行统一管理。
3.1.1 核心数据模型
| 实体 | 字段 | 说明 |
|---|---|---|
| Certificate | cert(PEM 格式证书链) |
包含服务器证书及中间 CA 证书,按顺序拼接 |
key(PEM 格式私钥) |
RSA/ECDSA 私钥,Kong 不会以明文形式暴露 | |
tags |
用于分组和过滤,方便批量操作 | |
| SNI | name(域名) |
如 api.example.com,支持通配符 *.example.com |
certificate(外键) |
关联到具体的 Certificate 实体 |
最佳实践:证书更新时,建议创建新的 Certificate 实体(新 ID),再更新 SNI 的
certificate 引用。这种方式可以避免在更新过程中出现证书与私钥不匹配的窗口期,且支持快速回滚。
3.1.2 证书加载与缓存机制
Kong 在启动时或接收到 Admin API 的证书变更通知后,会执行以下流程:
- 数据库查询:从
certificates和snis表中加载所有有效记录。 - PEM 解析:验证证书链完整性、私钥匹配性及有效期。
- 内存缓存:将解析后的
SSL_CTX对象存入共享内存(LMDB 或 shm),供所有 Worker 进程使用。 - 热更新:通过
POST /certificates或PATCH /snis触发时,Kong 仅更新变更的SSL_CTX,无需 reload 整个进程。
注意:如果使用声明式配置文件(
kong.yml)进行证书更新,必须确保配置文件的 _format_version 正确,且证书内容经过 Base64 编码(当使用 cert 和 key 字段时)。错误的格式会导致 Kong 解析失败,进而影响 TLS 握手。
3.2 SNI 工作原理:多域名 TLS 的核心
SNI(服务器名称指示)是 TLS 协议的扩展,允许客户端在握手阶段(ClientHello)携带目标域名,服务端据此选择对应的证书进行响应。Kong 利用 SNI 实现单 IP 多证书的虚拟托管。
3.2.1 SNI 匹配流程
3.2.2 通配符与默认 SNI
- 精确匹配:
api.example.com完全匹配 SNI 记录。 - 通配符匹配:
*.example.com可匹配sub1.example.com、sub2.example.com,但不匹配example.com本身。 - 默认 SNI:当客户端未携带 SNI 或所有匹配失败时,Kong 使用
default标签的 SNI 对应的证书。建议始终配置一个默认 SNI,避免 TLS 握手失败。
性能要点:SNI 匹配发生在 TLS 握手阶段,属于 CPU 密集型操作。当证书数量超过 1000 个时,建议启用 Kong 的
ssl_cert_cache_ttl 参数(默认 3600 秒),减少数据库查询频率。同时,使用 ECDSA 证书而非 RSA 证书可以降低握手时的计算开销。
3.3 监听器配置:代理与 Admin 分离
Kong 的监听器配置决定了网关如何暴露 TLS 端口。合理的监听器配置不仅能提升安全性,还能通过端口分离实现性能隔离。
3.3.1 核心监听器参数
| 参数 | 默认值 | 说明 |
|---|---|---|
proxy_listen |
0.0.0.0:8000, 0.0.0.0:8443 ssl |
代理端口,ssl 标记启用 TLS |
admin_listen |
127.0.0.1:8001, 127.0.0.1:8444 ssl |
Admin API 端口,建议仅监听本地回环地址 |
stream_listen |
off |
TCP/UDP 流式监听,支持 TLS 透传 |
3.3.2 生产环境推荐配置
# kong.conf 片段
proxy_listen = 0.0.0.0:443 ssl, 0.0.0.0:80
admin_listen = 127.0.0.1:8001, 127.0.0.1:8444 ssl
stream_listen = 0.0.0.0:8443 ssl
# TLS 优化参数
ssl_cert_cache_ttl = 3600
ssl_cipher_suite = modern
ssl_protocols = TLSv1.2 TLSv1.3
ssl_prefer_server_ciphers = on
ssl_session_cache_size = 50m
ssl_session_timeout = 5m
安全警告:切勿将 Admin API 监听在公网 IP 上(如
0.0.0.0:8444)。Admin API 拥有完全控制权,暴露在公网将导致严重安全风险。始终使用 127.0.0.1 或内网 IP,并配合防火墙规则。
3.3.3 多端口监听与性能隔离
Kong 支持在同一进程中监听多个端口,每个端口可以独立配置 TLS 参数。这种设计允许你将不同安全等级的流量隔离到不同端口:
- 443 端口:面向公网的 HTTPS 流量,启用完整 TLS 验证。
- 8443 端口:内部微服务通信,使用 mTLS(双向 TLS)进行身份验证。
- 8445 端口:仅用于证书更新后的验证测试,绑定内网 IP,不对外暴露。
3.4 证书更新与 TLS 性能优化策略
3.4.1 零停机证书更新流程
- 预创建新证书:通过 Admin API 创建新的 Certificate 实体,包含新证书链和私钥。
- 更新 SNI 引用:将目标 SNI 的
certificate字段指向新证书的 ID。 - 验证生效:使用
openssl s_client -connect yourdomain:443 -servername yourdomain验证新证书是否生效。 - 清理旧证书:确认新证书正常工作后,删除旧的 Certificate 实体。
3.4.2 TLS 握手性能优化清单
| 优化项 | 操作 | 预期效果 |
|---|---|---|
| 会话复用 | 启用 ssl_session_cache 并设置合理大小 |
减少重复握手,降低延迟 30%-50% |
| OCSP Stapling | 配置 ssl_ocsp 为 on |
客户端无需单独查询 OCSP 响应,提升握手速度 |
| HSTS 预加载 | 在响应头添加 Strict-Transport-Security |
强制客户端使用 HTTPS,减少重定向开销 |
| 证书链优化 | 移除根证书,仅保留服务器证书 + 中间 CA | 减少握手数据量,降低带宽消耗 |
| TLS 1.3 优先 | 设置 ssl_protocols = TLSv1.2 TLSv1.3 |
TLS 1.3 握手仅需 1-RTT,比 TLS 1.2 快 33% |
升级窗口建议:在证书更新前,先通过 Kong 的
/schemas/certificates 端点验证新证书的格式是否正确。使用 curl -X POST http://localhost:8001/certificates -F "cert=@new_cert.pem" -F "key=@new_key.pem" 进行测试,避免因证书格式错误导致生产故障。