1. QUIC 协议基础与抓包环境搭建
各位好,我是老赵。做网络排错十几年了,从 TCP 到 QUIC,每次协议换代都是一次学习阵痛。今天咱们先打好地基,聊聊 QUIC 到底是什么、跟 HTTP/3 啥关系,再把抓包环境搭起来。
说实话,我第一次接触 QUIC 是在 2018 年,当时客户反馈 Chrome 访问自家服务偶尔断连,抓包一看全是 UDP 包,Wireshark 还解析不出来。嗯,从那以后我就开始认真研究这个协议了。
1.1 QUIC 协议概述
QUIC 的全称是 Quick UDP Internet Connections,谷歌在 2012 年就开始捣鼓了。说白了,它就是想解决 TCP 那些老毛病——连接慢、队头阻塞、迁移困难。
我个人的理解是:QUIC 把传输层和应用层揉在了一起,在 UDP 之上重新实现了可靠传输。你想想看,TCP 握手要 1.5 个 RTT,TLS 又要 1-2 个 RTT,加起来 2-3 个 RTT 才能发数据。QUIC 呢?首次连接 1-RTT,后续 0-RTT,快得不是一星半点。
核心特性一览:
- 基于 UDP,避免 TCP 队头阻塞
- 内置 TLS 1.3,加密是标配
- 多路复用,一个连接跑多个流
- 连接迁移,IP 变了连接不断
- 0-RTT 快速重连
这里我画了一张 QUIC 协议栈的对比图,帮你直观理解它跟传统 HTTP/1.1、HTTP/2 的差异:
1.2 HTTP/3 与 QUIC 的关系
很多人搞混这两个概念。我简单说:QUIC 是传输层协议,HTTP/3 是应用层协议。HTTP/3 跑在 QUIC 上面,就像 HTTP/2 跑在 TCP 上面一样。
但有个细节要注意——HTTP/3 并不是唯一能跑在 QUIC 上的协议。你可以用 QUIC 传 DNS、传 SSH、甚至传自定义数据。只不过目前最主流的应用就是 HTTP/3。
| 特性 | HTTP/2 + TCP | HTTP/3 + QUIC |
|---|---|---|
| 传输层 | TCP | QUIC (基于 UDP) |
| 加密 | 独立 TLS 层 | 内置 TLS 1.3 |
| 多路复用 | 有,但存在队头阻塞 | 无队头阻塞 |
| 连接迁移 | 不支持 | 原生支持 |
| 握手延迟 | 2-3 RTT | 0-1 RTT |
我的经验: 在弱网环境下(比如 4G 信号差的地方),QUIC 的优势特别明显。我曾经在高铁上做过测试,HTTP/3 的页面加载时间比 HTTP/2 快了将近 40%。
1.3 Wireshark 与 Chrome 抓包环境配置
好,理论说完了,咱们动手。要抓 QUIC 包,光装 Wireshark 是不够的,因为 QUIC 默认是加密的。你需要让 Chrome 把加密密钥吐出来,Wireshark 才能解密。
1.3.1 配置 Chrome 导出 QUIC 密钥
Chrome 支持通过环境变量导出 SSLKEYLOGFILE,这个文件记录了会话密钥。Wireshark 拿到它就能解密 QUIC 流量。
Windows 系统:
# 设置环境变量(建议加到系统变量里)
set SSLKEYLOGFILE=C:\tmp\sslkey.log
# 启动 Chrome
"C:\Program Files\Google\Chrome\Application\chrome.exe"
macOS / Linux 系统:
# 终端里执行
export SSLKEYLOGFILE=/tmp/sslkey.log
/Applications/Google\ Chrome.app/Contents/MacOS/Google Chrome
注意: 这个密钥文件会记录你所有 HTTPS 和 QUIC 连接的密钥,用完记得删除。我曾经见过有人把这个文件传到 GitHub 上,结果整个浏览记录都暴露了。
1.3.2 配置 Wireshark 加载密钥
打开 Wireshark,按以下步骤操作:
- 点击菜单 编辑 → 首选项 → Protocols → TLS
- 在 "(Pre)-Master-Secret log filename" 里填入刚才的密钥文件路径
- 点击 OK 保存
嗯,这里有个坑——Wireshark 旧版本把 QUIC 密钥配置放在 TLS 协议里,新版本(4.0+)单独放在了 QUIC 协议下。如果你找不到,两个地方都看看。
1.4 QUIC 流量过滤技巧
抓包最怕的就是流量太多,眼睛看花。我教你几个过滤表达式,直接定位 QUIC 流量。
1.4.1 基础过滤
| 过滤表达式 | 作用 |
|---|---|
quic |
显示所有 QUIC 包 |
udp.port == 443 |
显示 UDP 443 端口的包(QUIC 默认端口) |
quic && tls |
显示已解密的 QUIC 流量 |
quic.version == 1 |
只显示 QUIC v1 的包 |
1.4.2 高级过滤
我个人习惯用这些组合过滤,排查效率高很多:
# 只看某个 IP 的 QUIC 流量
quic && ip.addr == 192.168.1.100
# 只看 QUIC 握手包(Initial 包)
quic.frame_type == 0
# 只看 QUIC 的 HTTP/3 数据
quic && http3
# 排除健康检查的 QUIC 包
quic && !icmp
避坑指南: 我曾经在排查一个 QUIC 连接超时问题时,发现 Wireshark 里全是 UDP 包但 QUIC 解析不出来。后来发现是 Chrome 的 QUIC 版本太新,Wireshark 不支持。解决办法是升级 Wireshark 到最新版,或者用 chrome://flags/#enable-quic 临时关闭 QUIC 做对比测试。
1.5 验证抓包环境
配置完了,怎么知道好不好使?我一般用这个步骤验证:
- 启动 Chrome,打开
https://www.google.com(谷歌强制使用 QUIC) - 在 Wireshark 里输入过滤
quic - 如果能看到绿色的 QUIC 包,并且有 HTTP/3 解析内容,说明环境配置成功
- 如果全是灰色加密包,检查密钥文件路径是否正确
这里有个小技巧——在 Wireshark 里右键点击 QUIC 包,选择 "Follow → QUIC Stream",可以直接看到 HTTP/3 的请求和响应内容,跟看 HTTP/2 的流一样直观。
环境配置检查清单:
- ☐ Chrome 已设置 SSLKEYLOGFILE 环境变量
- ☐ Wireshark 已配置密钥文件路径
- ☐ 能抓到 QUIC 包并成功解密
- ☐ 能过滤出 HTTP/3 内容