双栈网络:同时运行 IPv4 和 IPv6
了解如何部署和管理 IPv4 和 IPv6 共存的双栈网络。涵盖配置、故障排除和过渡策略。
什么是双栈网络#
双栈意味着在同一网络基础设施上同时运行 IPv4 和 IPv6。每个设备都获得一个 IPv4 地址和一个 IPv6 地址。应用程序根据可用性和偏好自动选择使用哪个协议。
这是大多数组织推荐的过渡方法。你不需要迁移周末或服务切换。IPv4 在你逐步启用 IPv6 时继续工作。现有客户端看不到任何中断。支持 IPv6 的客户端获得原生连接。你按自己的节奏迁移。
现实世界的采用反映了这一点。根据谷歌的统计数据,超过 40% 的用户通过 IPv6 访问他们的服务。大多数主要网络——移动运营商、云提供商、内容分发网络——今天都运行双栈。这不再是实验性的。这是生产标准。
双栈如何工作#
在双栈网络上,每个接口承载两个网络堆栈。服务器可能有 IPv4 的 192.0.2.10 和 IPv6 的 2001:db8::10。两个地址都独立工作。流量可以通过任一协议流动,具体取决于客户端和服务器协商的内容。
┌──────────────────────────────────────┐
│ 应用程序(curl、浏览器) │
│ 使用 DNS 查找地址 │
├──────────────────────────────────────┤
│ TCP/UDP(不可知) │
├───────────────────┬──────────────────┤
│ IPv4 堆栈 │ IPv6 堆栈 │
│ 192.0.2.10 │ 2001:db8::10 │
│ 通过 gw1 路由 │ 通过 gw2 路由 │
└───────────────────┴──────────────────┘
│ │
IPv4 网络 IPv6 网络网络层维护单独的路由表。IPv4 数据包遵循 IPv4 路由。IPv6 数据包遵循 IPv6 路由。它们不会相互干扰。
应用程序行为:Happy Eyeballs#
应用程序不会手动在协议之间选择。操作系统使用称为「Happy Eyeballs」(RFC 8305)的算法处理协议选择。了解这一点有助于调试连接问题。
过程:
- 应用程序请求连接到
example.com - DNS 返回 A(IPv4)和 AAAA(IPv6)记录
- 操作系统首先尝试 IPv6 连接
- 延迟 50-250 毫秒后(因实现而异),操作系统并行启动 IPv4 连接
- 首先完成的连接获胜
- 结果缓存用于后续连接
这确保用户获得最快的可用连接,而无需等待超时。IPv6 获得优先权,但损坏的 IPv6 不会导致用户可见的延迟超过几分之一秒。
使用我们的 Ping 工具针对双栈目标测试此行为。比较 IPv4 和 IPv6 响应时间。
DNS 返回两种记录类型#
在双栈中,DNS 服务器为同一主机名发布 A 和 AAAA 记录:
$ dig example.com A +short
192.0.2.10
$ dig example.com AAAA +short
2001:db8::10客户端查询两种类型(或在仅支持 IPv6 的网络中使用 DNS64 合成)。解析器返回存在的任何记录。如果只有 A 存在,客户端使用 IPv4。如果两者都存在,Happy Eyeballs 决定。
配置示例#
双栈配置在现代系统上很简单。大多数支持通过 SLAAC(无状态地址自动配置)或 DHCPv6 的自动配置。
Linux:Netplan(Ubuntu)#
现代 Ubuntu 使用 Netplan 进行网络配置。编辑 /etc/netplan/01-netcfg.yaml:
network:
version: 2
renderer: networkd
ethernets:
eth0:
dhcp4: true
dhcp6: true
accept-ra: true关键设置:
dhcp4: true- 通过 DHCP 获取 IPv4dhcp6: true- 通过 DHCPv6 获取 IPv6accept-ra: true- 接受用于 SLAAC 的路由器通告
应用配置:
sudo netplan apply验证两种协议:
ip addr show eth0
# 查找「inet」(IPv4)和「inet6」(IPv6)地址Linux:NetworkManager(Fedora、RHEL、CentOS)#
使用 NetworkManager 的命令行界面:
# 在连接上启用两种协议
nmcli connection modify "Wired connection 1" ipv4.method auto
nmcli connection modify "Wired connection 1" ipv6.method auto
# 应用更改
nmcli connection up "Wired connection 1"
# 验证配置
nmcli device show eth0对于静态双栈配置:
# 配置静态 IPv4 和 IPv6
nmcli connection modify "Wired connection 1" \
ipv4.method manual \
ipv4.addresses 192.0.2.10/24 \
ipv4.gateway 192.0.2.1 \
ipv6.method manual \
ipv6.addresses 2001:db8::10/64 \
ipv6.gateway 2001:db8::1
nmcli connection up "Wired connection 1"Windows 10/11#
Windows 默认启用双栈。要验证或重新配置:
GUI 方法:
- 按
Win + R,输入ncpa.cpl,按回车 - 右键单击网络适配器 → 属性
- 验证两个协议都已选中:
- Internet 协议版本 4(TCP/IPv4)
- Internet 协议版本 6(TCP/IPv6)
- 根据需要配置每个协议的属性
PowerShell 方法:
# 检查当前配置
Get-NetIPAddress -InterfaceAlias "Ethernet"
# 为两种协议启用自动配置
Set-NetIPInterface -InterfaceAlias "Ethernet" -Dhcp Enabled
Set-NetIPInterface -InterfaceAlias "Ethernet" -AddressFamily IPv6 -Dhcp Enabled
# 或配置静态地址
New-NetIPAddress -InterfaceAlias "Ethernet" `
-IPAddress 192.0.2.10 -PrefixLength 24 -DefaultGateway 192.0.2.1
New-NetIPAddress -InterfaceAlias "Ethernet" `
-IPAddress 2001:db8::10 -PrefixLength 64 -DefaultGateway 2001:db8::1
# 验证
Get-NetIPAddress -InterfaceAlias "Ethernet"
Get-NetRoute -InterfaceAlias "Ethernet"使用 radvd 的 Linux 路由器#
要将 Linux 系统配置为双栈路由器,启用转发并运行路由器通告守护程序。
启用 IP 转发:
# 临时
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1
# 永久
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p安装和配置 radvd:
sudo apt install radvd # Ubuntu/Debian
# 或
sudo dnf install radvd # Fedora/RHEL编辑 /etc/radvd.conf:
interface eth0
{
AdvSendAdvert on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
prefix 2001:db8::/64
{
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr on;
};
RDNSS 2001:4860:4860::8888 2001:4860:4860::8844
{
};
};启动服务:
sudo systemctl enable radvd
sudo systemctl start radvdeth0 网络上的客户端现在将接收路由器通告并通过 SLAAC 自动配置 IPv6 地址。
Cisco IOS 路由器#
在 Cisco 路由器上配置双栈:
! 启用 IPv6 路由
ipv6 unicast-routing
! 配置 WAN 接口(双栈)
interface GigabitEthernet0/0
description WAN
ip address dhcp
ipv6 address autoconfig
ipv6 enable
no shutdown
! 配置 LAN 接口(双栈)
interface GigabitEthernet0/1
description LAN
ip address 192.168.1.1 255.255.255.0
ipv6 address 2001:db8:1::1/64
ipv6 enable
ipv6 nd prefix 2001:db8:1::/64
ipv6 nd ra interval 10
no shutdown
! 配置默认路由
ip route 0.0.0.0 0.0.0.0 GigabitEthernet0/0
ipv6 route ::/0 GigabitEthernet0/0
! 验证配置
show ip interface brief
show ipv6 interface briefSLAAC 与 DHCPv6
路由器通告启用 SLAAC,它在没有 DHCP 服务器的情况下自动配置客户端地址。为了获得更多控制(DNS 服务器、NTP、域名),与 SLAAC 一起使用 DHCPv6。大多数网络为简单起见运行 SLAAC。
地址选择规则#
当双栈客户端连接到双栈服务器时,它如何选择使用哪个协议?RFC 6724 定义了源和目标地址选择算法。
默认偏好顺序#
算法基于以下规则评估地址(简化):
- 偏好相同范围 - 链路本地到链路本地,全局到全局
- 偏好匹配地址族 - 如果源是 IPv6,偏好 IPv6 目标
- 偏好更高优先级 - IPv6 具有比 IPv4 更高的默认优先级
- 偏好原生传输 - 如果可能避免隧道
- 偏好较小范围 - 偏好更具体的路由
- 使用最长匹配前缀 - 更具体的路由获胜
默认情况下,IPv6 优先于 IPv4。这是有意的——它鼓励 IPv6 采用并提供更好的性能(无 NAT 开销)。
为什么 IPv6 通常获胜#
给定双栈客户端和双栈服务器:
客户端有: 192.0.2.100 和 2001:db8::100
服务器有: 192.0.2.10 和 2001:db8::10
DNS 返回: A 192.0.2.10,AAAA 2001:db8::10选择算法:
- 两个地址都有全局范围 → 平局
- 客户端有 IPv4 和 IPv6 源地址 → 平局
- IPv6 优先级(::ffff:0:0/96 = 35,::/0 = 40)> IPv4 优先级(::ffff:0:0/96 = 35)→ IPv6 获胜
结果:连接使用 IPv6,除非 IPv6 连接中断。
策略表配置#
你可以通过编辑策略表来修改默认行为。这很少需要,但对特定要求很有用。
Linux(Glibc):
编辑 /etc/gai.conf(地址选择策略):
# 偏好 IPv4 而不是 IPv6(不推荐)
precedence ::ffff:0:0/96 100
precedence ::/0 50Windows:
# 显示当前策略表
Get-NetIPv6Protocol | Format-List
# 偏好 IPv4(不推荐)
Set-NetIPv6Protocol -PreferredProtocol IPv4
# 重置为默认值(偏好 IPv6)
Set-NetIPv6Protocol -PreferredProtocol IPv6不要强制偏好 IPv4
覆盖默认值以偏好 IPv4 会破坏双栈的目的。修复损坏的 IPv6 连接,而不是用策略更改隐藏它。仅支持 IPv6 的网络(移动运营商)上的用户将体验到性能下降或故障。
IPv4 何时获得偏好#
IPv4 在这些场景中被选择:
- 没有 IPv6 连接 - 如果 IPv6 路由中断,Happy Eyeballs 回退到 IPv4
- 6to4 或 Teredo - 隧道 IPv6 的优先级低于原生 IPv4
- 显式应用程序选择 - 应用程序强制使用 IPv4(不好的做法但会发生)
- 修改的策略表 - 管理员手动更改了偏好顺序
大多数标记为「偏好 IPv4」的问题实际上是损坏的 IPv6 连接触发回退。
DNS 注意事项#
双栈 DNS 配置至关重要。配置错误的 DNS 会导致连接延迟、故障或意外的协议选择。
发布两种记录类型#
对于每个双栈服务,发布 A 和 AAAA 记录:
example.com. 300 IN A 192.0.2.10
example.com. 300 IN AAAA 2001:db8::10如果 IPv6 不工作,不要发布 AAAA。客户端将首先尝试 IPv6,失败,然后在延迟后回退到 IPv4。这创造了糟糕的用户体验。
解析顺序#
现代 DNS 解析器同时或以最小延迟查询 A 和 AAAA。解析器返回两种类型,客户端的操作系统执行地址选择。
一些较旧或配置错误的解析器按顺序查询(首先 A,然后 AAAA)。这增加了延迟,但不会破坏功能。
当一个协议失败时会发生什么#
如果 IPv6 可达但服务在 IPv6 上不响应:
- 客户端尝试 IPv6 连接
- 连接超时或被拒绝
- Happy Eyeballs 并行或在短暂延迟后尝试 IPv4
- IPv4 连接成功
总延迟:通常为 50-250 毫秒加上连接超时(在最坏情况下为 1-3 秒)。明显但不是灾难性的。
更好的解决方案:修复 IPv6 连接或删除 AAAA 记录,直到 IPv6 工作。
TTL 对齐#
为 A 和 AAAA 记录设置相同的 TTL。不匹配的 TTL 会导致不一致的缓存和奇怪的客户端行为。
# 好
example.com. 300 IN A 192.0.2.10
example.com. 300 IN AAAA 2001:db8::10
# 坏 - TTL 不匹配
example.com. 300 IN A 192.0.2.10
example.com. 3600 IN AAAA 2001:db8::10如果你需要更改 IP 地址,事先降低两条记录上的 TTL。等待旧 TTL 到期,然后更改 IP 并恢复正常 TTL。
常见问题和解决方案#
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 连接建立缓慢 | IPv6 超时然后回退到 IPv4 | 修复 IPv6 连接或删除 AAAA 记录 |
| 间歇性连接故障 | 一个协议中断,Happy Eyeballs 竞争 | 使用 curl -4 和 curl -6 分别测试两种协议 |
| 应用程序只使用 IPv4 | 硬编码 IPv4,旧库,或绑定到 0.0.0.0 | 检查应用程序设置,更新代码以绑定 :: |
| 没有 IPv6 默认路由 | 路由器未发送 RA 或 DHCPv6 未提供路由 | 验证路由器配置,检查 ip -6 route show |
| Windows 偏好 IPv4 | Teredo 或 6to4 活动(隧道) | 禁用隧道接口:netsh interface teredo set state disabled |
| 防火墙阻止 IPv6 | IPv6 规则未配置或过于严格 | 对两种协议应用相同的安全策略 |
| 隐私地址更改破坏连接 | RFC 4941 临时地址轮换 | 对服务器使用稳定地址,对客户端使用临时地址 |
| 路径 MTU 发现失败 | ICMPv6「数据包太大」被阻止 | 在防火墙规则中允许 ICMPv6 类型 2 |
详细故障排除:慢速连接#
大多数双栈投诉涉及「慢」连接。这通常意味着损坏的 IPv6 触发回退延迟。
诊断:
# 仅测试 IPv4
curl -4 -w "Time: %{time_total}s\n" -o /dev/null -s https://example.com
# 仅测试 IPv6
curl -6 -w "Time: %{time_total}s\n" -o /dev/null -s https://example.com
# 测试默认值(双栈)
curl -w "Time: %{time_total}s\n" -o /dev/null -s https://example.com如果 -6 失败或超时,但 -4 成功,并且默认值显示延迟,则你有损坏的 IPv6。
修复选项:
- 修复 IPv6 - 首选解决方案。调试路由、防火墙规则或 ISP 连接。
- 删除 AAAA 记录 - 临时解决方法。服务变为仅 IPv4,直到你修复 IPv6。
- 不要在服务器上禁用 IPv6 - 这会破坏事物并隐藏真正的问题。
监控双栈网络#
你无法管理你不测量的东西。双栈网络需要独立监控两种协议。
测试两种协议#
分别测试连接以识别哪个协议失败:
# 通过 IPv4 Ping
ping -4 google.com
# 通过 IPv6 Ping
ping -6 google.com
# 通过 IPv4 Traceroute
traceroute -4 google.com
# 通过 IPv6 Traceroute
traceroute -6 google.com
# 使用特定协议的 Curl
curl -4 https://example.com
curl -6 https://example.com将这些测试构建到监控脚本中。当一个协议失败时发出警报,即使另一个协议工作。
要跟踪的指标#
监控这些双栈特定指标:
- 协议分布 - 使用 IPv4 与 IPv6 的流量百分比
- 连接成功率 - 每个协议,跟踪失败的连接
- 响应时间 - 比较 IPv4 和 IPv6 延迟
- BGP 前缀 - 确保 IPv4 和 IPv6 路由都已通告
- DNS 查询比率 - 跟踪 A 与 AAAA 查询率
- ICMPv6 错误率 - 峰值表示路由或 MTU 问题
随着时间的推移趋势这些指标显示采用进度并在影响用户之前突出显示问题。
协议故障警报#
为每个协议创建单独的警报:
- IPv4 默认网关不可达
- IPv6 默认网关不可达
- AAAA 记录已发布但 IPv6 服务不可达
- IPv6 连接超时峰值
- 非对称路由(通过 IPv6 发送的流量,通过 IPv4 返回)
不要依赖通用的「服务关闭」警报。你需要协议特定的可见性。
测试工具#
使用这些工具验证双栈操作:
- ping6.net 工具 - 从不同角度测试 IPv4 和 IPv6 连接
- 带 -4/-6 标志的 curl - 强制协议选择进行 HTTP(S) 测试
- dig +short A/AAAA - 验证 DNS 返回两种记录类型
- tcpdump/wireshark - 捕获和分析协议特定流量
- mtr -4 / mtr -6 - 显示路径差异的连续 traceroute
我们的 Ping 工具和 Traceroute 工具支持强制 IPv4 或 IPv6,使双栈测试变得简单。
安全注意事项#
双栈扩大了你的攻击面。两种协议都需要等效的安全策略。
两种协议的防火墙规则#
最常见的双栈安全错误:忘记配置 IPv6 防火墙规则。管理员花费数年构建 IPv4 ACL,然后在没有过滤的情况下启用 IPv6。攻击者喜欢这个。
对两种协议应用相同的安全策略:
如果你的 IPv4 策略是:
拒绝所有入站,除了:
- TCP 22(SSH)来自管理网络
- TCP 443(HTTPS)来自任何地方
- ICMP 回显请求(ping)你的 IPv6 策略必须是:
拒绝所有入站,除了:
- TCP 22(SSH)来自管理网络
- TCP 443(HTTPS)来自任何地方
- ICMPv6 类型 1、2、3、4、128、129(基本类型)
- ICMPv6 类型 133-137(邻居发现,仅本地)像 ip6tables、nftables 或商业防火墙这样的工具支持双栈。配置两个地址族。
常见错误:保护 IPv4 但忘记 IPv6#
组织为了合规性或测试启用 IPv6,然后忘记它处于活动状态。攻击者扫描 IPv6 范围以寻找未过滤的主机。
示例场景:
- 管理员配置限制性 IPv4 防火墙,仅暴露 HTTPS
- 路由器上启用 IPv6 以「为未来做准备」
- 服务器通过 SLAAC 获得 IPv6 地址
- 未配置 IPv6 防火墙规则
- 攻击者扫描 2001:db8::/64,发现暴露的 SSH、数据库、内部服务
预防:
- 像审计 IPv4 一样审计 IPv6 防火墙规则
- 在两种协议上默认拒绝
- 使用仅支持 IPv6 的扫描工具进行测试
- 监控意外的 IPv6 连接
关键安全差距
在不配置防火墙的情况下启用 IPv6 相当于将服务器直接放在没有过滤的互联网上。在发布 AAAA 记录之前始终配置 IPv6 安全规则。
客户端的隐私扩展#
SLAAC 使用接口的 MAC 地址(EUI-64 格式)生成地址。这在网络之间创建了一个稳定的、可跟踪的标识符——对移动客户端来说是一个隐私问题。
隐私扩展(RFC 4941)生成定期轮换的随机临时地址。客户端使用临时地址进行出站连接,同时为入站连接维护稳定的地址。
启用隐私扩展:
Linux:
# 检查状态(2 = 偏好临时地址)
sysctl net.ipv6.conf.all.use_tempaddr
# 启用
sudo sysctl -w net.ipv6.conf.all.use_tempaddr=2
# 使其永久
echo "net.ipv6.conf.all.use_tempaddr = 2" | sudo tee -a /etc/sysctl.confWindows:
隐私扩展在 Windows 7 及更高版本上默认启用。验证:
netsh interface ipv6 show privacymacOS:
默认启用。不需要配置。
重要: 不要在服务器上启用隐私扩展。临时地址会破坏 DNS、监控和防火墙规则。仅在客户端设备上使用它们。
何时考虑仅 IPv6#
双栈是一种过渡策略,而不是最终目标。最终,网络转向仅 IPv6,简化操作并消除 IPv4 地址稀缺性。
移动运营商已经使用仅 IPv6#
主要移动运营商(T-Mobile USA、Reliance Jio、EE UK)运行仅 IPv6 核心网络。他们在需要时使用 464XLAT(NAT64 + CLAT)提供 IPv4 连接。
用户不会注意到。他们的手机有 IPv6 地址,传统的仅 IPv4 应用程序通过翻译透明地工作。
用于 IPv4 访问的 NAT64/DNS64#
仅 IPv6 网络使用 NAT64 和 DNS64 访问 IPv4 服务:
- 客户端查询仅 IPv4 服务的 DNS
- DNS64 使用 NAT64 前缀合成 AAAA 记录:
64:ff9b::192.0.2.10 - 客户端将 IPv6 流量发送到合成地址
- NAT64 网关转换为 IPv4,转发到服务
- 响应转换回 IPv6
这允许仅 IPv6 客户端访问剩余的 IPv4 互联网而无需运行双栈。
何时部署仅 IPv6:
- 移动网络(已经是标准)
- 新的数据中心建设(完全避免 IPv4)
- 没有传统要求的全新部署
- 完全控制客户端和应用程序的组织
何时保持双栈:
- 现有企业网络(IPv4 依赖需要多年才能消除)
- 具有传统硬件/软件的网络
- 你不控制所有客户端的环境
- 面向互联网的服务(双栈最大化可达性)
简化优势#
运行一个协议而不是两个可以减少:
- 路由表大小(一个表而不是两个)
- 防火墙复杂性(一个策略而不是两个)
- IP 地址管理开销
- 监控和警报复杂性
但这些好处只有在完全消除 IPv4 之后才会实现。双栈比仅 IPv4 或仅 IPv6 更复杂,但它是大多数网络唯一实用的迁移路径。
相关文章#
测试你的双栈网络
使用我们的 Ping 工具和 -4 和 -6 标志分别测试两种协议,使用我们的 Traceroute 工具验证路由路径。
常见问题#
双栈会使我的带宽使用量翻倍吗?
不会。流量对每个连接使用 IPv4 或 IPv6,而不是两者。双栈意味着两种协议都可用,但单个连接选择一个并坚持使用它。
一些协议(如 BGP)可能通过两个地址族交换路由信息,但这是可以忽略的开销。
为什么我的双栈网络比仅 IPv4 慢?
不应该慢。较慢的性能通常表示损坏或配置错误的 IPv6 在回退到 IPv4 之前触发连接超时。使用 curl -4 和 curl -6 分别测试每个协议以识别哪个失败。
如果 IPv6 较慢但工作,请检查路由效率低下或 ISP 对等问题。IPv6 路径并不总是像 IPv4 路径那样优化(还没有)。
我可以使用 NAT 运行双栈吗?
可以。IPv4 可以使用 NAT,而 IPv6 使用没有 NAT 的全局地址。这在企业和家庭网络中很常见。你的路由器转换私有 IPv4 地址(192.168.x.x、10.x.x.x),同时让 IPv6 不变地通过。
IPv6 不需要 NAT。使用防火墙而不是依赖 NAT 来提供安全性。
如果我不使用 IPv6,我应该禁用它吗?
不。Microsoft、Apple 和 Linux 发行版都建议保持 IPv6 启用,即使你没有积极使用它。禁用 IPv6 可能会破坏 DirectAccess、HomeGroup、Windows Update 等功能,并导致 DNS 解析延迟。
如果你真的不需要它,启用时是无害的。如果你以后可能需要它,保持启用可以节省你重新配置的工作。
如何知道我的流量是使用 IPv4 还是 IPv6?
使用以下方式检查活动连接:
# Linux/macOS
netstat -tuln | grep -E '(tcp|udp)'
# Windows PowerShell
Get-NetTCPConnection | Select-Object LocalAddress,RemoteAddress
# 或使用 tcpdump 查看实际数据包
sudo tcpdump -n -i eth0 'ip6 or ip'IPv6 地址更长并包含冒号。IPv4 地址是点分十进制。大多数监控工具按协议标记流量。
访问 ping6.net 查看你使用哪个协议访问我们的站点。