Lab / Systems

腾讯云 VPS IPv6 不通排查:从 metadata 到静态 IPv6

记录一次腾讯云 VPS 控制台显示 IPv6,但系统内公网 IPv6 不通的排查过程:地址、路由、metadata、DHCPv6 和最终静态配置方案。

背景

腾讯云控制台里已经给 VPS 开启了 IPv6,实例信息也能看到公网 IPv6,但系统内实际访问 IPv6 外网失败。

这个问题容易让人误判:控制台有 IPv6,不代表系统里已经拿到了可用的公网 IPv6 地址,也不代表默认路由、网关、安全组、VPC 路由都已经完整生效。

现象

主机内测试 IPv6 外网不通:

ping -6 2400:3200::1
curl -6 https://ifconfig.co

表现为报错或超时。

第一轮检查

先看系统里真实的 IPv6 地址和路由:

ip -6 addr show
ip -6 route show

当时观察到的关键信息:

  • eth0 只有内网 IPv6。
  • eth0 没有 IPv6 默认路由。
  • tailscale0 也有 IPv6,但那是 Tailscale 内网地址,不能代表公网 IPv6 连通。

这一步可以先确认一个基本判断:问题不在应用层,而在系统网络层。

查询腾讯云 metadata

腾讯云 metadata 能直接给出本机网络相关信息:

curl -sS http://metadata.tencentyun.com/latest/meta-data/local-ipv6
curl -sS http://metadata.tencentyun.com/latest/meta-data/public-ipv6
curl -sS http://metadata.tencentyun.com/latest/meta-data/network/interfaces/macs/<mac-address>/ipv6-gateway

得到的信息类型大致是:

local IPv6:fdxx:.../128
public IPv6:240d:.../128
IPv6 gateway:fe80::...

这里有一个关键点:metadata 里能看到公网 IPv6,但系统网卡上不一定已经自动绑定了这个公网 IPv6。

临时路由测试

先尝试只补 IPv6 默认路由:

ip -6 route add default via fe80::<gateway> dev eth0 metric 1002

结果:

  • 路由表出现 IPv6 默认路由。
  • curl -6 外网仍然超时。

这说明问题不只是缺默认路由。系统里只有内网 IPv6 时,即使手动补默认路由,也不能直接拿内网 IPv6 去访问公网 IPv6。

测试结束后撤回临时路由:

ip -6 route del default via fe80::<gateway> dev eth0 metric 1002

最终有效方案

最终使用 metadata 返回的公网 IPv6 手动绑定到 eth0,并持久化默认路由。

持久化文件:

/etc/network/interfaces.d/60-ipv6-static

配置示例:

# Tencent Cloud public IPv6 for eth0.
# Keep this separate from cloud-init managed IPv4 config.
iface eth0 inet6 static
    address <your-public-ipv6>
    netmask 128
    post-up ip -6 route replace default via fe80::<gateway> dev eth0 metric 1002
    pre-down ip -6 route del default via fe80::<gateway> dev eth0 metric 1002 || true

应用配置:

systemctl restart networking

验证:

curl -6 -sS --max-time 8 https://ifconfig.co
curl -6 -I --max-time 8 https://<your-ipv6-service-domain>/

期望结果:

curl -6 https://ifconfig.co 返回公网 IPv6
IPv6 服务域名返回 HTTP/2 200

这次修复后,依赖 IPv6 访问的监控 agent 也恢复连接。

为什么不直接照 guide 配 DHCPv6

排查时也参考过一份腾讯云 IPv6 guide。它的大方向是检查 RA、自动配置和 DHCPv6,但里面有一段配置不适合直接照搬:

ipv6rs
noipv6rs
option dhcp6_ia_na

问题在于:

  • ipv6rsnoipv6rs 同时出现,语义冲突。
  • noipv6rs 会禁止发送或接收 RA。
  • option dhcp6_ia_na 更像是请求 DHCPv6 option 的写法,不是 dhcpcd 请求 IPv6 地址租约的主配置项。

如果要继续验证自动获取,更合理的待验证写法是:

interface eth0
    ipv6rs
    ia_na 1

不过验证自动获取前,要临时停用已经生效的静态 IPv6 配置,否则静态地址会掩盖 DHCPv6 测试结果:

mv /etc/network/interfaces.d/60-ipv6-static /etc/network/interfaces.d/60-ipv6-static.disabled
systemctl restart networking

验证:

ip -6 addr show eth0
ip -6 route | grep default
ping6 -c 4 2400:3200::1
curl -6 -sS --max-time 8 https://ifconfig.co

如果自动获取失败,再恢复已验证可用的静态配置:

mv /etc/network/interfaces.d/60-ipv6-static.disabled /etc/network/interfaces.d/60-ipv6-static
systemctl restart networking

排查清单

遇到“控制台有 IPv6,但系统内 IPv6 不通”时,我会按这个顺序看:

  1. ip -6 addr show eth0:有没有公网 IPv6。
  2. ip -6 route show:有没有 IPv6 默认路由。
  3. metadata:公网 IPv6 和 IPv6 gateway 是否存在。
  4. 安全组:IPv6 出站是否允许,例如 ::/0
  5. VPC / 子网:IPv6 网关和路由表是否正常。
  6. 系统参数:accept_raautoconf 是否被关掉。
  7. DHCPv6:dhcpcd 是否真正请求了 IA_NA 地址。

常用检查命令:

sysctl net.ipv6.conf.eth0.accept_ra
sysctl net.ipv6.conf.eth0.autoconf
ps aux | grep dhcpcd
ip -6 addr show eth0
ip -6 route | grep default

如果要抓 RA 包:

tcpdump -i eth0 icmp6 and 'ip6[40] == 134'

判断方式:

  • RA Flags=[managed]:通常需要有状态 DHCPv6,dhcpcd 应配置 ia_na 1 请求地址。
  • RA Flags=[other]:通常需要 DHCPv6 获取补充配置,是否需要 ia_na 1 取决于云侧是否通过 DHCPv6 发公网地址。
  • RA 含公网 Prefix 且 flags 为空:通常 SLAAC 即可,需要确保 autoconf=1
  • 无 RA:优先查腾讯云控制台、VPC、子网、IPv6 网关和路由表。

结论

这次问题的关键不是“有没有 IPv6”,而是:

控制台分配了公网 IPv6
metadata 能看到公网 IPv6
系统网卡没有自动拿到公网 IPv6
默认路由也没有完整生效

最终通过静态绑定公网 IPv6 和默认网关恢复。

长期看,如果云厂商的 DHCPv6 自动获取能稳定工作,自动获取会更优雅;但对一台正在跑博客和监控的小 VPS 来说,先用静态配置恢复确定性更重要。