IPv6 VPN
暑假以来一直在做这个东西,希望找到一套合适的解决方案。这几天把找到的解决方案挨个实现了一遍(有的是别人实现的),写下本文供大家参考。
题目的“IPv6 VPN”是指“VPN over IPv6”,也就是跑在IPv6网络上的VPN,作为IPv4 over IPv6的一种实现形式,用于连接被IPv6网络分隔的IPv4孤岛,同时稍作修改也可以在VPN内实现纯IPv6网络或双栈网络。技术上难度并不大,主要是想法难得——我是在参与讨论yegle组织合租服务器时经winsty提醒想到的。最初的想法是客户端通过IPv6连接服务器,然后将服务器当作网关上网用。这就要求服务器运行双栈协议,可以经IPv6连接到客户端,同时又可以无限制的访问IPv4网络。这个想法并不隐含VPN,比如Cisco路由器、Solaris都自带IPv4 over IPv6隧道支持。最先成型的解决方案是IPv6直通车,基本原理是自己写了个小工具,监听IPv4指定端口,把数据通过IPv6转发出去,用OpenVPN建立IPv4 VPN。效率并不敢恭维,但稳定性无疑是最好的,成本也最低(对一个人而言)。之后就再也没有成型的解决方案了,需要我们DIY。VPN无疑是最自然的起点,目标就是让我在学校可以上网,服务器端用Linux,客户端既有Windows XP,又有Linux。
符合条件的服务器我找了一下,主要提供商有HE、FDCServers、Kimsufi等。需要说明的是从中国到美国西海岸有200ms左右的延迟,tcp三次握手,来回就是600ms,浏览网页还是能感受到的,到英国的话,单程要300ms+。中国似乎只有DNS3G一家提供IPv6网络。
HE提供的机器是
Ok, we've just added a new item to our price list of a "Green" Power Efficient Dedicated Server (Core 2 Duo processor with 2 GB of RAM and 500 GB HD) including an unlimited 100 Mbps (no traffic charges) port for $69/month $260 one time setup that could be used for you to run a tunnel over IPv6. Let me know if this interests you and then I'll have a sales person quote you. The IPv6 tunneling aspect of your service is a custom configuration which we will include for free.
FDCServers的最低价是$99/mon,Kimsufi可以开到£19.99/mon(是Ovh下属的一家公司,但只对英国人服务,在英国有亲戚朋友的可以考虑)。DNS3G从5K到数万不等(/year)。
后文假设已经找到了合适的服务器(没找到的可以发信给我,我给你找地方),并且在服务器上运行Linux系统(最好是debian),且基本熟悉Linux的各种管理工具。
jameszhang的基于IPv6的IPv4透明隧道建设尝试提出了一个非VPN的方案。这个方案的原理是在两个Linux机器上建立tap设备转发数据包,效率比起OpenVPN等使用tun设备的VPN要差一些,但省去加密,还是可以折平的。但一来出于“安全”考虑,我们必须要加密,二来这个方案完全不支持windows,故被我弃用。
接下来还是考虑基于VPN的方案。基于L2TP的VPN最近很热门,在无人区@寒水远山有详细叙述,已经被实现且正在为他们服务。但Windows XP却享受不到。
OpenVPN在数年之前就有过讨论是否添加对IPv6的支持,但终没有被加入到特性中,只有juanjo开发了一个udp6补丁。这个系列的补丁我尝试过(with Yangzhe1990),确实能在debian上跑起来,但却明确不支持windows,中间juanjo似乎与社区失去了联系。但这是我当时能找到的最好的解决方案,还是断断续续的跑了近1个月。现在,好消息是——juanjo已经回来了,受聘于Google并且将此作为他的“20% project”。在这里已经可以看到代码和编译好的binary。目前已经支持windows平台,debian sid的openvpn已经整合了这个补丁,ubuntu的deb包由Bernhard提供。
配置OpenVPN服务器的过程可参考这里。不同的是现在easy-rsa/下又分了1.0和2.0两套,我们需要的是2.0的,同时不需要ta.key。基本步骤大概如下所示:
1. 将examples复制到oepnvpn的配置文件目录,方便使用。
# cp -r /usr/share/doc/openvpn/examples /etc/openvpn
2. 将vars里的KEY_COUNTRY, KEY_PROVINCE, KEY_CITY, KEY_ORG及KEY_EMAIL参数改成自己的值。
# cd /etc/openvpn/examples/easy-rsa/2.0/
# vim ./vars
3.接下来设定服务器端:将vars的参数load到环境中,并将旧的key或设定清除,建立root certificate。
# source ./vars
# ./clean-all
# ./build-ca
完成后会在keys/下生成ca.crt和ca.key。
4. 建立服务器的证书。
# ./build-key-server server
server是指服务器的名字,完成后生成server.crt、server.csr和server.key。
5. 建立客户端的证书。
# ./build-key client
因为Windows客户端默认不支持密码,故建立的是无密码key。client指客户端的名字,完成后生成client.crt、client.csr和client.key。
6. 建立 Diffie Hellman parameters。
# ./build-dh
会生成dh{n}.pem。
今后若要添加客户端,则需重复source ./vars及5、6两步。
服务器端的/etc/openvpn目录下需要ca.crt/key、server.crt/key和dh{n}.pem(这几个文件直接放在/etc/openvpn下则后面的配置文件中不需要写路径),ca.crt、client.crt/key需要分发给客户端。
服务器端还需要server.conf,可以在examples/sample-config-files/server.conf基础上修改,将proto改用udp6或tcp6(udp6好一点);ca、cert、key、dh等填写刚刚建立的4个文件;取消push "redirect-gateway def1 bypass-dhcp"前的注释符号";"可以将客户端的默认路由改为经过server,不过最好不启用这个特性而令客户端自己配置路由。(OpenVPN的配置项较多,请仔细查看说明,不要全信我。)
客户端还需要client.conf,可由examples/sample-config-files/client.conf修改而来。
因为有些学校校园网可以免费访问教育网免费地址,所以我写了个addroute脚本为这些地址(更新到9月)添加路由(经过未连接VPN时的默认路由,仅限Linux),并将默认路由改为经过VPN,请看懂了再用。放在客户端的/etc/openvpn下,client.conf文件末尾加入
script-security 2
up ./addroute_cernet.sh
可以令其在建立连接后自动运行。Windows下的配置兹不详述。
tinc其实是比OpenVPN历史更悠久的一个VPN解决方案,也是我目前正在使用的方案,相比之下,tinc比OpenVPN占用资源更少,但效率不若OpenVPN,启用压缩后更是大幅下降。原本它的IPv6支持在Windows XP上是跑不起来的,经过我提交bug之后,终于在新版本中跑起来了。
Linux下的配置过程可见Documents和tinc manual,Windows下直接按Example来就行了。概括地说,每个机器需要一个tinc.conf文件(tinc运行需要的参数都在里面),一个tinc-up文件(配置IP地址和路由,Windows不使用),一套host文件(相当于OpenVPN的证书)。由于有OpenVPN的C/S结构先入为主,配置TInc时走了不少弯路。这里区别两种概念:OpenVPN的服务器端是VPN的核心节点;而tinc并不区分服务器端和客户端,它的本意是连接两个子网。我们把“服务器端”当作网关,就要令服务器的子网是0.0.0.0/0(即全世界),而令客户端的子网是x.x.x.x/32(即只有一台机器)。
tinc.conf大概将是这个样子:
Name = oldtai
ConnectTo = bjork
Device = /dev/net/tun
AddressFamily = ipv6
Compression = 0
最后两行指明用ipv6连接(不指明仍然不监听IPv6端口,应该是bug),取消压缩。Windows客户端不使用Device一项。
服务器端与客户端的配置文件并不是相同的。服务器端的tinc.conf没有ConnectTo项,因为服务器不连接其他子网;hosts/下给建立一个代表自身的host文件,其中Address可以不写,Subnet应填写"0.0.0.0/0",再给每个客户端建立一个host文件。客户端tinc.conf要写“ConnectTo 服务器名”,hosts/下只需要代表自身和代表服务器的host文件,代表服务器的host文件中Address要写服务器的外网IP(应该是个IPv6地址),Subnet应填写"x.x.x.x/32"其中"x.x.x.x"是服务器在VPN内的IP。
tinc没有OpenVPN那样的DHCP支持,需要在tinc-up脚本中用"ifconfig $INTERFACE x.x.x.x netmask 255.255.255.0"配置IP。在客户端,x.x.x.x应该与host文件中的Subnet指定的IP相同;在服务器端则是与客户端的代表服务器的host文件中的Subnet相同。上面添加教育网免费地址路由的addroute脚本可以合并入tinc-up,不过最后一行的$1应改为$INTERFACE。
其他的问题如isatap隧道、tun设备、iptables、NAT等兹不详述。其要点在于加载tun模块(/etc/modules),NAT(iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE)。整套方案的基础是IPv6网络无限制,将来IPv6普及之后,可用性不明。目前遗留的问题包括在Windows上自动添加路由、isatap相关的配置等。
29 Responses
还没上过v6的网络,很想上去玩玩~
Reply
今天心血来潮,G了一下IPv6,第一篇居然是兄台的,Mark了。
Reply
我最终还是重装了,打算自己再来一遍!可是却还是失败!
以下是我的步骤!请博主指导!麻烦了
apt-get install openvpn
cp -r /usr/share/doc/openvpn/examples /etc/openvpn
cd /etc/openvpn/examples/easy-rsa/2.0/
vim ./vars
source ./vars
./clean-all
./build-ca(一路按回车)
./build-key-server server(一路按回车,2个Y)
./build-key mofei(一路按回车,2个Y)
./build-dh(生成dh1024.pem)
复制ca.crt/key、server.crt/key和dh{n}.pem至/etc/openvpn目录下
修改examples/sample-config-files/server.conf文件ca、cert、key、dh为我刚刚建立的4个文件,取消push "redirect-gateway def1 bypass-dhcp"前的注释符号,传至/etc/openvpn/目录下
修改examples/sample-config-files/client.conf文件里的IP、cert、key,下载本地改名为mofei.opvn
目前本地有mofei.opvn,mofei.crt,mofei.key,ca.crt
编辑了/etc/sysctl.conf文件,去掉了net.ipv4.ip_forward=1的注释,SSH里运行sysctl -p使其生效
我的步骤就到这里,失败
与你之前帮我配置的相比较
在/etc/openvpn/目录里少了ta.key,server.down,server.up 三个文件
并且客户端mofei.opvn的最下面多了以下类似的命令
rcvbuf 65536
mssfix 1472
explicit-exit-notify 3
max-routes 1163
route 1.12.0.0 255.252.0.0 net_gateway 5
route 1.24.0.0 255.248.0.0 net_gateway 5
route 1.45.0.0 255.255.0.0 net_gateway 5
route 1.48.0.0 255.252.0.0 net_gateway 5
route 1.56.0.0 255.248.0.0 net_gateway 5
route 1.68.0.0 255.252.0.0 net_gateway 5
route 1.80.0.0 255.240.0.0 net_gateway 5
请博主指教哪里不对
麻烦博主了
Reply
没有不正确的。
ta.key是tls-auth key,可以不用;server.up/down是我写的添加iptables规则的脚本,写在别的地方也行;客户端里的rcvbuf和mssfix属于小优化,route开头的是添加中国IP的路由令其不经过VPN。
Reply
额...没有不正确的?可是我却连不上!我把日志发你邮箱了!麻烦您看看我这个是怎么回事吧!很抱歉这样的打扰您,但我真想自己把他搞起来,以后重搞也方便!
Reply
非常感谢博主!中科大的高材生!有知识就是好啊!
真的非常感谢!
我想自己在去学着配置一下!但又害怕配置不成功!
看了下客户端里的内容!貌似和我之前网上看到的里面的内容有点差别!
不知道能不能指点一翻
Reply
阁下,你好。
我按照你的文章进行实验,却怎么也不成功。
我想连接两台主机。
主机 c
Address = 2001:da8:8007:4a2:224:8cff:fe64:132e
Subnet = 10.0.0.0/24
主机 s
Address = 2001:da8:8007:1358:172:18:58:8
Subnet = 10.0.0.0/24
启动服务后两台主机均生成 tun 设备。但是没有 IPv4 地址(貌似tinc-up没起作用)。
我就手动配置s和c的tun设备。tuns 10.0.0.1/24 tunc 10.0.0.2/24。
但是二者无法 ping 通。
搞了好长时间,都没有成功。还请阁下不吝赐教。
谢谢。
Reply
@海涛涛, c和s必须代表不同的子网。
Reply
@WindyWinter,
果然。谢谢阁下啦。
Reply
@WindyWinter,
阁下,我用的ubuntu server lucid。为什么我的tinc-up不起作用呢?
每次都要手动配置IP地址。
Reply
不清楚。export一下$INTERFACE,然后手动执行tinc-up,看有没有问题。
Reply
谢谢了。问题找到了,tinc-up没有x权限,悲剧……
Reply
其实单纯 vpn 的话可以使用交换机模式,这样会建立普通的虚拟网卡设备。
效果就如同在两台电脑之间又联了一条网线一样,可以实现 6on4,4on6,6on6和4on4 等
各种vpn。
Reply
switch模式使用tap设备,不如tun设备(router模式)效率高。
Reply
楼主 你有ipv6的vpn吗?除了直通车以外 我想购买联系我邮箱吧
Reply
我不出售。请联系http://yegle.net/openvpn或http://eduvpn.com
Reply
http://eduvpn.com
基于openvpn的实现方案,现在有一个非正式的支持ipv6的patch了……
Reply
而tinc并不区分服务器端和客户端,它的本意是连接两个子网。我们把“服务器端”当作网关,就要令服务器代表0.0.0.0/0(即全世界),而令客户端代表x.x.x.x/32(即只有一台机器)
-----------------------------------
对于ipv6 ,也是如此吗?
怎么这里貌似不是这样
http://tinc-vpn.org/examples/ipv6-network/
谢谢
Reply
这里讲的是IPv4 over IPv6,tinc的Example讲的是IPv6 over IPv4。
Reply
你好,我昨天按
http://tinc-vpn.org/examples/ipv6-network/
以及阁下的文章
在win7下配了下tinc,发现tinc.vpn服务无法启动,
信息为
“tinc.vpn启动后自动停止,某些服务在未有其他程序使用时将自动停止”
并且我的TAP-Win32 Adapter也一直显示为断开状态
我所应用的场所是这样的
我有一台电脑A只有ipv6网络(主要ipv6是免费的,ipv4要收钱),系统为win7 和linux,
另外一台服务器B有ipv6和ipv4网络,系统为windows sever 2003,
A,B两台机器可以通过ipv6连接,
我现在A想用tinc通过B连接到ipv4网络,
我现在的A:
tinc.conf:
Name = home
ConnectTo = 2001:da8:d800:75:215:17ff:fe89:52c8
Interface = VPN
AddressFamily = ipv6
Compression = 0
hosts,名字为home,内容为:
Subnet = 2001:db8:beef::/48
服务器B:
tinc.conf:
Name = lab408
Interface = VPN
AddressFamily = ipv6
Compression = 0
hosts,名字为lab408,内容为:
Subnet = 2001:db8:beef:0::/64
请问我的以上配置那些地方有错,你能否指导我一下
非常感谢~~
Reply
ConnectTo项填的是节点的名字而非地址。根据你要实现的目标,你应该选用IPv4 over IPv6的方式而非IPv6 over IPvX。
Reply
谢谢!
是不是应该这样?
机器A:
tinc.conf
Name = home
ConnectTo = lab408
Interface = VPN
AddressFamily = ipv6
Compression = 0
hosts:home:
Subnet = 10.20.40.1/32
服务器B:
tinc.conf
Name = lab408
Interface = VPN
AddressFamily = ipv6
Compression = 0
hosts:home:
Subnet = 0.0.0.0/0
疑问一:
Connectto使用的是名字而不是ip,如果两台机器不是在同一局域网,他们是如何能连接上的,因为我没看到哪里能够指定服务器ip的选项
还有一个疑问就是,我按tinc的exmaple
http://www.tinc-vpn.org/examples/windows-install/
貌似那里没有Address这一项,而您的文章中却有提到,这一项是否必要
ps:看了下你的页面,发现你也是USTCer,我在网络方面比较小白,还请师兄指教(我已经google了不少,但都没能解决,哎,菜啊)
Reply
“节点名”就是host文件名,host文件中用Address指明该节点的地址。也就是上文中的
Reply
啊,现在真是"后生可畏",
我大概猜到你是谁了,
应该是谢谢了,我再试下,不行的话可能还要问你
Reply
就是说,服务器端和客户端两者hosts下的文件的配置不一样,主机端hosts下主机的Subnet为0.0.0.0/0而到了客户端则要把服务端的文件Subnet修正为如10.20.40.2/32形式,同理服务端下客户端的内容要详细些形如Address = 2001:da8::1,Subnet = 10.20.40.1/32,而客户端一方的客服端配置只需Subnet = 10.20.40.1/32就可了。不知理解是否有误,另外,两者tincd -n vpn -K都产生公钥,只要其中之一么?谢谢
Reply
没法读懂你的问题,“服务器端”、“客户端”、“主机端”、“服务端”、“服务端下客户端”、“客服端”……
Reply
参照heiyeliu的,office方 hosts下有两个配置文件,home方也有。这两者的配置不太一样。
office方hosts下
office: {office:Subnet = 0.0.0.0/0 ; home:Subnet = 10.20.40.1/32, Address = 2001:da8::XXXX}.而在home方的hosts下
home:{home:Subnet = 10.20.40.1/32;office:Subnet = 10.20.40.2/32,Address = 2001:da8::YYYY}
.tincd -n vpn -K产生的双方的公钥,采用哪一个呢?
谢!
Reply
为什么张老师的方案不支持Windows?如果把那两台互联的机器作为网关是否可行呢?
Reply
Windows对Tap设备的支持没有Linux那么好。在Windows上做并非不可行。
Reply
Top Seven
Recent Comments
Categories
Blogroll
Login
Sponsor