资讯动态

curl 集成 Rustls:以 rustls-ffi 为 TLS 后端的构建指南与源码级解析

发布时间:2026/9/10 5:44:51 来源:尧图企业网站定制
curl 集成 Rustls以 rustls-ffi 为 TLS 后端的构建指南与源码级解析【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curlRustls 是一个用 Rust 编写的 TLS 协议实现curl 可以像使用 OpenSSL、GnuTLS、Schannel 一样将它作为自己的 TLS 后端用于 HTTPS 等 TLS 流量加密与服务器身份验证。本文以 docs/RUSTLS.md 为核心依据先完整介绍获取 rustls-ffiRustls 的 C 绑定库的三种方式与对应 curl 构建命令再从 m4/configure 检测脚本和 lib/vtls/rustls.c 源码出发说明 curl 是如何发现、链接并驱动这个 Rust 后端的。读完本文你将能够独立完成rustls 化的 curl 构建并理解其信任链验证、ALPN、错误映射等内部机制。背景为什么 curl 需要一个 Rust 编写的 TLS 后端TLS 是 curl 访问 HTTPS 站点时的核心依赖。历史上 curl 主要绑定 OpenSSL 及其分支但也长期支持 GnuTLS、mbedTLS、wolfSSL、Schannel、Secure Transport 等众多后端。Rustls 正是这些可选项中的一员它完全由 Rust 实现代码以内存安全为设计目标它只做 TLS 客户端/服务端库本身的事默认不直接读系统证书文件而是通过验证器verifier与根证书存储结合工作为方便 C 语言项目调用社区维护了 rustls-ffi 这一套 C ABI 绑定curl 正是通过它接入 Rustls 的。在 curl 中Rustls 后端的名字是rustls对应的后端标识为CURLSSLBACKEND_RUSTLS这一点可以直接在 lib/vtls/rustls.c 的Curl_ssl_rustls结构体首字段看到。根据 docs/RUSTLS.md 的说明当前这份代码兼容的是rustls-ffi v0.15.x系列。构建前准备三条获取 rustls-ffi 的路径rustls-ffi 是编译期依赖动态链接的库与头文件curl 不会替你下载它。文档给出了三种获取途径任选其一即可之后的 curl 构建命令大体相同区别只在于是否需要在--with-rustls后跟安装前缀路径。方式一从系统包管理器安装如果发行版的软件源已收录 rustls-ffi打包状态与安装细节因发行版而异请以 rustls-ffi 的 README 中 packaging 说明为准安装后即可用不带路径的--with-rustls构建 curlgit clone --depth 1 curl 仓库地址 cd curl autoreconf -fi ./configure --with-rustls make其中autoreconf -fi用于从 Git 源码生成 configure 脚本发布 tarball 已内置可跳过。不带路径的--with-rustls会让配置系统优先尝试通过pkg-config探测rustls.pc具体探测逻辑见下文 m4 脚本剖析。方式二下载 rustls-ffi 预编译二进制rustls-ffi 自 0.15.0 起在官方 Releases 页提供各平台的预编译归档。下载并解压到任意目录文档示例为${HOME}/rustls-ffi-built构建 curl 时把该前缀传给 configuregit clone --depth 1 curl 仓库地址 cd curl autoreconf -fi ./configure --with-rustls${HOME}/rustls-ffi-built make归档内通常包含include/rustls.h头文件与lib目录下的库文件这与 configure 对安装根目录的约定一致见后文对PREFIX_RUSTLS的分析。方式三从源码构建 rustls-ffi这种方式最灵活也便于锁定版本。需要两样工具Rust 编译器通过 rustup 或发行版包管理器安装1.73 或更新的工具链cargo-ccargo 插件提供cargo capi命令用于构建并安装 C 库。可用发行版包管理器安装、下载预编译归档或用cargo install cargo-c编译。然后检出与 curl 兼容的 rustls-ffi 版本文档示例为 v0.15.3 标签并安装到自定义前缀git clone --depth 1 --branch v0.15.3 rustls-ffi 仓库地址 cd rustls-ffi cargo capi install --release --prefix${HOME}/rustls-ffi-built最后构建 curl指向同一前缀git clone --depth 1 curl 仓库地址 cd curl autoreconf -fi ./configure --with-rustls${HOME}/rustls-ffi-built make需要说明的是rustls 的密码学运算依赖一个 cryptography provider提供 AES、SHA 等原语常见如 aws-lc-rs、RustCrypto 等不同 provider 的构建与平台要求不同docs/RUSTLS.md 建议在需要调整时查阅 rustls-ffi 对应文档中的 cryptography provider 一节后再决定构建方式。configure 如何找到 Rustlsm4 宏与 configure.ac 剖析命令行入口在 configure.ac 中定义了构建选项OPT_RUSTLSno AC_ARG_WITH(rustls, AS_HELP_STRING([--with-rustlsPATH],[where to look for Rustls, PATH points to the installation root]),[ OPT_RUSTLS$withval ... ])可见默认不启用OPT_RUSTLSno--with-rustls可带PATH该路径被解释为Rustls 安装根目录传入路径时Rustls 还会被登记进 curl 的 experimental实验性特性名单这对应了 curl 对该后端可用但定位实验性的态度。m4 探测逻辑真正的探测在 m4/curl-rustls.m4 的CURL_WITH_RUSTLS宏里其流程可概括为区分yes与具体路径--with-rustls不带路径时走 pkg-config带路径时先检查$prefix/lib/pkgconfig/rustls.pc不存在再尝试$prefix/lib64/pkgconfig/rustls.pc找到则仍走 pkg-configm4/curl-rustls.m4。无 pkg-config 时的兜底直接用路径拼装编译参数-I$PREFIX/include、-L$PREFIX/lib并补充额外系统库见下文同时定义USE_RUSTLSm4/curl-rustls.m4。符号级验证无论哪条路径最终都会用AC_CHECK_LIB(rustls, rustls_supported_hpke, ...)做一次真实链接测试确认库中确有该符号否则直接报错 could not find compatible Rustlsm4/curl-rustls.m4。rustls_supported_hpke与 HPKE/ECH 支持相关可作为判断 rustls 版本能力的一个探针。平台附加依赖非 Windows 平台需要把-lpthread -ldl -lm一并链入Apple 平台则是-framework Security -framework Foundation这些在 CMake 的查找模块中同样有对应处理CMake/FindRustls.cmake。写入 libcurl 的私有依赖通过 pkg-config 找到时会在生成的libcurl.pc中追加Requires.private: rustlsm4/curl-rustls.m4。此外configure.ac 中还有一组 TLS 后端的互斥/提示逻辑如果用户禁用了 SSL 却又期望启用 TLS 功能configure 会提示使用--with-rustls等选项。启用成功后 configure 会打印detected Rustls并在最终的 SSL backend 列表中登记Rustls。CMake 构建路径不习惯 autotools 的开发者可以用 CMake。curl 提供了独立的查找模块 CMake/FindRustls.cmake其输入输出变量如下变量含义RUSTLS_INCLUDE_DIRrustls 头文件目录含rustls.h的绝对路径RUSTLS_LIBRARYrustls库文件的绝对路径RUSTLS_FOUND/RUSTLS_VERSION是否找到及版本CURL::rustls供其他 CMake 目标链接的 IMPORTED 接口目标模块同样优先走 pkg-configpkg_check_modules(_rustls rustls)失败则退回find_path/find_library的常规查找。平台相关依赖方面Apple 要求 Security 与 Foundation 两个系统框架缺失即 FATAL非 Windows 平台按需补pthread、dl、m。开关选项记录在 docs/INSTALL-CMAKE.md-DCURL_USE_RUSTLSON启用 Rustls 后端默认 OFF标注 experimental-DRUSTLS_INCLUDE_DIR...、-DRUSTLS_LIBRARY...指定查找位置。源码视角rustls.c 里 curl 如何驱动 Rustls后端能力清单curl 的每个 TLS 后端都实现为一个struct Curl_ssl。Rustls 后端定义在 lib/vtls/rustls.c其支持的 SSL 特性由一组SSLSUPP_*标志声明SSLSUPP_CAINFO_BLOB支持内存 CA 数据CURLOPT_CAINFO_BLOBSSLSUPP_HTTPS_PROXY支持 HTTPS 代理隧道SSLSUPP_CIPHER_LIST与SSLSUPP_TLS13_CIPHERSUITES可配置密码套件SSLSUPP_CERTINFO可取回服务器证书信息SSLSUPP_ECH条件编译下支持 ECHEncrypted Client HelloSSLSUPP_CRLFILE支持证书吊销列表文件。后端私有数据struct rustls_ssl_backend_datalib/vtls/rustls.c保存两件关键东西由 builder 构建出的struct rustls_client_config *config以及代表单条连接状态的struct rustls_connection *conn。连接初始化与信任链验证cr_init_backendcr_init_backendlib/vtls/rustls.c是理解该后端的核心入口它把 libcurl 的ssl_primary_config/ssl_config_data翻译成 rustls 的 builder 配置ALPN若协商列表非空通过init_config_builder_alpn写入 builderlib/vtls/rustls.c关闭验证CURLOPT_SSL_VERIFYPEER为 0 时调用rustls_client_config_builder_dangerous_set_certificate_verifier挂上cr_verify_none危险模式不校验证书系统原生信任库启用 native CA store 时走init_config_builder_platform_verifier借助平台验证器如 macOS/iOS 的 Security 框架链完成证书验证。源码注释明确指出一个限制此模式下 rustls-ffi 没有 CRL 挂载 API因此CURLOPT_CRLFILE与原生信任库不能同时使用否则返回CURLE_NOT_BUILT_INlib/vtls/rustls.c显式 CA 文件/内存 Blob有CURLOPT_CAINFO或CURLOPT_CAINFO_BLOB时init_config_builder_verifier负责把 PEM 内容解析进根证书存储CURLOPT_CAINFO_BLOB优先级更高客户端证书配置了 client cert 与私钥时调用init_config_builder_client_authECH编译期开启USE_ECH且运行时启用时注入 ECH 配置若 ECH 被设为 HARD 且失败直接终止连接lib/vtls/rustls.c密钥日志init_config_builder_keylog挂接 keylog 回调配合CURLOPT_SSLKEYLOGFILE输出 TLS 会话密钥供 Wireshark 解密抓包lib/vtls/rustls.c。配置就绪后rustls_client_config_builder_build冻结配置再以服务器主机名为参数调用rustls_client_connection_new创建连接对象lib/vtls/rustls.c。握手完成后cr_set_negotiated_alpn通过rustls_connection_get_alpn_protocol取回实际协商的协议例如 HTTP/2 的h2再写回 curl 的连接上下文lib/vtls/rustls.c。数据收发、错误映射与清理cr_connectlib/vtls/rustls.c驱动握手过程rustls 通过注册的read_cb/write_cblib/vtls/rustls.c从底层 socket filter 读取/写出原始字节EAGAIN/EWOULDBLOCK被正确透传以支持非阻塞事件循环cr_recv/cr_send处理加密数据的明文侧读写TLS 关闭通知则由cr_shutdown完成优雅关闭错误翻译集中在map_errorlib/vtls/rustls.c凡rustls_result_is_cert_error一律映射为CURLE_PEER_FAILED_VERIFICATION对应命令行常见的 SSL certificate problemNULL_PARAMETER映射为CURLE_BAD_FUNCTION_ARGUMENT其余映射为CURLE_RECV_ERROR可读的 rustls 错误文本经rustls_error取出后交给 curl 的failf输出curl 自身的随机数需求如生成一些协议临时值也借用了 rustls 的加密 providercr_random调用rustls_default_crypto_provider_randomlib/vtls/rustls.c版本字符串方面cr_version直接返回rustls_version()的结果lib/vtls/rustls.c即curl --version中括号里显示的 rustls 库版本cr_close负责释放rustls_connection与rustls_client_config后端清理cr_cleanup则关闭 keylog 文件句柄。整个模块的开关是编译期宏USE_RUSTLSlib/vtls/rustls.h中只有定义了该宏才声明Curl_ssl_rustlslib/vtls/rustls.hconfigure 探测成功后会通过AC_DEFINE(USE_RUSTLS, 1)写入配置头。构建验证与多后端共存完成make后可通过以下命令确认 Rustls 真正生效./src/curl --version在输出中查找(rustls ...)形式的库版本标注它正是上文cr_version提供的字符串查看 configure 过程中的detected Rustls提示以及最终 backend 列表中包含的Rustls。curl 允许一次构建链接多个 TLS 后端docs/INSTALL.md例如在 Rustls 之外同时保留 OpenSSL只要各后端符号不冲突即可共存运行时再决定本次使用哪一个。对希望尝试纯 Rust TLS 栈、或希望避开 OpenSSL 系依赖的部署场景而言rustls是--with-openssl、--with-gnutls、--with-schannel之外的另一个务实选择——尤其值得按本文方式三锁定 rustls-ffi v0.15.x 版本做可复现构建。小结curl 通过 rustls-ffiC ABI 绑定接入 Rust 实现的 Rustls TLS 库当前代码兼容v0.15.x三种获取 rustls-ffi 的路径包管理器、预编译归档、cargo capi源码构建分别对应三种./configure --with-rustls[PATH]用法配置系统在 m4/curl-rustls.m4 中实现 pkg-config 优先、路径兜底、符号级验证三级探测CMake 用户可参考 CMake/FindRustls.cmakelib/vtls/rustls.c 完整实现了 curl TLS 后端接口覆盖证书验证含 native CA store、ALPN、客户端证书、ECH、密钥日志、非阻塞收发与错误映射并公开了声明的能力标志便于应用层在运行时判断可用的 SSL 特性。【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价