最近在熟悉 vpp 的各项功能,摆在眼前的第一个就是 nat,网上相关的资料还比较少。下面就整理一下目前所学到的,在 vpp 中进行 nat 实验的基本流程,还不完善,可能有理解上的错误,欢迎指正。
首先给出该 nat 实验的网络拓扑连接,下面的步骤稍微有点多,但目的是为了搭建这样的拓扑图。
基本流程:
1)在 host 中创建一对 veth 设备 vpp1outside 和 vpp1outsidehost
$ ip link add name vpp1outside type veth peer name vpp1outsidehost
2)在 host 中给 vpp1outsidehost 设置 IP
$ ip addr add 10.10.1.1/24 dev vpp1outsidehost
$ ifconfig vpp1outsidehost up
3)在 host 中创建另外一对 veth 设备 vpp1inside 和 vpp1insidehost
$ ip link add name vpp1inside type veth peer name vpp1insidehost
4)在 host 中给 vpp1insidehost 配置 IP
$ ip addr add 10.10.2.1/24 dev vpp1insidehost
5) 在 host 中创建 netns
$ ip netns add inside
6) 将 vpp1insidehost 加入 netns
$ ip link set dev vpp1insidehost up netns inside
7) 在 netns 中给 vpp1insidehost 设置 IP
$ ip netns exec inside ip addr add 10.10.2.1/24 dev vpp1insidehost
8) 在 netns 中设置路由
$ ip netns exec inside ip route add 10.10.1.0/24 via 10.10.2.2
9) 在 vpp 中创建连接到 vpp1outside 的接口
vpp# create host-interface name vpp1outside
10) 在 vpp 中给 vpp1outside 设置 IP
vpp# set int ip address host-vpp1outside 10.10.1.2/24
vpp# set int state host-vpp1outside up
11) 在 vpp 中创建连接到 vpp1inside 的接口
vpp# create host-interface name vpp1inside
12) 在 vpp 中给 vpp1inside 设置 IP
vpp# set int ip address host-vpp1inside 10.10.2.2/24
vpp# set int state host-vpp1inside up
13) 在 vpp 中配置 nat 接口
vpp# nat44 add interface address host-vpp1outside
vpp# set interface nat44 in host-vpp1inside out host-vpp1outside
14) 在 host 中对 vpp1outsidehost 抓包
$ tcpdump -s 0 -i vpp1outsidehost -vv
15) 在 netns 中 ping host IP
$ ip netns exec inside ping -c 1 10.10.1.1
运行效果:
1)在 netns 中 ping 10.10.1.1
$ ip netns exec inside ping -c 1 10.10.1.1
PING 10.10.1.1 (10.10.1.1) 56(84) bytes of data.
64 bytes from 10.10.1.1: icmp_seq=1 ttl=63 time=26.1 ms
--- 10.10.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 26.088/26.088/26.088/0.000 ms
2)在 host 中对 vpp1outsidehost 抓包
$ tcpdump -s 0 -i vpp1outsidehost -vv
dropped privs to tcpdump
tcpdump: listening on vpp1outsidehost, link-type EN10MB (Ethernet), capture size 262144 bytes
15:19:48.964020 IP (tos 0x0, ttl 63, id 12594, offset 0, flags [DF], proto ICMP (1), length 84)
10.10.1.2 > bogon: ICMP echo request, id 53336, seq 1, length 64
15:19:48.964194 IP (tos 0x0, ttl 64, id 59361, offset 0, flags [none], proto ICMP (1), length 84)
bogon > 10.10.1.2: ICMP echo reply, id 53336, seq 1, length 64
可以看到,在 netns 中 ping 10.10.1.1 时,目标网口 vpp1outsidehost 收到的数据包的源 IP 是 vpp 中 host-vpp1outside 网口的 IP(10.10.1.2),而不是 netns 中 vpp1insidehost 的 IP (10.10.2.1)
参考资料:
1、VPP/Progressive VPP Tutorial - fd.io
2、VPP/NAT - fd.io