我在我的一台VPS上使用了飓风电动隧道,并没有完全运行。 我用一个基本上与此相同的脚本来build立隧道: http : //www.cybermilitia.net/2013/07/22/ipv6-tunnel-on-openvz/ ,只修改了我的特定设置。 我可以ping服务器,并从中获取网页,但是我从ping6得到以下输出:
root@unixshell:~# ping6 -c4 2001:470:1f0e:12a7::2 PING 2001:470:1f0e:12a7::2(2001:470:1f0e:12a7::2) 56 data bytes From 2002:d8da:e02a::1 icmp_seq=1 Destination unreachable: Address unreachable 64 bytes from 2001:470:1f0e:12a7::2: icmp_seq=1 ttl=63 time=96.4 ms 64 bytes from 2001:470:1f0e:12a7::2: icmp_seq=2 ttl=63 time=73.2 ms From 2002:d8da:e02a::1 icmp_seq=2 Destination unreachable: Address unreachable --- 2001:470:1f0e:12a7::2 ping statistics --- 2 packets transmitted, 2 received, +2 errors, 0% packet loss, time 1005ms rtt min/avg/max/mdev = 73.256/84.838/96.420/11.582 ms
在问题服务器上,运行tcpdump,我看到这与上面同时:
root@tektonic:~# tcpdump -n not port 22 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on venet0, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes 21:25:44.000024 IP 216.218.224.42 > 207.210.83.205: IP6 2002:cfd2:4a7c::1 > 2001:470:1f0e:12a7::2: ICMP6, echo request, seq 1, length 64 21:25:44.000094 IP 207.210.83.205 > 216.218.224.42: ICMP 207.210.83.205 protocol 41 port 0 unreachable, length 132 21:25:44.000629 IP 207.210.83.205 > 216.218.224.42: IP6 2001:470:1f0e:12a7::2 > 2002:cfd2:4a7c::1: ICMP6, echo reply, seq 1, length 64 21:25:45.020972 IP 216.218.224.42 > 207.210.83.205: IP6 2002:cfd2:4a7c::1 > 2001:470:1f0e:12a7::2: ICMP6, echo request, seq 2, length 64 21:25:45.021059 IP 207.210.83.205 > 216.218.224.42: ICMP 207.210.83.205 protocol 41 port 0 unreachable, length 132 21:25:45.021260 IP 207.210.83.205 > 216.218.224.42: IP6 2001:470:1f0e:12a7::2 > 2002:cfd2:4a7c::1: ICMP6, echo reply, seq 2, length 64 ^C 6 packets captured 6 packets received by filter 0 packets dropped by kernel
这里是我的iptablesconfiguration的相关部分:
root@tektonic:~# iptables --list | egrep '41|ipv6' ACCEPT ipv6 -- anywhere anywhere ACCEPT ipv6 -- anywhere anywhere
我意识到我可以停止使用iptables发送ICMP不可达消息,如下所述: 禁用ICMP不可达答复 ,但是这是一个次优的解决scheme。 任何想法如何解决实际问题,而无需挖掘内核源码?
错误消息的“端口0”部分是一个红色的鲱鱼。 6in4数据包只是一个ipv6数据包,前面加了一个ipv4头,因此在ipv4级没有端口号。 但是,发送的ICMP报文的types编号为3,编号为3,意为“端口不可达”,不是编码2,“协议不可达”。 这里是一个:
12:15:51.011697 IP 207.210.83.205 > 216.218.224.42: ICMP 207.210.83.205 protocol 41 port 0 unreachable, length 132 0x0000: 45c0 0098 8d6c 0000 4001 0f94 cfd2 53cd [email protected]. 0x0010: d8da e02a 0303 62fb 0000 0000 4500 007c ...*..b.....E..| 0x0020: 9157 4000 f829 145c d8da e02a cfd2 53cd .W@..).\...*..S. 0x0030: 6000 0000 0040 3a3b 2002 cfd2 4a7c 0000 `....@:;....J|.. 0x0040: 0000 0000 0000 0001 2001 0470 1f0e 12a7 ...........p.... 0x0050: 0000 0000 0000 0002 8000 aa6e 1022 0002 ...........n.".. 0x0060: ad8a c355 ce94 0a00 0809 0a0b 0c0d 0e0f ...U............ 0x0070: 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f ................ 0x0080: 2021 2223 2425 2627 2829 2a2b 2c2d 2e2f .!"#$%&'()*+,-./ 0x0090: 3031 3233 3435 3637 01234567
[更新2015-08-06]升级tb_userspace到版本18,没有变化。
[update 2015-08-09] tb_userspace.c line 163: sockv6 = socket(AF_INET, SOCK_RAW, IPPROTO_IPV6); ,并且lsof -c tb_userspace显示确实创build了套接字: tb_usersp 6614 root 4u raw 0t0 1559059549 CD53D2CF:0029->00000000:0000 st=07
[更新2015-08-09 17:18 PDT]确认在没有openvz的纯内核上存在同样的问题:
jcomeau@unixshell:~$ ping6 2001:470:66:79d::2 PING 2001:470:66:79d::2(2001:470:66:79d::2) 56 data bytes 64 bytes from 2001:470:66:79d::2: icmp_seq=1 ttl=60 time=86.5 ms From 2001:470:0:206::2 icmp_seq=1 Destination unreachable: Address unreachable 64 bytes from 2001:470:66:79d::2: icmp_seq=2 ttl=60 time=83.4 ms From 2001:470:0:206::2 icmp_seq=2 Destination unreachable: Address unreachable 64 bytes from 2001:470:66:79d::2: icmp_seq=3 ttl=60 time=86.1 ms From 2001:470:0:206::2 icmp_seq=3 Destination unreachable: Address unreachable ^C --- 2001:470:66:79d::2 ping statistics --- 3 packets transmitted, 3 received, +3 errors, 0% packet loss, time 2012ms rtt min/avg/max/mdev = 83.429/85.376/86.556/1.427 ms jcomeau@unixshell:~$ logout Connection to www closed. jcomeau@aspire:~$ uname -a Linux aspire 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64 GNU/Linux
还冲刷了iptables和ip6tables,并删除了所有的netfilter模块。 同样的症状。
来自http://linux.die.net/man/7/raw的 [update 2015-08-11 01:04]发现原始数据包被分派到任何原始套接字后,内核仍然会传递给任何原始套接字为该协议注册的模块。 我自己的上网本上的模块,是我testing的“没有openvz的原始内核”,是tunnel4。 一旦我删除它,目标不可达消息停止。 我假设相同的模块内置到我的VPS单片内核。 / proc / kallsyms不存在,所以我将不得不联系客户支持。
[更新2015-08-11 01:50] http://www.haifux.org/lectures/217/netLec5.pdf也是一个资源,也帮助。
正如在问题的更新中指出的那样,问题在于,在内核将数据包传递给正在侦听该协议的任何原始套接字后, 然后将其传递给为该协议注册的任何内核模块 。 既然我已经在我的上网本上使用了一个坐式隧道,即使我已经临时设置了tb_userspace隧道进行testing,但是tunnel4模块仍然被加载。 因为它已经被注册了,但是没有configuration处理程序,所以它拒绝了带有ICMP 3:3消息的数据包。 随后rmmod sit rmmod tunnel4解决了这个问题。
在原来的问题服务器上,这并不是那么容易,因为它是一个openvz VPS与客户端“盒”看到的单片内核。 但是用http://linux.die.net/man/7/raw和http://www.haifux.org/lectures/217/netLec5.pdf中的信息武装起来,我能够与提供者一起解决问题。 在这种情况下,他们重新安装了sit模块,所以我根本不必使用tb_userspace隧道软件。 但我怀疑问题是那个tunnel4也安装在那里。
它看起来像tektonic没有分配给它的venet0接口的地址2001:470:1f0e:12a7 :: 2。 它正在接收数据包,即使它们格式良好,也会拒绝它们。
您的下一步应该是validationtektonic可以build立到仅IPv6主机(例如ipv6.google.com)的TCP连接,并且数据包确实通过IPv4封装前往configuration的Hurricane Electric中继主机。 如果TCP通过但ICMP不通过,那肯定是一个端点过滤问题(即防火墙规则)。
ICMP错误是由内核发送的,因为没有套接字存在以接收具有该源和目标IP地址的特定组合的协议41分组。
如果进程使用协议41创build一个原始套接字,那么内核将停止产生ICMP错误。 这样的套接字默认会接收来自所有源IP的数据包发送到分配给本地机器的任何目标IP地址。 使用绑定和/或连接系统调用,应用程序可以限制将要接收的源和目标IP地址的组合。 不匹配任何这种套接字的数据包仍然会产生ICMP错误。
很明显,在你的情况下,数据包被隧道同时接收并产生ICMP错误。 但是根据我上面的描述,一个套接字接收到的数据包也不可能产生ICMP错误信息。 但是还有其他的方式可以接收数据包,这并不能阻止内核产生ICMP错误。
套接字可以在较低的协议层接收数据包,不pipeIP协议号如何,所有的数据包都是可见的。 如果您使用的隧道软件使用这样一个低级套接字来接收协议41数据包,那么ICMP错误就会像您在问题中所描述的那样产生。
如果这是隧道软件的function,那么我认为这是隧道软件的devise缺陷。 在这种情况下,你有三个select: