PVE 宿主机无法获取 IPv6 地址的问题排查与解决教程

PVE 宿主机无法获取 IPv6 地址的问题排查与解决教程

PVE 宿主机无法获取 IPv6 地址的问题排查与解决教程

1. 问题现象

  • 在 PVE 宿主机上执行 ip -6 addr show vmbr0,输出中只有链路本地地址(以 fe80:: 开头),没有公网 IPv6 地址(如 240e:2001: 开头)。

  • 检查 IPv6 状态:sysctl net.ipv6.conf.vmbr0.accept_ra 显示为 1,但即使上游路由器已经开启 IPv6 并发送路由通告(RA),PVE 仍然无法自动获取地址。

  • 可能伴随的症状:运行在 PVE 上的虚拟机(如 OpenWrt)虽然启用了 IPv6,但无法获得公网 IPv6 地址,或访问某些页面时因 IPv6 超时而变慢。

2. 原因分析

  • PVE 默认开启了 IPv6 转发(net.ipv6.conf.all.forwarding=1),这是作为虚拟化宿主机的常见设置(用于虚拟机之间或虚拟机和外部网络的 IPv6 路由)。

  • 当 IPv6 转发开启时,Linux 内核会忽略路由通告(RA),即使 accept_ra 设置为 1(默认值),也不会自动配置 IPv6 地址。这是内核的安全机制,因为开启转发的主机通常应充当路由器,不应被动接收 RA 来改变自己的路由表。

  • 要强制接口接收 RA 并自动配置地址,需要将对应接口的 accept_ra 设置为 2(表示始终接受 RA,即使转发已开启)。

3. 解决方案

3.1 临时修复(立即生效,重启后失效)

在 PVE 宿主机上执行以下命令,为 vmbr0 接口设置 accept_ra=2

sysctl net.ipv6.conf.vmbr0.accept_ra=2
 

然后触发接口重新获取 RA:

# 方法1:重启网络服务(可能短暂断开 SSH,建议从本地控制台执行)

systemctl restart networking

方法2:重启单个接口(更安全) 

ifdown vmbr0 && ifup vmbr0

之后再次检查 IPv6 地址:

ip -6 addr show vmbr0
 

如果上游 RA 正常,应该很快出现公网 IPv6 地址。

3.2 永久修复(重启后依然有效)

创建或编辑 sysctl 配置文件,将设置持久化:

# 创建配置文件(如果不存在)

echo "net.ipv6.conf.vmbr0.accept_ra = 2" >> /etc/sysctl.d/99-ipv6.conf
echo "net.ipv6.conf.all.accept_ra = 2"   >> /etc/sysctl.d/99-ipv6.conf
echo "net.ipv6.conf.default.accept_ra = 2" >> /etc/sysctl.d/99-ipv6.conf
 

应用所有 sysctl 配置:

sysctl --system
 

此时配置已生效,无需重启网络。为保险起见,可重启网络或接口以确保 RA 被重新获取:

systemctl restart networking # 或 ifdown vmbr0 && ifup vmbr0
 

3.3 验证配置

  • 确认 accept_ra 已变为 2:

    sysctl net.ipv6.conf.vmbr0.accept_ra

    输出应为 net.ipv6.conf.vmbr0.accept_ra = 2

  • 确认已获取公网 IPv6 地址:

    ip -6 addr show vmbr0

    应看到类似 inet6 240e:.../64 scope global dynamic 的地址。

  • 测试 IPv6 连通性:

     
    ping6 -c 4 2400:3200::1

    如果能 ping 通,说明 IPv6 已正常工作

4. 附加排查

4.1 检查上游路由器是否发送 RA

如果执行上述步骤后仍未获取到地址,可能是上游设备(物理路由器/光猫)未正确发送 RA。在 PVE 上抓包验证:

# 安装 tcpdump(如果未安装)

apt update && apt install tcpdump

# 在 vmbr0 上抓取 RA 报文(ICMPv6 类型 134)

tcpdump -i vmbr0 -v -c 10 'icmp6 and ip6[40] == 134'

等待 30 秒左右,观察是否有 RA 报文出现。若无任何输出,说明上游未发送 RA,需要检查路由器 IPv6 设置(如是否开启“路由通告”、“无状态配置”等)。

4.2 检查防火墙是否阻挡 ICMPv6

PVE 宿主机可能启用了防火墙(如 nftables 或 iptables),阻止了 ICMPv6(IPv6 邻居发现协议)。查看 IPv6 防火墙规则:

ip6tables -L -n -v
 

如果发现大量 DROP 规则,可临时清空规则测试(注意:生产环境需谨慎,之后应恢复):

ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -F
 

然后再次检查是否获取到 IPv6 地址。若获取成功,则需调整防火墙规则,放行 ICMPv6(类型 133-137)和 DHCPv6 流量。

4.3 检查网络接口的 autoconf 设置

sysctl net.ipv6.conf.vmbr0.autoconf

确保接口的自动配置已启用:

 

应返回 1。若为 0,则需设置为 1(可通过 sysctl 或配置文件修改)。

5. 相关注意事项

  • 重启网络的影响systemctl restart networking 可能会短暂断开 SSH 连接,建议在本地控制台操作,或使用 screen 等工具避免中断。

  • 虚拟机 IPv6 继承:当 PVE 宿主机成功获取 IPv6 后,桥接模式下的虚拟机(如 OpenWrt)通常也能通过 DHCPv6 或 SLAAC 获得 IPv6 地址,前提是虚拟机的 WAN 口启用了 IPv6 自动配置。

  • 上游路由器配置:确保物理路由器已开启 IPv6,并启用了 RA(路由通告)和前缀委托(PD),否则即使 PVE 设置正确也无法获取地址。

6. 总结

PVE 宿主机无法获取 IPv6 地址的典型原因是开启了 IPv6 转发导致内核忽略 RA。通过将接口的 accept_ra 设置为 2,可以强制接收 RA 并自动配置地址。此设置需持久化到 sysctl 配置文件,并在必要时重启网络。如果问题依然存在,请检查上游 RA 和防火墙规则。

按照本教程操作,您应该能顺利让 PVE 获得公网 IPv6 地址,进而为虚拟机提供 IPv6 连接。

© 版权声明
THE END
喜欢就支持一下吧
点赞15 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容