后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载导读本文围绕 EMQX 仓库变更记录 changes/ee/fix-18314.en.md 展开剖析一项针对数据集成安全的关键修复当通过 HTTP API 读取使用 JSON Service Account 认证的 GCP 连接器GCP Pub/Sub Producer/Consumer、BigQuery时连接器配置中的敏感凭据将被统一脱敏为******避免私钥等密钥材料通过管理接口泄露。读完本文你将掌握 EMQX 连接器敏感字段的脱敏redact与反脱敏deobfuscate闭环机制、涉及的具体源码实现与测试验证以及如何在真实 API 调用中确认该行为。变更背景一次面向凭据安全的加固原始变更内容只有一句话但其含义在数据集成安全场景下十分重要When reading GCP Connectors (GCP PubSub Producer/Consumer, Bigquery) that use JSON Service Account authentication via the HTTP API, now the values are redacted.即通过 HTTP API 读取使用 JSON Service Account 认证的 GCP 连接器时凭据值现在会被脱敏。在此之前GET /connectors/:id之类的查询接口可能将完整的服务账号 JSON其中包含private_key私钥原样返回给调用方任何拥有只读管理权限的用户都能看到密钥材料。本次修复后API 响应中不再出现真实凭据。该修复的落点集中在三类 GCP 集成连接器上连接器对应应用目录认证方式GCP Pub/Sub Producerapps/emqx_bridge_gcp_pubsubService Account JSON 等GCP Pub/Sub Consumerapps/emqx_bridge_gcp_pubsubService Account JSON 等BigQueryapps/emqx_bridge_bigqueryService Account JSON 等从源码结构看这三类连接器共享同一个 GCP 认证 schema 库 apps/emqx_bridge_gcp_pubsub/src/emqx_bridge_gcp_pubsub_schema_lib.erl因此一次修复即可覆盖多个连接器BigTable 等复用同一库的连接器同样受益。GCP 连接器的三种认证方式在理解脱敏之前先明确service_account_json在连接器配置中的位置。从 emqx_bridge_gcp_pubsub_schema_lib.erl 的authentication_field/0可见GCP 认证是一个 union 类型支持三种方式attached_service_account挂载服务账号使用 EMQX 所在 Compute Engine 实例上挂载的 GCP 服务账号无需在配置中存放任何凭据service_account_json服务账号 JSON直接填写创建服务账号时下载的 JSON 凭据文件内容包含private_key私钥属于高度敏感字段wifWorkload Identity Federation通过 GCP Workload Identity Federation 使用联邦 token配置中包含service_account_email、gcp_project_id、gcp_project_number、gcp_wif_pool_id、gcp_wif_pool_provider_id以及initial_tokenOIDC client credentials其中client_secret同样是敏感字段。对应的国际化描述见 rel/i18n/emqx_bridge_gcp_pubsub_schema_lib.hoconservice_account_json的说明为“包含要与 GCP 一起使用的 GCP 服务账号凭据的 JSON即创建服务账号时下载的凭据文件”。三种方式中service_account_json携带私钥明文是本次脱敏保护的核心对象wif下的client_secret同样被sensitive true标记。敏感字段是如何被标记的schema 层的sensitive声明脱敏的第一步是在 schema 定义中将字段标记为敏感。以 emqx_bridge_gcp_pubsub_schema_lib.erl 中fields(auth_service_account_json)为例{service_account_json, emqx_schema_secret:mk( #{ required false, validator fun ?MODULE:service_account_json_validator/2, sensitive true, desc ?DESC(service_account_json) } )}关键点有两处sensitive true向配置系统声明该字段为敏感信息这是后续脱敏行为的依据emqx_schema_secret:mk/1将字段包装为 secret 类型支持直接填写 JSON 字符串也支持file://...形式的文件引用——当使用文件引用时EMQX 会读取文件内容作为凭据而配置中只保存文件路径。BigQuery 连接器的 schema apps/emqx_bridge_bigquery/src/emqx_bridge_bigquery_connector_schema.erl 与 GCP Pub/Sub 的 emqx_bridge_gcp_pubsub.erl 都以完全相同的sensitive true方式声明service_account_json并且直接复用emqx_bridge_gcp_pubsub_schema_lib:service_account_json_validator/2作为校验器。这正是“一次修复覆盖多个连接器”的实现基础。除了service_account_jsonwif认证下的client_secret见 emqx_bridge_gcp_pubsub_schema_lib.erl也声明为sensitive true。凭据校验逻辑service_account_json_validator/2定义了合法的服务账号 JSON 结构emqx_bridge_gcp_pubsub_schema_lib.erl必须是合法 JSON且必须包含以下五个键且type必须为service_accounttypeproject_idprivate_key_idprivate_keyclient_email校验器先通过emqx_secret:unwrap/1解开 secret 包装file://引用会在此处被解析为文件内容再解码为 map 检查必填键。若命中脱敏值maybe_obfuscated上下文下值为******则直接放行交由 HTTP API 层在更新流程中反脱敏。脱敏核心emqx_utils_redact的递归脱敏引擎所有连接器 API 的脱敏最终都汇聚到通用工具模块 apps/emqx_utils/src/emqx_utils_redact.erl。该模块对外提供redact/1、redact/2递归脱敏 termmap、tuple、list、任意嵌套redact_headers/1针对 HTTP 头部的脱敏authorization、api-key、cookie等is_sensitive_key/1判断键名是否为敏感键is_redacted/2,3判断某个值是否已被脱敏deobfuscate/2,3反脱敏更新配置时用旧值恢复敏感字段redacted_value/0返回脱敏占位值******。敏感键名单is_sensitive_key/1维护了一份按字母序排列的敏感键清单emqx_utils_redact.erl支持 atom、string、binary 三种键形式与本主题直接相关的条目包括is_sensitive_key(private_key) - true; %% 服务账号 JSON 中的私钥 is_sensitive_key(service_account_json) - true; %% 整个服务账号 JSON 字段 is_sensitive_key(client_secret) - true; %% WIF 的 OAuth Client Secret is_sensitive_key(token) - true; is_sensitive_key(access_token) - true; is_sensitive_key(password) - true; ... is_sensitive_key(_) - false.因此只要配置树中某键名为service_account_json无论嵌套多深redact/1都会将其值替换为******。递归遍历由do_redact/2,3实现emqx_utils_redact.erlmap 逐键处理tuple 转为 list 处理后还原list 逐元素处理非敏感键则继续下钻其值——这保证了即便敏感字段被包裹在authentication等嵌套 map 中也能被命中。值的处理细节redact_v/1emqx_utils_redact.erl对敏感键对应的值做了精细处理二进制/列表值统一替换为******file://前缀的值保留原样。因为file://...只是文件路径引用而非凭据本身路径本身不构成敏感信息且保留它才能让后续反脱敏正确工作模板占位符值若值是${var}形式的占位符模板也保留原样避免破坏变量引用语义secret 包装值尝试解包后递归处理无法解包则替换为******。do_redact_v(file://, _/binary V) - V; %% 文件引用不脱敏 do_redact_v(file:// _ V) - V; do_redact_v(B) when is_binary(B) - ?REDACT_VAL; %% 普通二进制 - ****** do_redact_v(L) when is_list(L) - ?REDACT_VAL; ...其中?REDACT_VAL定义在模块头部-define(REDACT_VAL, ******)emqx_utils_redact.erl。反脱敏更新配置时恢复真实凭据脱敏不能破坏“编辑后保存”的正常流程。deobfuscate/3emqx_utils_redact.erl实现反向恢复遍历新配置若某键值已被脱敏is_redacted/3命中则从旧配置中取出原值填回若旧配置中不存在该键说明是新增字段则直接丢弃脱敏值而非将其写入配置。headers与client_jwks有专门的恢复分支以支持大小写不敏感匹配与 JWKS 文件键恢复。HTTP API 层脱敏与反脱敏的完整闭环脱敏在 HTTP API 层的落点集中在 apps/emqx_connector/src/emqx_connector_api.erl。其filter/2回调会为请求附加maybe_obfuscated true上下文见 emqx_connector_api.erl告诉 schema 校验器“请求体中可能携带已脱敏的值”从而让service_account_json_validator对******放行。读取GET输出侧强制脱敏/connectors/:id(get, ...)的响应构造中fill_defaults/2在填充默认值时显式传入obfuscate_sensitive_values trueemqx_connector_api.erl随后对合并后的完整连接器信息统一执行redact/1emqx_connector_api.erlResourceData lookup_channels(Namespace, Type, ConnectorName, ResourceData0), RawConf fill_defaults(Type, RawConf0), redact( maps:merge(RawConf#{namespace ..., type Type, name ...}) ),因此GET /connectors/:id返回的authentication.service_account_json字段值恒为******真实 JSON 不会离开节点。更新PUT反脱敏后再落盘/connectors/:id(put, ...)在更新前调用deobfuscate(ConnectorType, Conf1, RawConf)emqx_connector_api.erl用已持久化的旧配置恢复请求体中的******再执行配置更新。这样用户在 dashboard 或 API 客户端中看到的永远是脱敏值而实际保存的仍是真实凭据。对于 MQTT 连接器中含嵌套 secret 的数组字段还实现了专用的deobfuscate_mqtt_connector逻辑emqx_connector_api.erl。探测与错误路径避免错误信息泄露凭据/connectors_probe与/connectors/:id/:operation的返回内容同样经过redact/1处理emqx_connector_api.erl确保连接测试失败时错误响应中不会夹带真实密钥。此外GET 响应的status_reason等诊断信息也会被redact/1清洗emqx_connector_api.erl。完整的 API 行为示意以下调用示意字段值以当前仓库 schema 为准仅为演示脱敏效果# 创建使用 Service Account JSON 认证的 BigQuery 连接器 curl -X POST http://localhost:18083/api/v5/connectors \ -u admin:public \ -H Content-Type: application/json \ -d { type: bigquery, name: my_bq, enable: true, authentication: { type: service_account_json, service_account_json: {\type\:\service_account\,\project_id\:\my-project\,\private_key_id\:\k1\,\private_key\:\-----BEGIN PRIVATE KEY-----...\,\client_email\:\samy-project.iam.gserviceaccount.com\} } } # 读取该连接器service_account_json 已脱敏为 ****** curl http://localhost:18083/api/v5/connectors/bigquery:my_bq -u admin:public # authentication: { type: service_account_json, service_account_json: ****** }测试验证行为有据可查本次修复在测试套件中留下了直接验证。以 BigQuery 为例apps/emqx_bridge_bigquery/test/emqx_bridge_bigquery_SUITE.erl 的t_legacy_service_account_json_redact/1用例完整覆盖了创建、读取、更新、探测四条路径%% 创建响应service_account_json 已脱敏 ?assertMatch( {201, #{authentication : #{service_account_json : ******}}}, create_connector_api(TCConfig, #{}) ), %% 读取响应service_account_json 已脱敏 ?assertMatch( {200, #{authentication : #{service_account_json : ******}}}, get_connector_api(TCConfig) ), %% 用脱敏后的参数更新仍能成功 ?assertMatch( {200, #{status : connected, authentication : #{service_account_json : ******}}}, update_connector_api(TCConfig, RedactedParams) ), %% 持久化配置中保存的仍是真实 JSON而非脱敏值 ?assertMatch({, _/binary, persisted_service_account_json(TCConfig)),这段测试同时印证了两个关键结论API 出口必然脱敏创建、读取、更新后的响应中service_account_json均为******内部存储不被破坏持久化配置中保存的仍是完整的真实 JSON断言以{开头说明脱敏只发生在 API 边界不影响连接器实际使用凭据建立连接。兼容性旧版根级字段的自动迁移service_account_json并非一直位于authentication之下。legacy_service_account_json_root_converter/2emqx_bridge_gcp_pubsub_schema_lib.erl负责将旧版配置中位于连接器根级的service_account_json自动迁移到authentication.service_account_json结构下legacy_service_account_json_root_converter(Conf0, _HoconOpts) - case Conf0 of #{service_account_json : SAJ0} - Conf maps:remove(service_account_json, Conf0), SAJ case is_map(SAJ0) of true - emqx_utils_json:encode(SAJ0); %% 旧 schema 是对象编码为 JSON 字符串 false - SAJ0 end, Conf#{ authentication #{ type service_account_json, service_account_json SAJ } }; _ - Conf0 end.该转换器被 BigQuery 连接器 schema 的config_connector、post_connector、put_connector三条路径注册emqx_bridge_bigquery_connector_schema.erl与测试用例中“在 6.2.0 中该字段被移动到authentication键之下”的注释相互印证。升级后读取旧配置API 返回的是迁移后的新结构且同样经过脱敏。总结一次修复三层防护本次变更并非孤立的字符串替换而是由三层机制共同构成的凭据安全体系schema 层标记service_account_json、client_secret等字段声明sensitive true并共享统一的 GCP 认证 schema 库使 GCP Pub/SubProducer/Consumer、BigQuery 等连接器一次接入即可获得保护通用脱敏引擎emqx_utils_redact.erl 提供递归脱敏、敏感键名单、file://引用豁免与反脱敏恢复能力且对private_key、token、password等一大批通用敏感键名同样生效API 边界闭环emqx_connector_api.erl 在读取、更新、探测、错误响应等所有出口统一执行redact/1并在更新入口用deobfuscate/2恢复真实值保证“对外只见******、对内存储真实凭据、编辑保存不受影响”。对于部署了 GCP 数据集成连接器的 EMQX 用户升级到包含本修复的版本后无需修改任何连接器配置管理 API 的凭据暴露风险即被自动消除——这正是该变更记录在 changes/ee/fix-18314.en.md 中一句话背后完整的安全设计。赞分享后端物联网消息队列通信【免费下载链接】emqxThe most scalable and reliable MQTT broker for AI, IoT, IIoT and connected vehicles项目地址https://gitcode.com/gh_mirrors/em/emqx点击查看免费下载相关推荐EMQX GCP 连接器 Attached Service Account 认证在 GCP VM 上自动获取实例元数据 TokenEMQX GCP 连接器 Attached Service Account 认证在 GCP VM 上自动获取实例元数据 Token 导读 本篇文章聚焦 EMQ后端物联网消息队列通信EMQX GCP 连接器 Workload Identity Federation (WIF) 认证实战指南基于 Service Account Impersonation 的免密钥接入EMQX GCP 连接器 Workload Identity Federation WIF 认证实战指南基于 Service Account Imperson后端物联网消息队列通信EMQX Prometheus 配置 API 安全修复push gateway 的 Authorization 头脱敏机制解析EMQX Prometheus 配置 API 安全修复push gateway 的 Authorization 头脱敏机制解析 本文基于 EMQX 开源仓库中后端物联网消息队列通信上一篇Llama-medx_v3 vs 传统医疗NLP模型为什么它能成为临床文本处理的终极选择下一篇【免费下载】 精准测试ADCMatlab代码助力动态与静态参数分析【matlab下载】创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考