EMQX ExHook 修复:启用 gRPC over TLS 时校验服务器主机名(verify server host name)
后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载本文基于当前仓库changes/ee/fix-15683.en.md变更记录展开该变更修复了 EMQX ExHook 的 TLS 选项使其在通过https://连接外部 gRPC Hook 服务时能够校验服务器主机名。文章将结合apps/emqx_exhook模块的源码、配置 Schema 与测试用例完整说明修复内容、相关配置参数以及如何在生产环境中正确配置 ExHook 的 TLS 客户端选项。变更背景ExHook 是什么为何需要修复 TLSEMQX 的 ExHookExternal Hook功能允许将消息与事件处理逻辑外置到独立的 gRPC 服务中。EMQX 作为 gRPC 客户端在客户端连接、消息发布、消息投递等约 20 个钩子点hookpoint见 emqx_exhook_server.erl上把事件转发给外部服务由外部服务返回处理结果如是否放行、是否修改消息。当 ExHook 服务的地址以https://开头时EMQX 需要以 TLS 客户端身份与之建连。本次变更编号 fix-15683修复的内容是让 ExHook 的 TLS 选项真正支持verify_peer模式下对服务器主机名的校验server host name verification。在此之前即使配置了verify verify_peer由于底层 TLS 客户端选项转换路径不完整主机名校验并未按预期生效导致中间人攻击防护能力打折修复后EMQX 会基于服务器证书中的主机名通过 SNI 与customize_hostname_check机制对https://URL 中的主机名进行校验。修复的核心链路从配置到 ssl 库的选项转换ExHook 服务的创建与加载入口是 emqx_exhook_server.erl 中的load/2它内部调用channel_opts/1决定底层 gRPC 通道的传输方式%% apps/emqx_exhook/src/emqx_exhook_server.erl case uri_string:parse(URL) of #{scheme : http, host : Host, port : Port} - ... % 明文 TCP #{scheme : https, host : Host, port : Port} - SslOpts case maps:get(ssl, Opts, undefined) of undefined - []; #{enable : false} - []; MapOpts - emqx_tls_lib:to_client_opts(MapOpts) end, NClientOpts ClientOpts#{ gun_opts GunOpts#{ transport ssl, tls_opts SslOpts } }, ...从源码可以看到三条关键分支emqx_exhook_server.erlURL 为http://走明文tcp传输TLS 选项被忽略URL 为https://但未配置ssl或ssl.enable falseSslOpts为空列表仍按 TLS 建连但不携带任何证书/校验选项URL 为https://且ssl.enable true调用emqx_tls_lib:to_client_opts/1将 HOCON 校验过的 TLS 配置映射为 Erlangssl库客户端选项列表再作为tls_opts交给底层 gRPC 通道。本次修复的核心就落在第 3 条路径确保to_client_opts完整输出与主机名校验相关的选项。在 emqx_tls_lib.erl 中可以看到转换逻辑Verify conf_get_opt(verify, Opts, verify_none), TLSClientOpts0 [ {versions, Versions}, {ciphers, Ciphers}, {verify, Verify} | emqx_utils:flattermap( fun(Extractor) - conf_extract_opt(Extractor, Opts) end, [ {depth, fun conf_get_opt/2}, {verify, fun conf_get_opt/2}, {middlebox_comp_mode, fun conf_get_opt/2, #{omit_if true}}, {server_name_indication, fun conf_get_sni/2}, {customize_hostname_check, customize_hostname_check(Verify)}, {reuse_sessions, fun conf_get_opt/2, #{omit_if true}}, {secure_renegotiate, fun conf_get_opt/2, #{omit_if true}} ] ) ],其中两个选项直接决定主机名校验是否生效{server_name_indication, ...}通过conf_get_sni/2emqx_tls_lib.erl把配置值转成 ssl 库可接受的字符串或disable。SNI 用于在 TLS 握手中向服务器声明期望访问的主机名是主机名校验的基础。{customize_hostname_check, customize_hostname_check(Verify)}当verify verify_peer时返回[{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]emqx_tls_lib.erl让证书主机名校验遵循 HTTPS 语义并支持通配符证书当verify verify_none时该项为undefined即不产生该校验。也就是说修复后配置verify_peer的 ExHook 客户端不仅校验证书链还会把服务器证书中的主机名与https://URL 的主机名做比对配合server_name_indication可以精确控制 SNI 发送的主机名。这正是 allow verify server host name 的完整实现路径。配置 SchemaExHook 的 TLS 客户端选项ExHook 的配置结构定义在 emqx_exhook_schema.erl 中。server字段包含name、enable、url、request_timeout、failed_action、ssl、socket_options、auto_reconnect、pool_size等其中ssl字段引用ssl_conf第 61 行{ssl, ?HOCON(?R_REF(ssl_conf), #{})}, ... fields(ssl_conf) - Schema emqx_schema:client_ssl_opts_schema(#{}), lists:keydelete(user_lookup_fun, 1, Schema);即 ExHook 的 TLS 选项复用了 EMQX 通用的客户端SSL 选项 Schemaemqx_schema.erl并删除了仅适用于服务端上下文的user_lookup_fun字段。该 Schema 在通用选项基础上补充了enable、middlebox_comp_mode、server_name_indication、managed_certs等客户端专属字段。因此ExHook 的ssl配置块支持以下关键参数均可在 HOCON 配置中直接使用参数类型默认值说明enablebooleanfalse是否启用 TLS 客户端选项为false时按无 TLS 选项处理verifyverify_peer/verify_noneverify_none是否校验对端证书。verify_peer时校验证书链并配合本修复校验服务器主机名cacertfilestring—CA 证书文件路径verify_peer模式下通常必需用于验证服务器证书链certfilestring—客户端证书文件路径若 gRPC 服务要求双向 TLSkeyfilestring—客户端私钥文件路径passwordstring敏感项—私钥口令在 API 返回与日志中会被脱敏为******server_name_indicationdisable/ string不设置指定 TLS SNI 中发送的主机名或设为disable关闭 SNIdepth非负整数10证书链验证的最大深度versionsTLS 版本数组当前可用版本剔除已过时的 TLS 1/1.1允许的 TLS 协议版本ciphers字符串数组内置默认套件允许的加密套件reuse_sessionsbooleanfalse是否复用 TLS 会话secure_renegotiatebooleantrue是否只允许安全重协商middlebox_comp_modebooleantrue兼容中间盒的 TLS 记录模式managed_certs对象—托管证书相关配置默认verify verify_none意味着如果不显式开启校验ExHook 客户端只加密通信但不验证服务器身份。需要主机名校验时必须同时设置verify verify_peer及cacertfile这正是 fix-15683 修复后能够可靠生效的组合。完整的实战配置示例1. 校验服务器主机名的标准配置单向 TLS当 ExHook gRPC 服务使用公开 CA 或自有 CA 签发的证书且地址为https://exhook.example.com:9000时启用主机名校验的配置如下exhook { servers: [ { name: default enable: true url: https://exhook.example.com:9000 request_timeout: 5s failed_action: deny auto_reconnect: 60s pool_size: 8 ssl { enable: true verify: verify_peer cacertfile: /etc/emqx/certs/cacert.pem # 可选显式指定 SNI 发送的主机名默认取 URL 中的主机名 # server_name_indication: exhook.example.com } } ] }要点url必须以https://开头否则ssl块不会参与建连见 emqx_exhook_server.erlURL 的合法性由validate_url/1校验emqx_exhook_schema.erl。cacertfile指向签发服务器证书的 CA 证书。校验时会同时检查证书链、有效期以及服务器主机名与 URL 主机名是否匹配支持通配符证书行为遵循 HTTPS 匹配规则。若使用双向 TLSmTLS再补充certfile与keyfile使 EMQX 能向 gRPC 服务出示客户端证书。2. 仅加密不校验verify_none不推荐用于生产如果暂时无法提供受信 CA可先保持加密但关闭身份校验exhook { servers: [ { name: default enable: true url: https://exhook.example.com:9000 ssl { enable: true verify: verify_none } } ] }注意verify_none不会执行主机名校验customize_hostname_check返回undefined此时即使开启 TLS 也存在中间人风险建议仅用于联调环境生产环境应迁移到verify_peer。3. 其他可选参数ssl { enable: true verify: verify_peer cacertfile: /etc/emqx/certs/cacert.pem versions: [tlsv1.3, tlsv1.2] depth: 10 reuse_sessions: false secure_renegotiate: true middlebox_comp_mode: true }versions用于收紧允许的 TLS 协议版本如仅允许 TLS 1.2/1.3默认会剔除已过时的 TLS 1.0/1.1server_name_indication: disable可用于在目标服务不接受 SNI 的少数场景显式关闭 SNI但会同时失去主机名协商能力需谨慎使用。除静态配置文件外ssl选项同样可以在 Dashboard 的 ExHook 创建/编辑界面或通过管理 API 提交其 JSON 结构与上述 HOCON 字段一一对应。源码与测试印证选项转换与文件管理emqx_tls_lib.erl 的to_client_opts/1,2负责把配置转换为 ssl 库选项其中明确包含{server_name_indication, ...}与{customize_hostname_check, ...}两项主机名校验相关选项emqx_exhook_server.erl 的channel_opts/1仅在https且ssl.enable true时调用上述转换函数并将其作为 gun 的tls_optsemqx_exhook_mgr.erl 在加载/更新服务器配置时会调用emqx_tls_lib:ensure_ssl_files_in_mutable_certs_dir/3把证书文件同步到可变的证书目录并会在ssl配置非法时抛出bad_ssl_config错误从管理层面保证 TLS 配置可用。测试用例仓库中的测试对本次修复相关的 TLS 配置路径做了直接覆盖emqx_exhook_SUITE.erl 的t_ssl_clear构造包含enable true、cacertfile、certfile、keyfile、verify verify_peer的ssl配置通过emqx_exhook_mgr:update_config/2添加/更新/删除服务器验证证书文件被正确写入可变证书目录且在删除后清理干净——即配置中verify_peer等 TLS 选项会被完整解析、传递与持久化管理emqx_exhook_api_SUITE.erl 的t_ssl_password_obfuscated验证 API 读出的ssl.password被脱敏为******而原始配置中仍保存真实口令说明ssl块含敏感字段会原样进入配置持久化流程。这些测试与上述源码共同印证ExHook 的 TLS 配置从 Schema 校验、证书文件管理到最终 ssl 库选项转换是一条完整链路而 fix-15683 补上的正是其中 verify server host name 这一环。验证与排障建议确认建连与校验生效配置完成后观察 ExHook 服务状态是否变为 connected若证书主机名不匹配或证书链不可信gRPC 通道将无法建立日志中会出现 TLS 握手/校验相关错误。可先在verify_none下确认网络与证书基本可用再切换到verify_peer验证主机名校验。证书与主机名匹配检查确保服务器证书的 SANSubject Alternative Name包含url中的主机名使用通配符证书时需注意其匹配规则与 HTTPS 一致见 emqx_tls_lib.erl 的注释 allow wildcard certificates。SNI 与反向代理场景如果 ExHook 服务在负载均衡器或网关后面且网关需要 SNI 来路由可显式设置server_name_indication为实际服务域名。密钥安全password属于敏感配置项Dashboard/API 展示时会脱敏请避免在配置文件中明文存放不必要的私钥口令。小结fix-15683 修复使 EMQX ExHook 在https://连接模式下真正支持verify_peer的服务器主机名校验配置经 emqx_exhook_schema.erl 的client_ssl_opts_schema校验后由 emqx_tls_lib.erl 的to_client_opts转换为包含 SNI 与pkix_verify_hostname_match_fun(https)主机名校验的 ssl 选项最终作用于 gRPC 客户端通道。生产环境中只要把 ExHook 地址配置为https://并设置ssl.enable true、verify verify_peer及正确的cacertfile即可获得加密 证书链校验 服务器主机名校验三层防护有效降低中间人攻击风险。赞分享后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载相关推荐EMQX ExHook 管理器配置更新健壮性修复解析服务器不健康时保持顺序与持续服务PR 18464EMQX ExHook 管理器配置更新健壮性修复解析服务器不健康时保持顺序与持续服务PR 18464 导读 本文基于 EMQX 开源仓库中的变更记录 ch后端物联网消息队列通信EMQX ExHook 配置导入崩溃修复badarg解析从 CLI 导入无效配置到 URL 校验器EMQX ExHook 配置导入崩溃修复badarg解析从 CLI 导入无效配置到 URL 校验器 导读 本文围绕 EMQX 发布记录 changes/e后端物联网消息队列通信UnoCSS PresetWind4 完全指南内建 Reset、按需 Theme 变量与 property 三层输出机制UnoCSS PresetWind4 完全指南内建 Reset、按需 Theme 变量与 property 三层输出机制 本文基于 UnoCSS 仓库中的官后端物联网消息队列通信创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

SAP拆解工单配置:S型工艺路线与成本独立归集实战

SAP拆解工单配置:S型工艺路线与成本独立归集实战

简介:本资源是面向SAP PP模块实施顾问、生产计划专员及FICO财务顾问的深度实操指南,系统解析SAP中拆解工单(Disassembly Order)这一特殊生产订单类型的全流程设计与落地要点。内容覆盖拆解业务场景本质(如缺陷产品不可…

2026/9/25 7:22:16 阅读更多 →
脱硫和脱硝的区别与脱硫脱硝一体化选型(附工艺对比表)

脱硫和脱硝的区别与脱硫脱硝一体化选型(附工艺对比表)

开篇结论:脱硫和脱硝的区别:治理对象不同(SO₂和NOx),工艺路线不同(碱液喷淋和还原脱除)。脱硫脱硝一体化是系统集成不是单台设备。本文附两张对比表,帮你按工况选工艺。1. 脱硫与脱…

2026/9/25 7:22:11 阅读更多 →
华科834真题算法验证:PDF解析+NetworkX建模+Graphviz可视化

华科834真题算法验证:PDF解析+NetworkX建模+Graphviz可视化

简介:本资源为2019年华中科技大学硕士研究生入学考试《834计算机综合》真题完整试卷(PDF版),面向报考该校计算机相关专业的考研学生,聚焦数据结构、算法分析、操作系统基础及计算机网络核心考点的实战检验。试卷涵盖10…

2026/9/23 22:16:22 阅读更多 →

最新新闻

Havoc Framework 实战指南:现代可塑化后渗透 C2 框架的架构、部署与配置全解析

Havoc Framework 实战指南:现代可塑化后渗透 C2 框架的架构、部署与配置全解析

网络安全 【免费下载链接】Havoc The Havoc Framework 项目地址: https://gitcode.com/gh_mirrors/ha/Havoc 点击查看 免费下载 导读:Havoc 是一个由 C5pider 创建的现代可塑(malleable)后渗透 C2(Command and Contro…

2026/9/25 7:21:45 阅读更多 →
confd 发布流程详解:CHANGELOG 自动生成、版本号管理与跨平台二进制构建

confd 发布流程详解:CHANGELOG 自动生成、版本号管理与跨平台二进制构建

后端配置中心运维 【免费下载链接】confd Manage local application configuration files using templates and data from etcd or consul 项目地址: https://gitcode.com/gh_mirrors/co/confd 点击查看 免费下载 confd 的每个正式版本都不是"打个 tag 就完事…

2026/9/25 7:21:44 阅读更多 →
在 AWS Lambda 上部署 GraphQL Playground:基于 Serverless Framework 的完整实战指南

在 AWS Lambda 上部署 GraphQL Playground:基于 Serverless Framework 的完整实战指南

开发工具后端API设计 【免费下载链接】graphql-playground 🎮 GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration) 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-playground 点击查…

2026/9/25 7:21:44 阅读更多 →
Hippy AI 编程实战指南:Cursor / CodeBuddy / Knot 智能体配置与 Prompt 最佳实践

Hippy AI 编程实战指南:Cursor / CodeBuddy / Knot 智能体配置与 Prompt 最佳实践

跨平台移动开发前端 【免费下载链接】Hippy Hippy is designed to easily build cross-platform dynamic apps. 👏 项目地址: https://gitcode.com/gh_mirrors/hi/Hippy 点击查看 免费下载 本篇指南面向 Hippy 开发者,系统讲解如何借助 AI 编…

2026/9/25 7:21:44 阅读更多 →
trackerslist:75 个公共 BT Tracker 列表,粘贴进去把下载速度拉到 MB 级

trackerslist:75 个公共 BT Tracker 列表,粘贴进去把下载速度拉到 MB 级

trackerslist:75 个公共 BT Tracker 列表,粘贴进去把下载速度拉到 MB 级 【免费下载链接】trackerslist Updated list of public BitTorrent trackers 项目地址: https://gitcode.com/GitHub_Trending/tr/trackerslist 换电脑、重装系统后速度只剩…

2026/9/25 7:21:44 阅读更多 →
Atlas 300V部署YOLO实战:从环境配置到多路视频推理调优

Atlas 300V部署YOLO实战:从环境配置到多路视频推理调优

早两个月我把一张Atlas 300V插进服务器的时候,第一反应是:这卡到底算不算运算加速卡?插上去之后系统里没有nvidia-smi,没有CUDA,连安装包都换了一整套名字。查了一圈才搞明白,它确实是运算加速卡&#xff0…

2026/9/25 7:20:44 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →