给一条 IPv6 链路补充可用性探测时,最容易犯的错误是:请求成功了,日志里也出现了 IPv6 地址,于是认为探测已经覆盖 IPv6。
但日志字段可能来自代理转发的请求头,客户端也可能在双栈环境中自动选择 IPv4。要证明链路真实经过 IPv6,需要同时控制解析结果、保留 HTTPS 主机名校验,并在网络层验证数据包。
先把验证目标说清楚
一次完整的链路探测至少应验证:
- DNS 能够得到目标 IPv6 地址;
- 客户端实际向 IPv6 地址建立连接;
- TLS 仍按原始域名完成证书校验;
- 应用请求和响应符合预期;
- 监控机器本身具备正确的 IPv6 路由。
如果直接请求字面量 IPv6 地址并关闭证书校验,只验证了“某个地址和端口可达”,没有覆盖域名与证书这一段真实链路。
在客户端显式选择 IPv6
双栈域名可能同时返回 A 和 AAAA 记录,客户端最后选择哪一个地址受运行库、系统配置和连接策略影响。探测程序不应依赖这种隐式选择。
Java 客户端可以为探测请求提供受控的 DNS 解析器,只返回选定的 IPv6 地址:
final class Ipv6OnlyResolver implements DnsResolver {
@Override
public InetAddress[] resolve(String host) throws UnknownHostException {
return Arrays.stream(InetAddress.getAllByName(host))
.filter(Inet6Address.class::isInstance)
.toArray(InetAddress[]::new);
}
}
生产实现还要处理没有 AAAA 记录、存在多个 IPv6 地址和连接失败时的错误分类,不能返回空地址后继续执行。
命令行验证时,可以使用 curl --resolve 把域名和端口固定到测试地址:
curl --resolve 'media.example.com:443:[2001:db8::10]' \
'https://media.example.com/health'
请求 URL 仍然使用域名,因此 TLS 可以校验证书;--resolve 只覆盖本次请求的地址解析。
为什么访问日志不能作为最终证据
反向代理通常会把 X-Forwarded-For 等字段写入访问日志。这个值描述的是代理链路携带的信息,不一定等于当前连接使用的网络协议。
更可靠的证据是抓包:
tcpdump -nni any 'ip6 and tcp port 443' -w ipv6-check.pcap
打开抓包文件后,应确认源地址和目标地址都是 IPv6,并且连接对应探测请求的时间窗口。
抓包时还要注意网卡选择。管理网、业务网和容器网可能分别拥有不同的 IPv6 地址;只监听默认网卡,有可能得到“没有流量”的错误结论。首次验证时使用 any,确认实际出口后再收窄范围更稳妥。
常见误区
机器有 IPv6 地址,不代表有可用路由
链路本地地址、管理地址或自动生成地址只能说明网卡配置存在。还需要确认默认路由、出口策略和目标网络可达。
直接请求 IPv6 字面量并跳过证书
这样会绕过证书域名验证,探测结果不能代表真实 HTTPS 访问。除非目标就是验证裸地址端口,否则不应把 --insecure 当作正式方案。
只检查应用日志
应用层日志适合确认业务结果,网络层抓包适合确认路径。两者需要互相印证,不能互相替代。
一套可重复的检查顺序
确认监控机 IPv6 地址与路由
↓
查询目标 AAAA 记录
↓
显式绑定域名到 IPv6 地址
↓
发起保留 TLS 校验的 HTTPS 请求
↓
抓包确认真实连接
↓
核对应用响应与监控结果
链路探测的价值不只是“定时请求成功”,而是失败时能明确区分 DNS、路由、TCP、TLS 和业务响应问题。验证路径越清楚,报警才越接近可执行的诊断信息。