Networking 从网络命名空间Ping外部IPv6地址

Networking 从网络命名空间Ping外部IPv6地址,networking,ipv6,linux-containers,Networking,Ipv6,Linux Containers,我需要从网络名称空间访问外部IPv6地址 在我的主机中,我设置了一个SIT隧道(IPv6-In-IPv4),用于对IPv6数据包进行隧道传输,并通过默认接口(eth0)发送。SIT隧道依赖于飓风电力隧道经纪服务。我可以从主机ping外部IPv6地址 $ ping6 ipv6.google.com PING ipv6.google.com(lis01s13-in-x0e.1e100.net) 56 data bytes 64 bytes from lis01s13-in-x0e.1e100.net

我需要从网络名称空间访问外部IPv6地址

在我的主机中,我设置了一个SIT隧道(IPv6-In-IPv4),用于对IPv6数据包进行隧道传输,并通过默认接口(eth0)发送。SIT隧道依赖于飓风电力隧道经纪服务。我可以从主机ping外部IPv6地址

$ ping6 ipv6.google.com
PING ipv6.google.com(lis01s13-in-x0e.1e100.net) 56 data bytes
64 bytes from lis01s13-in-x0e.1e100.net: icmp_seq=1 ttl=57 time=98.1 ms
64 bytes from lis01s13-in-x0e.1e100.net: icmp_seq=2 ttl=57 time=98.7 ms
以下是有关隧道的一些详细信息:

$ ip -6 route sh
2001:470:1f14:10be::/64 dev he-ipv6  proto kernel  metric 256
default dev he-ipv6  metric 1024
有趣的部分来了。出于超出本问题范围的原因,我需要在网络名称空间中执行相同的操作(pingipv6.google.com)

以下是我如何创建和设置网络名称空间:

ns1.sh

#!/bin/bash

set -x

if [[ $EUID -ne 0 ]]; then
   echo "You must run this script as root."
   exit 1
fi

# Create network namespace 'ns1'.
ip netns del ns1 &>/dev/null
ip netns add ns1

# Create veth pair.
ip li add name veth1 type veth peer name vpeer1

# Setup veth1 (host).
ip -6 addr add fc00::1/64 dev veth1
ip li set dev veth1 up

# Setup vpeer1 (network namespace).
ip li set dev vpeer1 netns ns1
ip netns exec ns1 ip li set dev lo up
ip netns exec ns1 ip -6 addr add fc00::2/64 dev vpeer1
ip netns exec ns1 ip li set vpeer1 up

# Make vpeer1 default gw.
ip netns exec ns1 ip -6 route add default dev vpeer1

# Get into ns1.
ip netns exec ns1 /bin/bash --rcfile <(echo "PS1=\"ns1> \"")
但是,如果我尝试ping外部IPv6地址:

ns1> ping6 2a00:1450:4004:801::200e
PING 2a00:1450:4004:801::200e(2a00:1450:4004:801::200e) 56 data bytes
^C
--- 2a00:1450:4004:801::200e ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1008ms
所有数据包都丢失了

我用tcpdump打开了veth1,检查了发生了什么。我看到的是邻居请求数据包正在到达接口。这些数据包正在尝试解析IPv6目标地址的MAC地址:

$ sudo tcpdump -qns 0 -e -i veth1
IPv6, length 86: fc00::2 > ff02::1:ff00:200e: ICMP6, neighbor solicitation,
   who has 2a00:1450:4004:801::200e, length 32
IPv6, length 86: fc00::2 > ff02::1:ff00:200e: ICMP6, neighbor solicitation,
   who has 2a00:1450:4004:801::200e, length 32
我真的不明白为什么会这样。我也在主机中启用了IPv6转发,但没有效果:

$ sudo sysctl -w net.ipv6.conf.default.forwarding=1
谢谢你阅读这个问题。建议(欢迎:)

编辑:

主机中的路由表:

2001:470:1f14:10be::/64 dev he-ipv6  proto kernel  metric 256 
fc00::/64 dev veth1  proto kernel  metric 256 
default dev he-ipv6  metric 1024
我在主机中添加了一个NDP代理,用于解决NDP请求。仍然无法从nsnet访问该地址(查看此信息):

ULA是不可路由的 您已为网络名称空间指定了唯一的本地地址(fc00::2):此IP地址在全球internet中不可路由,但只能在本地网络中路由

当您的ISP收到来自此地址的ICMP数据包时,它将丢弃该数据包。即使此数据包成功到达ipv6.google.com,它也不可能将答案发送回您,因为对于此IP地址

路由表问题(NDP通知) 您会收到NDP通知,因为这一行:

ip netns exec ns1 ip -6 route add default dev vpeer1
它告诉内核(在网络中)所有的IP地址都是在
vpeer1
接口上直接连接的。内核认为这个IP地址存在于以太网链路上:这就是它试图用NDP解析其MAC地址的原因

相反,您想说它们可以通过给定的路由器访问(在您的情况下,路由器就是您的主机):

解决 您可以:

  • 公共IPv6地址(您的公共IPv6前缀)关联到您的网络,并在主机上为此地址设置NDP代理

  • 将IPv6前缀设置为子网,并将子网路由到主机(如果可以)

  • 使用NAT(坏的,丑陋的,不要那样做)

您应该能够通过以下方式实现第一个目标:

#!/bin/bash
set -x

myipv6=2001:470:1f14:10be::42
peeripv6=2001:470:1f14:10be::43

#Create the netns:
ip netns add ns1

# Create and configure the local veth:
ip link add name veth1 type veth peer name vpeer1
ip -6 address add $myipv6/128 dev veth1
ip -6 route add $peeripv6/128 dev veth1
ip li set dev veth1 up

# Setup vpeer1 in the netns:
ip link set dev vpeer1 netns ns1
ip netns exec ns1 ip link set dev lo up
ip netns exec ns1 ip -6 address add $peeripv6/128 dev vpeer1
ip netns exec ns1 ip -6 route add $myipv6/128 dev vpeer1
ip netns exec ns1 ip link set vpeer1 up    
ip netns exec ns1 ip -6 route add default dev vpeer1 via $peeripv6

# IP forwarding
sysctl -w net.ipv6.conf.default.forwarding=1

# NDP proxy for the netns
ip -6 neigh add proxy $myipv6 dev veth1
ULA是不可路由的 您已为网络名称空间指定了唯一的本地地址(fc00::2):此IP地址在全球internet中不可路由,但只能在本地网络中路由

当您的ISP收到来自此地址的ICMP数据包时,它将丢弃该数据包。即使此数据包成功到达ipv6.google.com,它也不可能将答案发送回您,因为对于此IP地址

路由表问题(NDP通知) 您会收到NDP通知,因为这一行:

ip netns exec ns1 ip -6 route add default dev vpeer1
它告诉内核(在网络中)所有的IP地址都是在
vpeer1
接口上直接连接的。内核认为这个IP地址存在于以太网链路上:这就是它试图用NDP解析其MAC地址的原因

相反,您想说它们可以通过给定的路由器访问(在您的情况下,路由器就是您的主机):

解决 您可以:

  • 公共IPv6地址(您的公共IPv6前缀)关联到您的网络,并在主机上为此地址设置NDP代理

  • 将IPv6前缀设置为子网,并将子网路由到主机(如果可以)

  • 使用NAT(坏的,丑陋的,不要那样做)

您应该能够通过以下方式实现第一个目标:

#!/bin/bash
set -x

myipv6=2001:470:1f14:10be::42
peeripv6=2001:470:1f14:10be::43

#Create the netns:
ip netns add ns1

# Create and configure the local veth:
ip link add name veth1 type veth peer name vpeer1
ip -6 address add $myipv6/128 dev veth1
ip -6 route add $peeripv6/128 dev veth1
ip li set dev veth1 up

# Setup vpeer1 in the netns:
ip link set dev vpeer1 netns ns1
ip netns exec ns1 ip link set dev lo up
ip netns exec ns1 ip -6 address add $peeripv6/128 dev vpeer1
ip netns exec ns1 ip -6 route add $myipv6/128 dev vpeer1
ip netns exec ns1 ip link set vpeer1 up    
ip netns exec ns1 ip -6 route add default dev vpeer1 via $peeripv6

# IP forwarding
sysctl -w net.ipv6.conf.default.forwarding=1

# NDP proxy for the netns
ip -6 neigh add proxy $myipv6 dev veth1

事实上,这甚至不是一个有效的ULA,因为它位于保留给全球权威机构分配的部分(目前还不存在)。只有
fd00::/8
中的地址才允许在本地分配,并且它们必须使用随机生成的40位全局ID。对此进行了解释。@RonMaupin,确实如此。最后,我通过1)为veth对使用真实IPv6专用地址()2)在veth1中Natting传出数据包解决了问题(ip6tables-t nat-A POSTROUTING-o veth1-j伪装)。虽然没有人能提供比nat更好的解决方案,但我把这个答案作为接受答案。@DiegoPino,nat实际上破坏了IPv6中的内容。虽然NAT66有一个RFC,但它被标记为实验性的,因此它是“自担风险使用”无法保证RFC会进入标准轨道,或者如果它进入了标准轨道,它将与现在一样。我只是不认为有任何理由在IPv6上进行NAT。你破坏了IPv6恢复的真正端到端IP连接。NAT是由于IPv4地址不足而添加到IP的一个难题,IPv6不存在NAT,因此NAT不可用essary@ysdx感谢您更新答案。关于生成NDP ns数据包的原因的解释非常有趣。脚本运行良好,我可以从名称空间ping::2和外部IPv6地址。实际上,这甚至不是有效的ULA,因为它位于保留给全局授权机构分配的部分(它还不存在)。只有
fd00::/8
中的地址才允许在本地分配,并且它们必须使用随机生成的40位全局ID。对此进行了解释。@RonMaupin,确实如此。最后,我通过1)为veth对使用真实的IPv6专用地址()2)在veth1中Natting传出数据包解决了问题(ip6tables-t nat-A POSTROUTING-o veth1-j伪装)
#!/bin/bash
set -x

myipv6=2001:470:1f14:10be::42
peeripv6=2001:470:1f14:10be::43

#Create the netns:
ip netns add ns1

# Create and configure the local veth:
ip link add name veth1 type veth peer name vpeer1
ip -6 address add $myipv6/128 dev veth1
ip -6 route add $peeripv6/128 dev veth1
ip li set dev veth1 up

# Setup vpeer1 in the netns:
ip link set dev vpeer1 netns ns1
ip netns exec ns1 ip link set dev lo up
ip netns exec ns1 ip -6 address add $peeripv6/128 dev vpeer1
ip netns exec ns1 ip -6 route add $myipv6/128 dev vpeer1
ip netns exec ns1 ip link set vpeer1 up    
ip netns exec ns1 ip -6 route add default dev vpeer1 via $peeripv6

# IP forwarding
sysctl -w net.ipv6.conf.default.forwarding=1

# NDP proxy for the netns
ip -6 neigh add proxy $myipv6 dev veth1