SSL / secret / wasm / pubsub
收官前把剩余几个子系统扫一遍:动态 TLS 证书(按 SNI 选、热更新)、密钥管理(对接 Vault 等)、Wasm 插件支持(呼应上一站 wasm-go)、pubsub 发布订阅。它们各自解决一类问题。
动态证书
init.lua:173-182 的 ssl_phase:TLS 握手时用 router.router_ssl(Day 06 的 radixtree_sni)选证书。apisix/ssl/ + ssl.lua 管证书。
ssl_client_hello_phase
init.lua:184-224 的 ssl_client_hello_phase——在 TLS 的 ClientHello 阶段(握手最早期)就拿到 SNI:
function _M.ssl_client_hello_phase()
local sni, err = apisix_ssl.server_name(true) -- 从 ClientHello 取 SNI
if not sni then ngx_exit(-1) end
local api_ctx = core.tablepool.fetch("api_ctx", 0, 32)
router.router_ssl.match_and_set(api_ctx, true, sni) -- 按 SNI 匹配证书并设置
end
ssl_client_hello_by_lua 让你在这个最早期介入。拿到 SNI → radixtree_sni 匹配 → 设置本次握手用的证书。之后 ssl_phase 完成握手。SNI 选证书
SSL 对象(schema_def.lua:765)含 cert(证书)、key(私钥)、snis(这张证书服务哪些域名)。router_ssl 按 SNI 建 radixtree(Day 06),握手时 match_and_set 匹配。
*.example.com)、多 SNI 共享一张证书。secret 密钥管理
apisix/secret.lua + apisix/secret/:对接外部密钥管理系统(Vault、AWS Secrets Manager、环境变量),让配置里不写死敏感信息。secret.lua:77 的 init_worker watch /secrets。
$secret://vault/1/mysql-pass),运行时从 Vault 等动态解析真实值。密钥集中在 Vault 管理、轮换,配置里只留引用。这是生产安全的重要一环——和上一站 Higress Console 的"证书/密钥存 Secret"是同类思想。"redis_password": "$secret://vault/1/redis/pass"。运行时 secret 层照这个"取件码"去 Vault 取真实密码交给插件。配置(etcd)里永远只有取件码、没有真密码——谁翻到配置也偷不走密码。密码轮换只在 Vault 改,配置一字不动。
密钥引用
配置里用 $secret://<manager>/<id>/<key> 或 $env://VAR 引用。secret.lua 的 fetch_by_uri 解析这些引用,从对应后端取真实值(带缓存 + TTL)。
secret/ 目录)。wasm 支持
apisix/wasm.lua:APISIX 也支持 Wasm 插件(通过 proxy-wasm)——除了 Lua 插件,还能跑 Wasm 插件(Go/Rust/C++ 编译的)。wasm.lua:158 的 require 把 wasm 插件包装成标准插件对象。
wasm.lua 把 Wasm 插件适配成 APISIX 的插件接口(priority/schema/阶段方法),和 Lua 插件一视同仁地跑。这意味着 APISIX 和 Envoy/Higress 在插件层有了共同语言——proxy-wasm 是跨网关的插件标准(呼应上一站 wasm-go Day 03 说的"USB 标准")。👶 小白:APISIX 都用 Lua 写插件了,为什么还要费劲支持 Wasm?
👨🏫 老师:三个理由:① 复用已有资产——你在 Envoy/Higress 上写的 proxy-wasm 插件(上一站 wasm-go)能直接搬过来;② 语言自由——想用 Rust/Go 写高性能或复杂逻辑插件;③ 生态互通——proxy-wasm 是跨网关标准("USB 接口"),支持它就等于和 Envoy 系有了共同语言。Lua 主打"快和热加载",Wasm 补上"跨生态和多语言",两条路并存。
pubsub
apisix/pubsub/ + core/pubsub.lua:APISIX 能当"消息网关"——代理 Kafka、MQTT、NATS 等发布订阅协议,让 WebSocket 客户端订阅消息流。
今日小结 + 动手
🧠 今天你应该能回答
- 动态证书为什么要在 ClientHello 阶段按 SNI 选?
- secret 机制怎么让配置不写死密钥?谁来解析引用?
- APISIX 除了 Lua 插件为什么还支持 Wasm?和上一站什么关系?
- pubsub 体现了 APISIX 什么野心?
✋ 动手
cd /Users/bitmart/work/codes/github/apisix
sed -n '173,225p' apisix/init.lua
sed -n '68,90p' apisix/secret.lua
ls apisix/secret/ apisix/ssl/ apisix/pubsub/