最近一直在用OpenVPN通过IPv6将连接到我的linode服务器进行科学上网和免流量。然后要上图书馆查文献的时候又需要关了OpenVPN,倍感麻烦。一开始是在自己电脑上加路由表,但是觉得这样也不方便,不同网络环境还要写不同脚本。然后自己校内还有一堆可以面流量的服务器,于是就像自己做一个PPTP的网关,我通过PPTP连接到校内的服务器,然后校内的服务器作为网关再智能选择走国内学校自带的线路还是走OpenVPN连接到外网。这个拓扑图大概是这样:

user<--PPTP 192.168.8.0/24--->校内服务器<----正常上网 10.*.*.*---->Internet
					^
					|
			      OpenVPN
				   IPv6
			   192.168.5.0/24
				 	|
					|
					v
				国外服务器

拓扑就是这样的,关键的节点在校内服务器上,这个节点作为PPTP的服务器,还要肩负数据包选路由,NAT的任务。

配置PPTP

这一点和之前的都一样,唯一不同的是不要输防火墙的nat指令。只要保证用户能够正常PPTP连接到你的服务器就好了。

配置OpenVPN

OpenVPN的配置上也是一样,相关教程一大堆。但是在服务器端的配置文件里不要加上push "redirect-gateway def1 bypass-dhcp"这句话,加上这句话之后会把所有流量都定位到了国外的服务器上,这样智能选路由的目的就不能达到了。

智能选择路由

智能选择路由上,只要根据目标地址选择对应的网关就好了,在校内服务器的路由表上进行配置就好了。V站上的人推崇chnroutes,他会自动从APNIC去下载ipv4网络段归属国家,然后使用python chnroutes.py -p linux,生成能在linux下执行的脚本。可能是我用的是Ubuntu Desktop版本,路由表效率非常低,chnroutes生成出来的路由表有7k多条路由,实在多的令人发指。没几天就把我服务搞崩溃了(也有可能是我在服务器上开了个MC的服务器,把磁盘读坏了,只能重装系统)。 这次吸取教训,没有用Desktop版本服务器,使用的是Server版本服务器。路由表也没有用chnroutes,使用的是bestroutetb来进行路由表转发工作。路由表少了很多很多,大概只有1700多条。作者有证明,虽然看不懂,但是还是觉得很高大上的样子。 bestroutetb也是有点问题,生成的脚本没有chnroutes那么好用,要是路由表里面有相同的路由,脚本执行就会终止,期待作者在下一个版本进行改进。

使用iptables配置NAT

折腾完路由,就要开始折腾NAT了。之前想过这个事,没想明白iptables根据不同的网卡出口自动进行NAT。后来看了这篇文章里面的那张图,然后查了一下man手册看明白了。要实现数据包根据出口自动NAT,只要把原来命令里的-o 参数去掉就好了。iptables -t nat -A POSTROUTING -s x.x.x.x/x -j MASQUERADE,里面的xxx换成你的PPTP分配的IP地址网段就好了。我这个例子中是192.168.8.0/24

DNS选择

目前来说DNS没有找到一个好用的DNS,国内大部分DNS都把fb啊,tw,google地址直接屏蔽了,自己架一个又太麻烦。暂时使用8.8.8.8,这样的话问题就是一些校内的CDN用不了了,还有国内某些网站会直接解析到了海外的CDN,像乐视、爱奇艺这样的视频网站,导致在这些网站的体验不是很好。不过可以直接忽略。

测试

使用traceroute 跟踪几个网站就能看到具体路由的选择。就能看到配置的正确性。我在使用Mac更新一些系统的时候,速度能到1-2MB/s,速度还是可观的。

问题

目前存在的DNS问题,还有就是Mac下对IPv6支持太差。使用PPTP连上之后,所有流量都走这个通道,IPv6地址也走这个通道,非常尴尬。 马学长说的对,Mac下面IPv6的支持是个大坑。没有Windows的兼容性那么好。 有些时候OpenVPN会暂时断开,怀疑是GFW对IPv6的OpenVPN进行干扰。不过这两天稳定了很多了。

唠叨唠叨

做的时候有很多的想法,一条是直接通过chnroute生成OpenVPN的配置文件,直接推送到客户端,就不用那么麻烦了。可是看着OpenVPN推送7k多条路由,实在蛋疼,就没用。 其实这个方案是在网络层实现的转发,要是在应用层实现转发,直接使用ss就好了,easy很多。 北京的天气真是热的睡不着,宿舍也没有空调,7月份和8月份难过了。 最近装的系统有点多。许久不运动了,有点懒了。 最近动了用Golang重新撸一个博客系统的冲动,晚上抽空写了几天,还要加油写完啊。 完成于:2015.7.18 1:03