ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Envoy SPIFFE 证书校验器如何利用 upstream SAN 覆盖实现上游对等证书的附加校验

Envoy SPIFFE 证书校验器如何利用 upstream SAN 覆盖实现上游对等证书的附加校验 Envoy SPIFFE 证书校验器如何利用 upstream SAN 覆盖实现上游对等证书的附加校验【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本指南围绕 Envoy 新增的envoy.reloadable_features.spiffe_validator_use_upstream_subject_alt_names运行时开关讲解 SPIFFE 证书校验器envoy.tls.cert_validator.spiffe如何通过知名 filter stateenvoy.network.upstream_subject_alt_names对上游对等证书的 SAN 名称进行附加校验并给出行为变更的语义、底层实现与测试证据。读完本文你将掌握该特性的启用方式、覆盖 SAN 与配置 SAN matcher 同时生效的双匹配规则以及如何通过运行时 guard 回退到旧行为。特性概述来自 changelog 的官方说明本特性记录在 tls__spiffe-validator-upstream-subject-alt-names.rst 中核心内容如下SPIFFE 证书校验器现在支持通过知名 filter stateenvoy.network.upstream_subject_alt_names对上游对等证书的 SAN 名称进行附加校验当同时存在覆盖的 SAN 列表override SAN list与配置的 SAN matchers时两者必须同时匹配Both the overridden SAN list and the configured SAN matchers must match if both are present该行为变更可以通过将运行时 guardenvoy.reloadable_features.spiffe_validator_use_upstream_subject_alt_names设置为false来回退revert。这是一条典型的 Envoy reloadable feature 类变更新行为默认开启但保留运行时开关以便在出现问题时可快速回滚避免破坏既有部署。理解两个关键概念SAN 覆盖列表与 filter stateupstream SAN 覆盖列表从何而来在 Envoy 的传输套接字选项中存在一个专门用于覆盖对端证书 SAN 校验的字段。其接口定义于 envoy/network/transport_socket.h核心方法为virtual const std::vectorstd::string verifySubjectAltNameListOverride() const PURE;verifySubjectAltNameListOverride()返回一组 SAN 字符串通常由上游upstream侧通过某种机制例如某个过滤器写入 filter state再由TransportSocketOptions携带注入到 TLS 连接建立流程中。它本质上是调用方期望对端证书里出现的 SAN 列表。知名 filter state 的命名该列表通过知名 filter state 键名envoy.network.upstream_subject_alt_names对外暴露。也就是说当某个过滤器filter在流式状态StreamInfo FilterState中写入这个键名时对应的 SAN 列表即可在 TLS 握手阶段被 SPIFFE 校验器读取用于校验上游证书。下游共享 filter state 对象的传递在 SPIFFE 校验器的实现里上游场景下它从transport_socket_options-downstreamSharedFilterStateObjects()中遍历查找目标对象完整调用链见 spiffe_validator.cc} else { if (transport_socket_options) { for (const auto obj_meta : transport_socket_options-downstreamSharedFilterStateObjects()) { if (obj_meta.name_ WorkloadTrustDomainKey) { obj dynamic_castconst Router::StringAccessor*(obj_meta.data_.get()); break; } } if (Runtime::runtimeFeatureEnabled( envoy.reloadable_features.spiffe_validator_use_upstream_subject_alt_names)) { verify_san_list transport_socket_options-verifySubjectAltNameListOverride(); } } }从源码结构看downstreamSharedFilterStateObjects()把下游过滤器的共享状态对象传递到上游连接的传输套接字选项中SPIFFE 校验器据此取得覆盖的 SAN 列表。注意读取覆盖列表的动作被Runtime::runtimeFeatureEnabled(...)包裹这正是 changelog 中提到的运行时 guard 的实际作用位置——guard 关闭时verify_san_list保持为空覆盖列表完全被忽略。双匹配语义覆盖 SAN 与配置 matcher 必须同时满足changelog 强调Both the overridden SAN list and the configured SAN matchers must match if both are present.实现层面的双校验在doVerifyCertChain中取得verify_san_list覆盖列表后会将其连同 workload trust domain 一起传给verifyCertChainUsingTrustBundleStore后者在完成 BoringSSL 的X509_verify_cert链校验之后顺序执行两段独立的 SAN 匹配见 spiffe_validator.cc// Do SAN matching. if (!verify_san_list.empty()) { bool san_match DefaultCertValidator::verifySubjectAltName(leaf_cert, verify_san_list); if (!san_match) { error_details absl::StrCat(verify cert failed: URI SAN peer identity mismatches, expected SANs: , absl::StrJoin(verify_san_list, , )); stats_.fail_verify_san_.inc(); return false; } } if (!subject_alt_name_matchers_.empty()) { bool san_match matchSubjectAltName(leaf_cert); if (!san_match) { error_details verify cert failed: SAN match; stats_.fail_verify_san_.inc(); return false; } }可以清晰看到三段逻辑链校验先通过 trust bundle store 完成 X.509 证书链校验X509_verify_cert覆盖 SAN 匹配若verify_san_list非空用DefaultCertValidator::verifySubjectAltName逐一比对叶子证书的 SAN失败时错误信息为URI SAN peer identity mismatches配置 matcher 匹配若subject_alt_name_matchers_非空用matchSubjectAltName匹配失败时错误信息为SAN match。两段匹配使用不同的错误提示便于定位是哪一层 SAN 校验失败。任何一个失败都会使校验整体失败Failed并递增统计量fail_verify_san_。测试用例的完整验证测试文件 spiffe_validator_test.cc 中的TestDoVerifyCertChainWithSanOverrideAndMatchers覆盖了三种组合场景测试证书san_uri_cert.pem的 URI SAN 为spiffe://lyft.com/test-team场景覆盖 SAN配置 matcher预期结果双匹配成功spiffe://lyft.com/test-team前缀spiffe://lyft.com/Successful覆盖匹配、matcher 不匹配spiffe://lyft.com/test-team前缀spiffe://example.com/Failed错误verify cert failed: SAN matchmatcher 匹配、覆盖不匹配spiffe://lyft.com/wrong-team前缀spiffe://lyft.com/Failed错误URI SAN peer identity mismatches而TestDoVerifyCertChainWithSanOverrideDisabled则验证了运行时 guard 关闭后的行为即使覆盖列表是错误的值spiffe://lyft.com/wrong-team由于覆盖列表被忽略且没有配置 matcher校验依然Successful。这正是行为变更可以回退的测试级证据。运行时 guard如何开启、关闭与回退该特性的开关是标准 Envoy reloadable feature 运行时标志envoy.reloadable_features.spiffe_validator_use_upstream_subject_alt_names默认行为默认开启值为trueSPIFFE 校验器读取verifySubjectAltNameListOverride()对上游证书执行覆盖 SAN 的附加校验回退方式将运行时值设置为false即可恢复旧行为忽略覆盖列表。配置方式在 bootstrap 配置的runtime部分或使用分层运行时 overlay中设置runtime: layered_runtime: - name: static_layer static_layer: envoy: reloadable_features: spiffe_validator_use_upstream_subject_alt_names: false测试代码中对应的设置方式是通过TestScopedRuntime合并运行时值见 spiffe_validator_test.ccTestScopedRuntime scoped_runtime; scoped_runtime.mergeValues( {{envoy.reloadable_features.spiffe_validator_use_upstream_subject_alt_names, false}});底层实现原理从 filter state 到 SAN 校验的完整链路综合 spiffe_validator.cc 的源码该特性的完整数据流可以归纳为上游侧注入上游连接建立前某过滤器向 StreamInfo FilterState 写入知名键envoy.network.upstream_subject_alt_names覆盖 SAN 列表该列表最终被放入TransportSocketOptions校验器读取SPIFFE 校验器在doVerifyCertChain的客户端分支is_server false中遍历downstreamSharedFilterStateObjects()找到目标对象在运行时 guard 开启的前提下通过verifySubjectAltNameListOverride()取出覆盖列表双段匹配verifyCertChainUsingTrustBundleStore在完成证书链验证后先执行覆盖 SAN 列表的精确匹配再执行配置的subject_alt_name_matchers_支持前缀、精确、正则等StringMatcher语义匹配失败处理任一匹配失败即返回Failed并递增fail_verify_san_统计同时附带区分度较高的错误详情URI SAN peer identity mismatches或SAN match便于运维排查。需要特别说明的是该 SAN 覆盖机制只在上游客户端校验对端服务器证书方向生效服务端方向仍以 workload trust domainenvoy.tls.cert_validator.spiffe.workload_trust_domain作为身份判定依据。注意事项与适用前提启用前提SPIFFE 校验器配置为自定义证书校验器name: envoy.tls.cert_validator.spiffe类型为envoy.extensions.transport_sockets.tls.v3.SPIFFECertValidatorConfig并配置trust_domains时该特性才相关双匹配是与关系只要覆盖列表与 matchers 同时存在二者必须同时通过缺一不可不能理解为二选一回退机制升级后若遇到上游连接因覆盖 SAN 校验失败可先将spiffe_validator_use_upstream_subject_alt_names置为false快速恢复旧行为再排查是谁在 filter state 中写入了错误的 SAN 覆盖值统计观测可通过fail_verify_san_统计量的递增情况确认是否由 SAN 匹配失败导致并结合错误详情中的expected SANs列表核对覆盖值是否正确。小结本特性让 SPIFFE 证书校验器在原有 trust domain SAN matcher 校验体系之上新增了一条来自envoy.network.upstream_subject_alt_namesfilter state 的 SAN 覆盖校验路径并以覆盖列表与配置 matcher 双匹配的严格语义加强了上游对等身份验证。对运行在 SPIFFE 信任模型下的服务网格与边车代理场景这为动态注入上游 SAN 期望值提供了标准化入口而运行时 guard 的存在则让该行为变更具备平滑回退能力降低了升级风险。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表