这几天一直折腾没啥意义的IPv6,首先是看到了 @蔓舞寻樱 dalao 的文章:利用代理隧道接入HE.net的IPv6网,就顺便在阿里云的学生优惠服务器上尝试部署了一下,拿到了前缀 2001:470:36:a90,前缀长度为 64 的 IPv6 地址池,就是这个速度实在是比较尴尬 _(:3」∠)_,从青岛阿里云到江苏教育网的 MTR 输出大致这样 (╯-_-)╯╧╧

                             My traceroute  [v0.85]
ntzyz-aliyun (::)                                      Sat Sep 24 14:46:35 2016
Keys:  Help   Display mode   Restart statistics   Order of fields   quit
                                       Packets               Pings
 Host                                Loss%   Snt   Last   Avg  Best  Wrst StDev
 1. zhangyuze320602-1.tunnel.tserv25  0.0%    10  408.3 408.8 408.1 410.3   0.5
 2. 10ge1-6.core1.sin1.he.net         0.0%    10  400.0 405.3 399.7 409.9   4.5
 3. 10ge1-16.core1.hkg1.he.net        0.0%    10  432.5 438.2 432.0 464.2   9.7
 4. 100ge10-1.core1.tyo1.he.net       0.0%    10  484.9 488.1 484.5 494.7   4.0
 5. 10ge1-13.core1.lax2.he.net        0.0%    10  584.6 590.1 583.7 600.6   6.2
 6. cngi-bjix-as-ap-as23911.10gigabi 77.8%    10  587.2 587.2 587.2 587.3   0.0
 7. 2001:252:0:302::1                 0.0%    10  731.0 730.9 730.4 731.2   0.0
 8. 2001:252:0:100::1                88.9%    10  729.8 729.8 729.8 729.8   0.0
 9. 2001:252:0:1::1                  11.1%    10  729.7 729.5 729.2 730.0   0.0
10. 2001:da8:1:1006::2               11.1%    10  736.0 734.4 731.6 739.2   2.4
11. 2001:da8:257:0:101:4:19:11        0.0%    10  727.7 738.3 727.7 776.6  16.0
12. 2001:da8:257:0:101:4:1:5          0.0%    10  727.4 727.9 727.4 728.6   0.0
13. 2001:da8:257:0:101:4:1:2          0.0%    10  736.9 736.5 732.0 739.8   2.4
14. ???
15. 2001:da8:257:0:101:4:67:e         0.0%     8  756.8 758.2 756.8 766.4   3.2
16. 2001:da8:257:0:101:4:67:1        12.5%     8  762.1 762.4 761.9 763.5   0.4
17. 2001:da8:1:504::2                 0.0%     8  768.0 766.4 765.0 768.2   1.1
18. cernet2.net                      12.5%     8  767.5 768.0 767.5 768.5   0.0
19. 2001:da8:1008:500::2              0.0%     7  767.0 767.2 766.7 767.8   0.0
20. 2001:da8:1008:20::1              16.7%     7  788.4 774.2 770.0 788.4   7.9
21. 2001:da8:1008:1030:bdd2:aba0:a20  0.0%     7  816.3 791.0 770.0 831.8  26.6

不过再怎么说也算是有了自己的 IPv6 地址了(这延迟这速度能用?)。但是这手里有这么多 IPv6 地址不搞点什么也真是太浪费了,所以想到的问题就是,有没有什么简单的办法,能让任意设备接入这个隧道?

首先想到的是使用 sit 隧道,直接借助 6in4 实现这个功能,但是实际上这个隧道在很多时候不可用(比如防火墙不允许 6in4 流量),同时两端的 IPv4 地址必须指定,不是很灵活(虽然几个脚本就能解决但是我懒),遂放弃 sit 隧道。

再然后想到的就是虚拟专用网络了,VPN 可以通过互联网传递内网信息,因为可以通过这项技术来加密流量并改变出口,VPN 也被大范围的拿来用作科学上网的工具。此处我只是需要试验一下这个思路是否可行,所以只搭建了简单而并不算安全的 PPTP VPN。我使用的服务器安装的系统为 Ubuntu 14.04.5 LTS,其他发行版操作也是类似的。首先安装 pptpd

sudo apt install -y pptpd

安装完成后,修改几个配置文件,印象里要编辑的就是 /etc/ppp/chap-secrets, /etc/ppp/pptpd-options 和 /etc/pptpd.conf,这些在网上都有大量的教程,我就不赘述了(其实还是懒)。通常的安装步骤都需要编辑 /etc/sysctl.conf 来启用 IPv4 Forward 功能并编辑 iptables 的 NAT 表,来实现转发 IPv4 数据包的功能,但是我并不打算用这个隧道走 IPv4 流量,这些步骤就可以忽略不看了。

配置完成后,就可以在 Windows 下的网络和控制中心中创建一个新的 VPN 连接来测试一下,协议类型选择 PPTP,身份验证选 MS-CHAPv2。创建完成后连接,如果没有其他问题就能成功联通,获得了一个 IPv4 地址(同时你会发现你上不了网了2333)。如果出现其他问题,可以参照 /var/log/syslog 和 Windows 下的错误代码,面向 Google 进行调试。

下面就是如何让这个 PPTP 支持 IPv6 了。首先,我们要修改一下 /etc/ppp/pptpd-options,在文件最后添加一些内容:

cat >> /etc/ppp/pptpd-options << EOF
ipparam pptpd
ipv6 ,
EOF

然后就是安装 radvd (Linux IPv6 Router Advertisement Daemon):

sudo apt install -y radvd

完成后,你需要创建一个脚本,他们会在每个 ppp 连接建立之后运行,来完成 IPv6 相关的设置。首先是 /etc/ppp/ipv6-up.d/radvd,你需要将其中的 IPv6 地址(2001:470:35:a90)换成你自己的地址:

#!/bin/sh
if test $PPP_IPPRARM != pptpd ;then
        exit 0
fi

ADDR=$(echo $PPP_REMOTE | cut -d : -f 3,4,5,6)

if test x$ADDR == x ; then
        echo "Unable to generate IPv6 Address"
        exit 0
fi
ADDR=2001:470:35:a90:$ADDR

#add route
route -6 add $ADDR/128 dev $PPP_IFACE

#generate radvd config
RAP=/etc/ppp/ipv6-radvd/$PPP_IFACE
RA=$RAP.conf

cat <<EOF >$RA
interface $PPP_IFACE{
        AdvManagedFlag off;
        AdvOtherConfigFlag on;
        AdvSendAdvert on;
        MinRtrAdvInterval 5;
        MaxRtrAdvInterval 100;
        UnicastOnly on;
        AdvSourceLLAddress on;
        prefix 2001:470:35:a90::/64 {};
};
EOF

#start radvd
/usr/sbin/radvd -C $RA -p $RAP.pid

#start tchdpd
/usr/sbin/tdhcpd \n --dns-server=2001:470:20::2 \n --dns-name=$PPP_IFACE.tunnel.ipv6.icybear.net \n --pid-file=$RAP.dhcp.pid \n --local-id=tunnel.ipv6.icybear.net -L debug\n $PPP_IFACE

#update dns
ARPA=$(ipv6_rev $ADDR)
nsupdate << EOF
update delete $ARPA
update add $ARPA 10 ptr $PPP_IFACE.tunnel.ipv6.icybear.net
send
update delete $PPP_IFACE.tunnel.ipv6.icybear.net
update add $PPP_IFACE.tunnel.ipv6.icybear.net 10 aaaa $ADDR
send
EOF

exit 0

再然后是 /etc/ppp/ipv6-down.d/radvd:

#!/bin/sh

RAP=/etc/ppp/ipv6-radvd/$PPP_IFACE

kill `cat $RAP.pid` || true
kill `cat $RAP.dhcp.pid` || true

rm -f $RAP.*

ADDR=$(echo $PPP_REMOTE | cut -d : -f 3,4,5,6)
ADDR=2001:470:35:a90:$ADDR
ARPA=$(ipv6_rev $ADDR)

nsupdate << EOF
update delete $ARPA
send
update delete $PPP_IFACE.tunnel.ipv6.icybear.net
send
EOF

exit 0

最后,给他们可执行权限并重启 pptpd:

chmod +x /etc/ppp/ipv6-*.d/radvd
systemctl restart pptpd.service

不出意外的话,再进行 PPTP 连接后,你就可以获得一个 IPv6 地址啦但是他真的非常慢(废话)

完成这个 IPv6 Over PPTP 后,我开始有些奇怪的想法:由于阿里云的 IPv6 地址池是走的 sit 隧道,速度非常慢,同时 Linode 机房可是有原生的 IPv6 支持的,所以如果先开一个 ticket 给自己的 Linode 搞到一个 V6 地址池,并把这个 PPTP 放到 Linode 上,会不会好很多呢?(望天)于是我准备试一下,但是装 PPTP 的时候出现了问题:

Setting up pptpd (1.4.0-7ubuntu0.1) ...
Job for systemd-modules-load.service failed because the control process exited with error code. See "systemctl status systemd-modules-load.service" and "journalctl -xe" for details.
dpkg: error processing package pptpd (--configure):
 subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
 pptpd
E: Sub-process /usr/bin/dpkg returned an error code (1)

查了一下似乎是 Ubuntu 的新 Bug(掀桌)。既然是 bug 那么想必过一段时间就会修复。其实在 Linode 上跑 PPTP 是一件十分不安全的事儿(GFW is watching you)搞不好自己的服务器就被搞了那还玩个什么鬼,所以觉得是时候用 OpenVPN 代替 PPTP,使用 OpenVPN over Shadowsocks 来获得一个 IPv6 地址,但是似乎吃力不讨好啊……

所以还是勉强接受了这个国内的 PPTP 隧道了(躺地