curl -v 输出的每一行都对应协议栈里的一个阶段。学会读它,HTTP/HTTPS 问题就排掉了一半。本文以一次真实请求为样本,讲清 HTTP 报文结构、TLS 握手在干什么、证书报错怎么定位。
一次请求的完整解剖
curl -v https://example.com/> 开头是客户端发出的,> 之外带 < 的是收到的,* 是 curl 自己的注释。发出部分:
GET / HTTP/2Host: example.comUser-Agent: curl/8.xAccept: */*这就是 HTTP 请求报文的全部骨架:请求行(方法 + 路径 + 版本)+ 首部(键值对)+ 可选的请求体。响应同理:状态行(HTTP/2 200)+ 首部 + 正文。
要单独看首部用 curl -I(发 HEAD 请求);要忽略正文只看交换过程用 curl -sv https://... -o /dev/null。
TLS 握手在 HTTP 之前
curl -v 里 * 部分有一段 TLS 日志:
* TLSv1.3 (OUT), TLS handshake, Client hello (1):* TLSv1.3 (IN), TLS handshake, Server hello (2):* TLSv1.3 (IN), TLS handshake, Certificate (11):* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384握手的两个目标:协商加密参数和验证服务器身份。
- TLS 1.2:密钥协商走 RSA 或 ECDHE,需要两个完整往返(2-RTT)。
- TLS 1.3(2018 年定稿,现为主流):客户端在 Client Hello 里直接带上密钥材料,1-RTT 完成握手,且支持 0-RTT 会话恢复;同时把证书之后的握手消息也加了密。
对使用者来说结论很简单:TLS 1.3 更快更安全,服务端应优先启用并保留 1.2 兜底,1.0/1.1 必须禁用。
证书链:浏览器凭什么信任这个网站
服务器在握手中出示的不是一张证书,而是一条链:
服务器证书(example.com) ↑ 由 中间 CA(如 R3)签发 ↑ 由 根 CA(如 ISRG Root X1)签发 ← 预置在操作系统/浏览器信任库验证逻辑:逐级用上级公钥校验签名,直到碰到信任库里已有的根。中间证书必须由服务器一起下发——最常见的「浏览器正常、curl/旧安卓报证书错误」,就是服务器漏配中间证书(fullchain),浏览器能自动补齐而别的客户端不能。
用 OpenSSL 查看证书细节:
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates-dates 看有效期(过期是第二大常见故障),-servername 用于一台服务器托管多个 HTTPS 站点(SNI)时指定域名。
常见证书报错对号入座
| curl 报错 | 含义 | 处理 |
|---|---|---|
certificate has expired | 证书过期 | 续期,检查自动续期任务是否失效 |
unable to get local issuer certificate | 服务器没发中间证书,或本地 CA 库太旧 | 服务端配置 fullchain;客户端更新 ca-certificates |
subject name mismatch | 证书域名与访问域名不符 | 证书上 SAN 没包含该域名(注意 www. 前缀差异) |
self signed certificate | 自签名证书 | 内网可 -k 跳过或分发 CA;公网换正规证书 |
把请求拆开计时
接口慢,到底是 DNS 慢、握手慢还是服务器处理慢?
curl -so /dev/null -w 'DNS:%{time_namelookup}s TCP:%{time_connect}s TLS:%{time_appconnect}s 首字节:%{time_starttransfer}s 总:%{time_total}s\n' https://example.com/time_connect - time_namelookup≈ TCP 握手耗时(约等于 RTT);time_appconnect - time_connect≈ TLS 握手耗时;time_starttransfer - time_appconnect≈ 服务器处理并返回首字节的耗时。
一眼就能看出慢在哪一段,比凭感觉猜高效得多。
HTTP/2 与 HTTP/3 简述
HTTP/2 在单条 TCP 连接上多路复用(解决 HTTP/1.1 队头阻塞),首部走 HPACK 压缩;HTTP/3 把底层换成基于 UDP 的 QUIC,进一步消除 TCP 层队头阻塞并改善弱网切换。对开发者透明——curl 和浏览器会自动协商(curl -v 里能看到 ALPN: server accepted h2),服务端用 Nginx/云 CDN 开启即可。
延伸阅读
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
最后更新于 ,距今已过 31 天
部分内容可能已过时