Envoy 的 SSL 库构建配置指南:BoringSSL、BoringSSL-FIPS 与 OpenSSL 的选择与验证

发布时间:2026/9/10 12:37:57
Envoy 的 SSL 库构建配置指南:BoringSSL、BoringSSL-FIPS 与 OpenSSL 的选择与验证 Envoy 的 SSL 库构建配置指南BoringSSL、BoringSSL-FIPS 与 OpenSSL 的选择与验证【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy本文基于 Envoy 仓库中的 bazel/SSL.md 编写系统讲解 Envoy 的 SSL 库构建体系默认的 BoringSSL、面向合规场景的 BoringSSL-FIPS以及可选的 OpenSSL 动态加载方案。读完本文你将掌握三类构建命令、各方案的架构支持与版本字符串特征、从旧版--define boringsslfips的迁移方法以及通过envoy --version验证构建结果的标准流程。一、Envoy 的 SSL 库选型总览作为云原生边缘/中间/服务代理Envoy 的 TLS 能力由底层的 SSL 库提供。当前仓库支持三种 SSL 构建形态全部通过 Bazel 的--config参数切换构建形态对应 config默认状态版本字符串标准 BoringSSL无默认默认BoringSSLBoringSSL-FIPS--configboringssl-fips可选BoringSSL-FIPSOpenSSL--configopenssl可选OpenSSL选择依据很简单没有特殊合规要求时直接用默认 BoringSSL需要 FIPS 140 合规且运行在 Linux x86_64/aarch64 上时用 BoringSSL-FIPS因业务或生态原因必须使用 OpenSSL 时再用--configopenssl。需要特别注意的是三种形态的版本字符串都由编译期宏注入详见本文第五部分因此构建完成后可以随时通过envoy --version快速确认实际链接的是哪个库。二、默认非 FIPS构建零配置即可使用 BoringSSL默认构建无需任何额外配置BoringSSL 是 Envoy 的默认 SSL 实现直接执行标准构建命令即可bazel build //source/exe:envoy-static从仓库的 bazel/BUILD 可以看到默认值的来源label_flag( name ssl, build_setting_default boringssl//:ssl, ) label_flag( name crypto, build_setting_default boringssl//:crypto, )即//bazel:ssl与//bazel:crypto两个标签的默认值分别指向boringssl//:ssl和boringssl//:crypto。也就是说任何不显式覆盖这两个标签的构建都会默认链接标准 BoringSSL无需用户干预。三、FIPS 构建BoringSSL-FIPS3.1 支持的 FIPS 构建与架构Envoy 项目目前仅在 x86_64 上对 BoringSSL FIPS 构建提供官方支持与测试。仓库欢迎其他库或架构的补丁但维护与兼容性修复的责任由下游项目自行承担。具体到 BoringSSL-FIPS 形态bazel/SSL.md 给出的支持范围是支持的架构Linux x86_64、aarch64版本字符串BoringSSL-FIPS可在envoy --version输出中看到Envoy 遵循 BoringSSL 的 FIPS Update Stream 策略每当创建 Envoy 稳定发布分支时所使用的 BoringSSL FIPS 版本都会与该策略保持兼容除非出现影响 Envoy 的 Bug 或安全漏洞否则该版本以及配套的构建工具版本在发布分支上不会变更。3.2 构建命令bazel build --configboringssl-fips //source/exe:envoy-static--configboringssl-fips在 .bazelrc 中展开为一系列相互关联的配置common:fips-common --envoy//bazel:fipsTrue common:fips-common --test_tag_filters-nofips common:fips-common --build_tag_filters-nofips common:boringssl-fips --configfips-common common:boringssl-fips --envoy//bazel:sslboringssl-fips//:ssl common:boringssl-fips --envoy//bazel:cryptoboringssl-fips//:crypto common:boringssl-fips --quiche//:ssl_libboringssl-fips//:ssl这里有几个关键细节--envoy//bazel:fipsTrue开启 FIPS 语义标记不仅把ssl、crypto两个标签切到boringssl-fips连 QUICHEHTTP/3 的 QUIC 栈的ssl_lib也一并切到 FIPS 库确保全二进制使用同一套 SSL 实现避免符号/ABI 冲突--test_tag_filters-nofips与--build_tag_filters-nofips会过滤掉标注为nofips的测试与构建目标——这类目标通常依赖 FIPS 模式不支持的算法或特性在 FIPS 构建中应被排除。四、OpenSSL动态加载的替代方案4.1 与 BoringSSL 的本质差异BoringSSL 是 Envoy 官方支持且默认的 SSL 实现OpenSSL 只是替代方案。两者最根本的差异在于链接方式BoringSSL 系列直接静态链接进 Envoy 二进制OpenSSL 库不会被静态链接进 Envoy。OpenSSL 库要求3.5 或更高版本仓库 MODULE.bazel 中声明为bazel_dep(name openssl, version 3.5.7.envoy)必须在运行时存在由 Envoy 通过dlopen()动态加载FIPS 模式在 OpenSSL 中是运行时强制开启的通过 OpenSSL 本身和/或操作系统配置而不是像 BoringSSL-FIPS 那样在构建期决定。这一设计在 compat/openssl/README.md 中有更完整的描述bssl-compat兼容层实现了 BoringSSL API但底层调用转发到 OpenSSLsource/ossl.c中的转发函数通过dlopen/dlsym调用 OpenSSL。该库以 C ABI 的静态库形式交付bssl-compat//:bssl-compat并刻意只做data依赖而非link依赖从而避免客户端把 OpenSSL 库链接进二进制。4.2 构建命令与注意事项bazel build --configopenssl //source/exe:envoy-static对应到 .bazelrccommon:openssl --envoy//bazel:opensslTrue common:openssl --envoy//bazel:sslenvoy//compat/openssl:ssl common:openssl --envoy//bazel:cryptoenvoy//compat/openssl:crypto common:openssl --quiche//:ssl_libenvoy//compat/openssl:ssl common:openssl --copt-DENVOY_SSL_OPENSSL common:openssl --host_copt-DENVOY_SSL_OPENSSL common:openssl --envoy//bazel:http3False common:openssl --definequiche_disable_http3true common:openssl --test_tag_filters-nofips,-quiche common:openssl --build_tag_filters-nofips关键约束与注意事项支持的架构Linux x86_64、aarch64、ppc64le版本字符串OpenSSL可见于envoy --versionHTTP/3QUIC在 OpenSSL 构建中被禁用config 将//bazel:http3置为False并额外--definequiche_disable_http3true把依赖 BoringSSL 专属原语如SIPHASH_24的 QUIC 代码排除在 OpenSSL 构建之外。不过 QUICHE 库仍会因非 QUIC 特性如 HTTP datagram / CONNECT-UDP capsule 支持被链接进来因此其ssl_lib也必须指向 OpenSSL 兼容层防止 BoringSSL 与 OpenSSL 同时链接进同一二进制引发符号/ABI 冲突安全策略范围OpenSSL 构建目前不在 Envoy 安全策略SECURITY.md的覆盖范围内。这意味着用--configopenssl产出的二进制不受 Envoy 官方安全公告流程保护生产环境选用前需自行评估风险FIPS 语义在 OpenSSL 形态下启用 FIPS 属于运行时行为通过 OpenSSL 的 FIPS 模块配置或操作系统层配置完成与构建期无关。五、从旧版--define boringsslfips迁移历史版本使用--define boringsslfips选择 FIPS 库该标志已失效直接使用会构建失败。仓库通过 bazel/deprecated_features.bzl 中的check_removed_fips_define规则主动检测一旦检测到ctx.var.get(boringssl) fips就会fail()并输出迁移提示。迁移对照表如下旧用法新用法--define boringsslfips--configboringssl-fips--define boringsslfips在 ppc64le 上--configopenssl迁移逻辑的要点旧标志在 ppc64le 上会自动选择一个 FIPS 库而新方案要求显式选择库。在 ppc64le 上应使用--configopensslOpenSSL 的 FIPS 模式在运行时强制开启而非 BoringSSL-FIPS。六、SSL 标志完整性为什么不能直接设置底层标志Bazel 的 SSL 配置由三个相互依赖的标志共同决定//bazel:ssl、//bazel:crypto和//bazel:fips此外 OpenSSL 形态还涉及//bazel:openssl。这三个标志定义在 bazel/BUILDlabel_flag(name ssl, build_setting_default boringssl//:ssl) label_flag(name crypto, build_setting_default boringssl//:crypto) bool_flag(name fips, build_setting_default False) bool_flag(name openssl, build_setting_default False)配套的config_settingbazel/BUILD用于在源码树中判断当前形态config_setting(name fips_build, flag_values {:fips: True}) config_setting(name using_boringssl, flag_values {:ssl: boringssl//:ssl}) config_setting(name using_boringssl_fips, flag_values {:ssl: boringssl-fips//:ssl}) config_setting(name using_openssl, flag_values {:openssl: True})切勿直接设置这些标志。原因很直接不一致的组合会产生损坏的构建或错误的版本字符串。例如选了一个 FIPS 库却保持--//bazel:fipsFalse或ssl与crypto指向不同库都会破坏构建一致性--config选项boringssl-fips/openssl在 .bazelrc 中一次性把ssl、crypto、fips/openssl乃至quiche的ssl_lib统一设置好保证三/四者始终一致。七、版本字符串的生成原理envoy --version中出现的BoringSSL/BoringSSL-FIPS/OpenSSL并非运行时探测结果而是编译期宏注入的固定字符串。在 source/common/version/BUILD 中version_string_lib通过select依据上文提到的config_setting注入宏copts select({ //bazel:using_boringssl_fips: [-DENVOY_SSL_VERSION\BoringSSL-FIPS\], //bazel:using_openssl: [-DENVOY_SSL_VERSION\OpenSSL\], //conditions:default: [-DENVOY_SSL_VERSION\BoringSSL\], }),而 source/common/version/version_string.cc 中的实现则把它拼进完整的版本字符串const std::string envoySSLVersion() { #ifdef ENVOY_SSL_VERSION static const std::string version ENVOY_SSL_VERSION; #else static const std::string version no-ssl; #endif return version; } const std::string envoyVersionString() { CONSTRUCT_ON_FIRST_USE(std::string, fmt::format({}/{}{}/{}/{}/{}, build_scm_revision, BUILD_VERSION_NUMBER, build_version_suffix, build_scm_status, envoyBuildType(), envoySSLVersion())); }因此完整的版本串形如1.32.0/abc123.Modified/RELEASE/BoringSSL格式说明见 version_string.h。这也解释了为什么“错误的 SSL 标志组合会导致错误的版本字符串”宏在编译期就被select固化标志设置不一致时版本串与实际链接库就会对不上。八、验证构建结果构建完成后运行envoy --version根据输出的最后一段判断实际生效的 SSL 库BoringSSL-FIPS— BoringSSL FIPS 构建BoringSSL— 标准非 FIPS构建OpenSSL— OpenSSL 构建九、快速决策清单场景推荐方案常规生产环境无 FIPS 合规要求默认构建BoringSSL零配置需要 FIPS 140 合规Linux x86_64/aarch64--configboringssl-fips必须使用 OpenSSL如组织强制要求Linux x86_64/aarch64/ppc64le--configopenssl注意 HTTP/3 禁用、不受 Envoy 安全策略覆盖迁移旧构建脚本将--define boringsslfips替换为上表对应--config无论选择哪种形态都建议在构建后用envoy --version复核版本字符串并确认构建配置与预期一致——这是避免“构建成功但 SSL 库不对”这类隐蔽问题的最直接手段。【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考