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 的差异:

HTTP 协议栈对比:传统 vs QUIC HTTP/1.1 HTTP 应用层 TLS 加密层 TCP 传输层 IP 网络层 握手:TCP(1.5RTT)+TLS(1-2RTT) 队头阻塞:严重 连接迁移:不支持 HTTP/3 (QUIC) HTTP/3 应用层 QUIC 传输层 (内置 TLS 1.3) (多路复用) (连接迁移) UDP 传输层 IP 网络层 握手:1-RTT(首次)/0-RTT(重连) 队头阻塞:无 关键差异 QUIC 将传输层上移 到用户空间 迭代更快,部署灵活

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,按以下步骤操作:

  1. 点击菜单 编辑 → 首选项 → Protocols → TLS
  2. 在 "(Pre)-Master-Secret log filename" 里填入刚才的密钥文件路径
  3. 点击 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 验证抓包环境

配置完了,怎么知道好不好使?我一般用这个步骤验证:

  1. 启动 Chrome,打开 https://www.google.com(谷歌强制使用 QUIC)
  2. 在 Wireshark 里输入过滤 quic
  3. 如果能看到绿色的 QUIC 包,并且有 HTTP/3 解析内容,说明环境配置成功
  4. 如果全是灰色加密包,检查密钥文件路径是否正确

这里有个小技巧——在 Wireshark 里右键点击 QUIC 包,选择 "Follow → QUIC Stream",可以直接看到 HTTP/3 的请求和响应内容,跟看 HTTP/2 的流一样直观。

环境配置检查清单:

  • ☐ Chrome 已设置 SSLKEYLOGFILE 环境变量
  • ☐ Wireshark 已配置密钥文件路径
  • ☐ 能抓到 QUIC 包并成功解密
  • ☐ 能过滤出 HTTP/3 内容