在 Linux 上部署 464XLAT 实现 IPv6 Only 网络下提供 IPv4 兼容

3.7k 词

前言

随着互联网的快速发展,IPv4因其数量限制已不适合当今的互联网,我们应当加速推进IPv6 Only网络的推进,然而还有一些应用仍然只支持IPv4网络,我们希望在推进IPv6 Only网络的同时为这些应用提供IPv4兼容
为此有很多解决方案,详细参阅 IPv6 过渡机制

而我的选择是464XLAT,它的优点在于:

  • 兼容性高,对于使用IPv4的应用是无感的
  • 无额外的MTU开销
  • 配置简单

464XLAT的简单拓扑如下:

(来源: RFC6877)
其它相关细节请参阅 RFC6877

部署说明

CLAT:

  • 推荐至少两个IPv6,非则将需要使用NAT66
  • 如果为虚拟机,只支持全虚拟化的环境,如KVM,Hyper-V,VirtualBox等

PLAT:

  • 至少拥有 /96 的可路由IPv6
  • 如果为虚拟机,只支持全虚拟化的环境,如KVM,Hyper-V,VirtualBox等

本文使用 Debian12 进行部署
示例中的IPv6 Prefix:

  • CLAT: fd65::64:192.0.2.0/120
  • PLAT: fd63::64:0.0.0.0/96

安装jool

1
2
3
apt update
apt install jool-dkms jool-tools
reboot

部署CLAT

CLAT是客户端转换器,负责将v4p host发送的IPv4数据包转换为IPv6,以及将v4g host经过PLAT发往v4p host的IPv6转换为IPv4

有两种部署方式:

  • 作为仅本地部署: 适用于仅需要部署单实例并且其本身需要使用464XLAT连接IPv4网络
  • 作为路由器部署: 适用于多个实例需要使用使用464XLAT连接IPv4网络,部署为CLAT的设备无法使用该CLAT为自身服务

    At present, Netfilter Jool only hooks itself to PRE_ROUTING. It does not attach itself to LOCAL_OUT. This means it can only translate traffic that inbounds from some interface (physical or otherwise). It does not intercept packets sourced from its own network namespace.

作为仅本地部署

将以下内容写入clat.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/bin/bash

clat_ip="fd65::64:192.0.2.1" # 修改为你CLAT要使用的 IPv6 地址
plat_prefix="fd63::64:0.0.0.0/96" # 修改为你的PLAT IPv6 Prefix

# 为 jool_siit 配置一个独立的 Network Namespace
ip netns add joolns
ip link add name to_jool type veth peer name to_world
ip link set up dev to_jool
ip link set dev to_world netns joolns
ip netns exec joolns ip link set up dev to_world
to_jool_addr=$(ip -6 addr show scope link dev to_jool | grep 'inet6' | awk '{print $2}' | cut -d/ -f1)
to_world_addr=$(ip netns exec joolns ip -6 addr show scope link dev to_world | grep 'inet6' | awk '{print $2}' | cut -d/ -f1)

# 配置连接 jool_siit 的接口
ip netns exec joolns ip -6 route add default via $to_jool_addr dev to_world
ip netns exec joolns ip addr add 192.0.2.2/24 dev to_world
ip route add $clat_ip/128 via $to_world_addr dev to_jool
ip addr add 192.0.2.1/24 dev to_jool
ip route del 0.0.0.0/0
ip route add default via 192.0.2.2 dev to_jool

# 配置 jool_siit
modprobe jool_siit
echo 1 | tee /proc/sys/net/ipv6/conf/*/forwarding
ip netns exec joolns sysctl -w net.ipv4.conf.all.forwarding=1
ip netns exec joolns sysctl -w net.ipv6.conf.all.forwarding=1
ip netns exec joolns jool_siit instance add --netfilter --pool6 $plat_prefix
ip netns exec joolns jool_siit eamt add 192.0.2.1 $clat_ip

这里的to_jool和to_world是虚拟网卡,to_jool用于提供一个IPv4虚拟接口,并将IPv4路由到joolns里,上方配置于这两个接口的ipv4可以按需修改

作为路由器部署

将以下内容写入clat.sh

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

clat_prefix="fd65::64:192.0.2.0/120" # 修改为你的CLAT IPv6 Prefix
plat_prefix="fd63::64:0.0.0.0/96" # 修改为你的PLAT IPv6 Prefix
clat_ipv4_prefix="192.0.2.0/24" # 修改为你的CLAT IPv4 Prefix

sysctl -w net.ipv4.conf.all.forwarding=1
sysctl -w net.ipv6.conf.all.forwarding=1
modprobe jool_siit
jool_siit instance add --netfilter --pool6 $plat_prefix
jool_siit eamt add $clat_ipv4_prefix $clat_prefix

启动

执行 clat.sh 即可启动CLAT
你还可以配置开机自启该脚本,可以使用systemd等工具实现,这里不再赘述

部署PLAT

PLAT是网关转换器,负责将CLAT发过来的IPv6数据包转换为IPv4,以及将v4g host发来的IPv4数据包转换为IPv6
此处也有两种部署方式:

  • 有状态NAT64: 常见的方式,适用于大部分场景
  • 无状态NAT64: 仅适用于需要为CLAT侧的每个设备分配独立的IPv4的场景(你需要为此准备足够多的IPv4)(这其实不符合RFC6877)

有状态NAT64

将以下内容写入plat.sh

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash

plat_prefix="fd63::64:0.0.0.0/96" # 修改为你的PLAT IPv6 Prefix

modprobe jool
jool instance add --netfilter --pool6 $plat_prefix

# 可选: 配置IPv4 Pool,当你希望NAT到多个ipv4时使用
# 具体参阅 https://nicmx.github.io/Jool/en/usr-flags-pool4.html
#jool pool4 add --tcp <IPv4-prefix> <port-range>
#jool pool4 add --udp <IPv4-prefix> <port-range>
#jool pool4 add --icmp <IPv4-prefix> <port-range>

无状态NAT64

将以下内容写入plat.sh

1
2
3
4
5
6
7
8
#!/bin/bash

clat_prefix="fd65::64:192.0.2.0/120" # 修改为你的CLAT IPv6 Prefix
plat_prefix="fd63::64:0.0.0.0/96" # 修改为你的PLAT IPv6 Prefix
clat_ipv4_prefix="192.0.2.0/24" # 修改为你的CLAT IPv4 Prefix

jool_siit instance add --netfilter --pool6 $plat_prefix
jool_siit eamt add $clat_ipv4_prefix $clat_prefix

启动

执行 plat.sh 即可启动CLAT
你还可以配置开机自启该脚本,可以使用systemd等工具实现,这里不再赘述

测试结果

部署完成后,你可以通过ping6和ping4来测试是否成功
效果图:

在 Linux 上部署 464XLAT 实现 IPv6 Only 网络下提供 IPv4 兼容

http://example.com/post/464xlat/
Author

lingxh

Published at

2024-10-18

License

CC BY-NC-SA 4.0

留言