重新编译 curl 以支持 HTTP3

技术 秋水逸冰 12186浏览 0评论

从 2022 年 6 月 HTTP/3 的 RFC 发布,截至目前,常用的 Web Server,比如 Caddy Web ServerNginx 已经支持 HTTP/3。与此同时,常用的浏览器比如 Google Chrome,Microsoft Edge,Mozilla Firefox,Apple Safari 等也都开始支持 HTTP/3。这里吐槽一下,Apache httpd 支持 HTTP/3 还遥遥无期。
常用的 Client 软件比如 curl 其实也早已开始支持 HTTP/3,但是目前各大 Linux 发行版编译的 curl 都不包含 HTTP3 特性,故此我打算自己来。
本文主要详细讲述如何在下列 RHEL 系统中安装已经重新编译好的 curl,以及在编译 curl 中遇到的问题。
Enterprise Linux 8 (CentOS Stream 8, RHEL 8, Rocky Linux 8, AlmaLinux 8, Oracle Linux 8)
Enterprise Linux 9 (CentOS Stream 9, RHEL 9, Rocky Linux 9, AlmaLinux 9, Oracle Linux 9)
Enterprise Linux 10 (CentOS Stream 10, RHEL 10, Rocky Linux 10, AlmaLinux 10, Oracle Linux 10)

如何安装已经编译好的 curl


(以下均为使用 root 用户操作)
1. 开启 EPEL Repository
适用于 Enterprise Linux 8 (CentOS Stream 8, RHEL 8, Rocky Linux 8, AlmaLinux 8, Oracle Linux 8) 的安装命令

dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

适用于 Enterprise Linux 9 (CentOS Stream 9, RHEL 9, Rocky Linux 9, AlmaLinux 9, Oracle Linux 9) 的安装命令

dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm

适用于 Enterprise Linux 10 (CentOS Stream 10, RHEL 10, Rocky Linux 10, AlmaLinux 10, Oracle Linux 10) 的安装命令

dnf install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-10.noarch.rpm

2. 执行以下命令安装 Teddysun Linux Repository:
适用于 Enterprise Linux 8 (CentOS Stream 8, RHEL 8, Rocky Linux 8, AlmaLinux 8, Oracle Linux 8) 的安装命令

dnf install -y https://dl.lamp.sh/linux/rhel/el8/x86_64/teddysun-release-1.0-1.el8.noarch.rpm

适用于 Enterprise Linux 9 (CentOS Stream 9, RHEL 9, Rocky Linux 9, AlmaLinux 9, Oracle Linux 9) 的安装命令

dnf install -y https://dl.lamp.sh/linux/rhel/el9/x86_64/teddysun-release-1.0-1.el9.noarch.rpm

适用于 Enterprise Linux 10 (CentOS Stream 10, RHEL 10, Rocky Linux 10, AlmaLinux 10, Oracle Linux 10) 的安装命令

dnf install -y https://dl.lamp.sh/linux/rhel/el10/x86_64/teddysun-release-1.0-1.el10.noarch.rpm

3. 重建 Repository 缓存,执行如下命令:

dnf makecache

4. 通过 dnf 来安装重新编译的 curl,执行如下命令:

dnf install -y curl libcurl libcurl-devel

5. 通过 dnf 来升级 libnghttp2 和 c-ares 版本,执行如下命令:

dnf install -y libnghttp2 libnghttp2-devel c-ares c-ares-devel

dnf 会自动安装一些依赖包。安装成功后,查看 curl 的版本号,执行命令:curl -V
在 Enterprise Linux 8 (CentOS Stream 8, RHEL 8, Rocky Linux 8, AlmaLinux 8, Oracle Linux 8) 系统下,显示的是:

curl 8.18.0 (x86_64-redhat-linux-gnu) libcurl/8.18.0 OpenSSL/3.5.4 zlib/1.3.1 brotli/1.2.0 zstd/1.5.7 c-ares/1.34.6 libidn2/2.3.8 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.68.0 nghttp3/1.14.0 librtmp/2.6 libgsasl/1.10.0 mit-krb5/1.18.2 OpenLDAP/2.4.46
Release-Date: 2026-01-07
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc asyn-rr AsynchDNS brotli gsasl GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy HTTPSRR IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL SSLS-EXPORT threadsafe TLS-SRP TrackMemory UnixSockets zstd

在 Enterprise Linux 9 (CentOS Stream 9, RHEL 9, Rocky Linux 9, AlmaLinux 9, Oracle Linux 9) 系统下,显示的是:

curl 8.18.0 (x86_64-redhat-linux-gnu) libcurl/8.18.0 GnuTLS/3.8.3 zlib/1.3.1 brotli/1.2.0 zstd/1.5.7 c-ares/1.34.6 libidn2/2.3.8 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.68.0 ngtcp2/1.19.0 nghttp3/1.14.0 librtmp/2.6 libgsasl/1.10.0 mit-krb5/1.21.1 OpenLDAP/2.6.8
Release-Date: 2026-01-07
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc asyn-rr AsynchDNS brotli gsasl GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy HTTPSRR IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL SSLS-EXPORT threadsafe TLS-SRP TrackMemory UnixSockets zstd

在 Enterprise Linux 10 (CentOS Stream 10, RHEL 10, Rocky Linux 10, AlmaLinux 10, Oracle Linux 10) 系统下,显示的是:

curl 8.18.0 (x86_64-redhat-linux-gnu) libcurl/8.18.0 GnuTLS/3.8.10 zlib/1.3.1.zlib-ng brotli/1.2.0 zstd/1.5.7 c-ares/1.34.6 libidn2/2.3.8 libpsl/0.21.5 libssh2/1.11.1 nghttp2/1.68.0 ngtcp2/1.19.0 nghttp3/1.14.0 librtmp/2.6 libgsasl/1.10.0 mit-krb5/1.21.3 OpenLDAP/2.6.9
Release-Date: 2026-01-07
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc asyn-rr AsynchDNS brotli gsasl GSS-API HSTS HTTP2 HTTP3 HTTPS-proxy HTTPSRR IDN IPv6 Kerberos Largefile libz NTLM PSL SPNEGO SSL SSLS-EXPORT threadsafe TLS-SRP TrackMemory UnixSockets zstd

5. 特性说明
在 Enterprise Linux 8 使用 OpenSSL/3.5.4 + nghttp3/1.14.0 作为后端支持 HTTP/3。
在 Enterprise Linux 9 使用 GnuTLS/3.8.3 + ngtcp2/1.19.0 + nghttp3/1.14.0 作为后端支持 HTTP/3。
在 Enterprise Linux 10 使用 GnuTLS/3.8.10 + ngtcp2/1.19.0 + nghttp3/1.14.0 作为后端支持 HTTP/3。
支持 rtmp, ws, wss 等 Protocol。
支持 brotli, gsasl, zstd 等 Feature。
编译了 curl 的各个依赖软件到最新版本。
6. 测试是否支持 HTTP/3
使用以下命令来查看是否支持 HTTP/3。

curl -I --http3 https://nghttp2.org/

返回值示例如下所示:

HTTP/3 200 
date: Tue, 23 Dec 2025 10:59:00 GMT
content-type: text/html
last-modified: Sat, 25 Oct 2025 08:47:14 GMT
etag: "68fc8e92-18b4"
accept-ranges: bytes
content-length: 6324
x-backend-header-rtt: 0.001967
strict-transport-security: max-age=31536000
server: nghttpx
via: 2 nghttpx
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff

第一行的 HTTP/3 200 就表示已经支持 HTTP/3。

在编译 curl 中遇到的问题

1. ngtcp2 和 nghttp3 的 rpm 不存在
开启 HTTP/3 特性需要 ngtcp2 和 nghttp3 来支持,但是目前并没有相关的 rpm,于是我参考了 nghttp2 的 spec 文件,自行制作了这两个依赖的 rpm 包。
ngtcp2 同时还需要 Crypto helper library 才能实现 QUIC 协议,目前受支持的 TLS 后端也就是如下列表:

quictls
GnuTLS >= 3.7.5
BoringSSL (commit e575a84d5f051483793b14c07b60720d0ed318b3); or aws-lc >= 1.39.0
Picotls (commit 34d4d6496cec80bc3b56dbdab45f21bd9fbc17aa)
wolfSSL >= 5.5.0
LibreSSL >= v3.9.2
OpenSSL >= 3.5.0

Enterprise Linux 9 中默认安装的 GnuTLS 版本是 3.8.3,满足条件,因此是首选。编译出 libngtcp2_crypto_gnutls 的 Crypto helper library,加上 nghttp3 来开启 HTTP/3 特性。
Enterprise Linux 8 中默认安装的 GnuTLS 版本是 3.6.16,不满足条件。又没有别的更好的 TLS 后端,于是编译了 openssl3 到最新的 3.5.4(该版本已经实现了 QUIC),加上 nghttp3 来开启 HTTP/3 特性。
2. 默认安装的依赖软件版本比较旧
比如 brotli,zstd,libidn2,libpsl,libssh2,libgsasl,发行版自带的默认版本比较旧,补丁摞补丁,就是不升级版本(当然了,这是为了稳定性,毕竟是企业级系统,可以理解)。
对于自用,这些依赖升级了也不会出现大问题,至少目前还没发现。
3. 某些依赖软件不存在
比如 librtmp,这款软件名为 rtmpdump,属于 ffmpeg 项目下的一个 toolkit,用于支持 RTMP 流。在 RHEL 下默认就没有该 rpm 包,RpmFusion 里只有古老的版本。稀奇的是今年在其 git 里竟然更新了。
其最新 git commit log 是 v2.6 版本,结果编译出来的 library 和头文件还是 v2.3,于是只能自己写个补丁,把版本号改正过来,再制作编译 rpm 到最新版 2.6-1.20240301.git6f6bb13。
前前后后遇到不少问题,花了不少时间,总算是搞出来了。目前为止,自己用着挺满意,今天分享出来,希望大家也满意。

写在最后

请关注我的 Telegram 频道:https://t.me/qiushuiyibing
我会在此不定期发布一些杂七杂八的作品。
同时也欢迎加入交流群:https://t.me/qiushui2018

转载请注明:秋水逸冰 » 重新编译 curl 以支持 HTTP3

发表我的评论
取消评论

请输入正确答案后提交评论 *超出时限。 请再次填写验证码。

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址