我在我的一个 VPS 上使用了 Hurricane Electric 隧道,但它没有完全工作。我使用与此脚本基本相同的脚本设置隧道: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
这是我的 iptables 配置的相关部分:
root@tektonic:~# iptables --list | egrep '41|ipv6'
ACCEPT ipv6 -- anywhere anywhere
ACCEPT ipv6 -- anywhere anywhere
我意识到我可以停止使用 iptables 发送 ICMP 不可达消息,如此处所述:禁用 ICMP 不可达回复,但这是一个次优的解决方案。关于如何在无需挖掘内核源代码的情况下解决实际问题的任何想法?
错误消息的“端口 0”部分是一条红鲱鱼。6in4 数据包只是一个带有 ipv4 标头的 ipv6 数据包,因此在 ipv4 级别没有端口号。但是,正在发送的 ICMP 数据包的类型号为 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,没有变化。
[更新 2015-08-09] tb_userspace.c第 163 行:sockv6 = socket(AF_INET, SOCK_RAW, IPPROTO_IPV6);
,并lsof -c tb_userspace
显示确实创建了套接字: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 模块。相同的症状。
[更新 2015-08-11 01:04] 来自http://linux.die.net/man/7/raw发现在将原始数据包发送到任何原始套接字后,内核仍会将其传递给任何为该协议注册的模块。我自己的上网本上的模块是我正在测试的“没有openvz的原始内核”,它是tunnel4。一旦我删除它,目标无法到达的消息就会停止。我假设我的 VPS 上的单片内核中内置了相同的模块。/proc/kallsyms 上不存在,所以我必须联系客户支持。
[2015-08-11 01:50 更新] http://www.haifux.org/lectures/217/netLec5.pdf也是一个有帮助的资源。