某个用户从运营商移动网(移动 / 联通 / Verizon Wireless / T-Mobile / Vodafone……)或现代家庭宽带反馈站点打不开——TCP 层就超时。你在公司有线上一开秒开。差别就在 IPv6:移动运营商和很多 APAC 运营商提供 IPv6 优先 / 仅 IPv6 接入,浏览器的 Happy Eyeballs 先试 AAAA。你的 AAAA 指向死主机、或在 CDN 前置场景下根本不该存在、或源站防火墙丢 IPv6 包——用户就要等 TCP 完整超时(一般 75-120 秒),可能才回落到 IPv4,那时候 tab 早关了。这个故障对大多数监控不可见,因为 IPv4 健康检查全过。
常见原因
按用户可观察到的疼痛排序。
1. AAAA 存在但指向不再托管你的 IP
你以前主机同时有 A 和 AAAA。换到新主机(Vercel / Netlify / 别的 VPS),A 更新了 AAAA 忘了。旧 IPv6 地址要么是死的、要么现在是别人的。
怎么判断:dig AAAA yourdomain.com +short 返回一个地址,但 curl -6 -I https://yourdomain.com 超时或返回错误内容。
2. CDN 前置只送 IPv4,AAAA 直接绕过 CDN
你的 CDN(老的 Cloudflare 配置、某些 Bunny 设置、自定义边缘)IP 列表只暴露 IPv4,但你手动加了一条 AAAA 指向源站”帮 IPv6 用户”。那些用户直接绕过 CDN,命中没配好 / 不可达的源站。
怎么判断:A 记录是 CDN IP,AAAA 是源站 IP。curl -6 直击源站,没有 CDN 保护。
3. 源站防火墙丢 IPv6 包
ip6tables(或云防火墙 / 安全组)没配。默认拒绝阻挡 :443 入站 v6。源站技术上能双栈,但 v6 没人能进。
怎么判断:sudo ip6tables -L INPUT -v -n 看不到 :443 v6 的 ACCEPT 规则。外部:nc -6 -zv yourdomain.com 443 卡住。
4. 反向代理 / nginx 不监听 v6
OS 防火墙开了,nginx 默认 listen 443 ssl; 只是 IPv4。需要显式 listen [::]:443 ssl;。
怎么判断:ss -tlnp | grep :443 显示 0.0.0.0:443 没有 [::]:443。或者都显示但只绑了 IPv4。
5. Happy Eyeballs 会 fallback,但 AAAA TTL 太长缓存住了
哪怕你把坏 AAAA 删了,浏览器还会按 TTL 缓存(常见 4-24 小时)。用户每次还是先打 v6、超时、回落 v4——好几个小时都”慢”。
怎么判断:用户说”网最后能开,但每次要 30 秒”。浏览器 DevTools 时间线里 DNS / 连接阶段超长。
6. 运营商 NAT64 / CLAT 引入 SNI 问题
移动运营商用 NAT64(终端没原生 v4),从你的 A 合成 AAAA。SNI / Host header 逻辑要是依赖源地址族就崩。
怎么判断:A 正常、你没 AAAA,但运营商用户还是抱怨。SNI 拿到的是 well-known-ipv6-pref 合成地址。按运营商具体看。
开始前
- 看清楚哪些用户 / 地区受影响——移动 vs 家庭宽带 vs 公司网行为差很多。
- 确认托管平台的 IPv6 态度:暴露 AAAA 吗?Cloudflare 默认是,纯 VPS 看配置。
- 找一个能用 IPv6 的客户端测。
test-ipv6.com能确认客户端 v6 是好的。 - 知道源站的 IPv6 地址(云厂商控制台能看)。
需要收集的信息
dig A yourdomain.com +short和dig AAAA yourdomain.com +short输出。curl -4 -I https://yourdomain.com和curl -6 -I https://yourdomain.com输出。- 源站
ss -tlnp | grep :443输出。 - 源站
ip -6 addr show输出(看分配的 v6 地址)。 - 从一个 IPv6-only / IPv6-preferred 网络的测试——手机流量是最容易的来源。
一步步修
顺序:尽快把坏 AAAA 干掉,再做好双栈。
第 1 步:从外部测两栈
curl -4 -v https://yourdomain.com 2>&1 | head -20
curl -6 -v https://yourdomain.com 2>&1 | head -20
-4 成功、-6 卡或挂,诊断确认。注意 -6 在哪一层挂:TCP connect、TLS 握手、HTTP 响应——每层意味着不同子问题。
第 2 步:删掉死 AAAA
dig AAAA yourdomain.com 返回的地址确实不应答:
- DNS 面板 → 找到 AAAA 记录。
- 删了(或改成对的地址)。
- 把附近记录的 TTL 临时降到 300 秒,方便后续改动快速传播。
浏览器和解析器会在旧 TTL 内开始忽略你的域名的 v6,Happy Eyeballs 干净回落 v4。
第 3 步:双栈源站确认服务器监听 v6
编辑 /etc/nginx/sites-available/yourdomain:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name yourdomain.com;
# ...
}
[::]:443 这一行绑 IPv6。重启:
sudo nginx -t && sudo systemctl reload nginx
ss -tlnp | grep :443
输出现在应该同时有 0.0.0.0:443 和 :::443。
第 4 步:开 IPv6 防火墙
sudo ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo ip6tables-save | sudo tee /etc/ip6tables.rules
ufw:
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp
ufw 默认同时对 v4 v6 生效。验证:
sudo ip6tables -L INPUT -v -n | grep 443
云厂商控制台(AWS 安全组 / GCP 防火墙 / DigitalOcean Cloud Firewall)里,明确把 IPv6 来源 ::/0 加给 80/443——很多 UI 默认只是 0.0.0.0/0。
第 5 步:加上正确的 AAAA 记录
确认源站支持 v6 后,取地址:
ip -6 addr show | grep "scope global"
挑非临时、非链路本地的(一般是没有 temporary 标志的那个)。在 DNS 里加 AAAA,TTL 先 300:
yourdomain.com. 300 IN AAAA 2001:db8::1
测:
dig AAAA yourdomain.com @1.1.1.1 +short
curl -6 -I https://yourdomain.com
第 6 步:用 CDN 的话,优先用 CDN 提供的 IPv6,不要自己加
Cloudflare 代理记录会自动发 A 和 AAAA 都指向 Cloudflare 边缘——已代理的记录绝对不要手动加绕过 Cloudflare 的 AAAA。Vercel / Netlify 看文档,有些自动发 AAAA、有些不发,自己加会造成劈裂。
验证
dig AAAA yourdomain.com +short返回正确地址(或什么都没有,故意只 v4 的话)。curl -6 -I https://yourdomain.com返回HTTP/2 200或预期响应,不超时。test-ipv6.com(从某个网络)显示站点 v6 可达。- 从手机流量(移动数据热点给笔记本)开网页无延迟。
- 源站
ss -tlnp显示 443 同时有 v4 和 v6 监听。
长期预防
- 监控加 IPv6 健康检查(UptimeRobot / Pingdom / Better Stack 都支持 v6 探测——要显式打开)。
- 迁移主机时 A 和 AAAA 同步更新,不要留旧 AAAA 指向旧 VPS。
- 标准化 nginx / haproxy / caddy 模板,开局就带
[::]:443。 - 每月用移动网测一次——大多数 IPv6 故障只在那看得见。
- runbook 里写:每个对外服务,要么有可用的 AAAA、要么没 AAAA,绝不留一个坏的。
常见坑
- 死 AAAA 留着不管,因为”v4 还能用”——你正在静默劣化 v6 优先用户的体验。
- AAAA 加了忘开 v6 防火墙——记录指向丢包的主机。
- 哪里都用
0.0.0.0/0以为 v6 也覆盖——大部分防火墙 v4 和 v6 是两套规则。 - AAAA TTL 设 86400 然后想修错误——用户一整天都拿着坏记录。
- 云厂商自动分配临时 v6(隐私地址)加到 DNS——重启就变。
FAQ
Q:2026 年了我是不是必须支持 IPv6,即使用户主要是桌面?
是。移动流量经常 IPv6 占多数,即使桌面不是。坏 AAAA 主动伤害用户;没 AAAA 反而能接受(Happy Eyeballs 在现代浏览器里 ~300ms 内干净 fallback)。
Q:我直接全删 AAAA、忘掉 IPv6 行不行?
行,是个有效立场。完全没 AAAA 时所有客户端立刻 fallback v4。坏的失败模式是 AAAA 错的,不是没 AAAA。
Q:我源站在 AWS——默认有 IPv6 吗?
只有你在 VPC 显式开了双栈、并给实例分配了 v6 地址才有。legacy VPC 里的老 AWS 账号默认只 v4。查 VPC 和子网设置。
Q:Cloudflare 橙云自动给我 IPv6 吗?
是——代理记录无论源站什么栈,都同时发 Cloudflare 的 IPv4 和 IPv6 anycast 地址。这是不动源站就”支持 IPv6”最省事的方式。
参见 A 记录跟 CNAME 分不清、DNS 改了站点还是打不开、子域名不解析。
标签: #排查 #DNS #ipv6 #排查 #Networking