最近在用Titanium 写一个Twitter 客户端,因为要用到OAuth 认证,所以就在手机连接VPN,但是速度比较慢。刚好想在家里的路由器上加上OpenVPN,昨天就折腾了一下。
在家里路由器上加上OpenVPN的一个主要问题是,家里的网络中还有下载机,而下载的流量是不想通过VPN去传输的。虽然 chnroutes 项目的路由表可以让国内的IP走直连,国外的IP走VPN,但是eMule或者BT下载时,难免会连接到国外的用户或者服务器,这个时候也不想去浪费VPN的流量。
因为这些,我的想法是在路由器上做判断,如果是从下载机过来流量,就通过直接连接,如果其他机器,例如笔记本,就根据目标IP来判断是通过直接连接还是VPN来传输。
下载机是通过LAN连接到路由器www.luyouqiwang.com的,本来想按进入流量的设备来判断是否为下载机,后来发现实现比较麻烦,就决定按流量来源IP来判断是否为下载机的数据。
准备工作
·运行dd-wrt的路由器一个,要带有OpenVPN。
·OpenVPN服务器一个,认证方式选择证书认证。
·Linux知识若干。
当然dd-wrt并不是必须的,也可以是openwrt或者tomato之类,只要带有OpenVPN就行,如果不带OpenVPN,就需要在启动过程中去外部下载相关的软件,那就是另外的内容了,暂且不提。
网络分段
因为要按IP来区分流量是否要走VPN,因此要先划分一下局域网里要用到的IP段。
路由器的IP是192.168.2.1,DHCP分配范围为192.168.2.100~149,按照需求将一个/24的网段分为三个部分:
192.168.2.16~31,此IP段的设备流量均走直连 192.168.2.32~63,此IP段的设备流量根据目标IP判断走直连还是走 VPN 192.168.2.100~149,此IP段为DHCP分配的IP段,流量也根据目标IP来判断是否走VPN。
因为DHCP分配的IP并不可控,所以将流量走直接的设备,例如下载机,通过静态IP的方式,直接分配一个在 192.168.2.16~32 中固定IP地址,可以保证不会连接到有VPN的网络。
路由策略表
先创建一个用来直连的路由策略表,用来将所有指定IP段的流量走直连。
## 添加一个路由策略表,此表针对192.168.2.16/28的IP地址段有效
ip rule show | grep "lookup 10" || ip rule add from 192.168.2.16/28 ta 10
# 设置策略表的默认路由
WAN_IP=`ifconfig ppp0 | grep "inet addr" | cut -d ":" -f 2 | cut -d " " -f1`
ip route replace 192.168.2.0/24 dev br0 proto kernel scope link src 192.168.2.1 ta 10
ip route replace 127.0.0.0/8 dev lo scope link
ip route replace 169.254.0.0/16 dev br0 proto kernel scope link src 169.254.255.1
ip route replace default via $WAN_IP dev ppp0 ta 10
将以上代码保存在dd-wrt的Filewall Script 中,这样在每次WAN IP改变的时候,都可以更新这个路由策略表了。
OpenVPN 配置
OpenVPN按默认配置即可,需要注意的是,路由器上的tun mtu、tun mtu extra以及mssfix需要与服务器一致,或者服务器与路由器上的配置一致。
因为要用到chnroutes,但是dd-wrt中的OpenVPN配置并不支持自定义配置,没办法添加route选项,因此要把这些选项放到OpenVPN服务端的配置文件中,使用push指令在连接时推送到客户端来。
例如:
push "route 1.0.0.0 255.255.0.0 net_gateway 5"
另外一有点需要注意,如果在dd-wrt中同时启用了OpenVPN Daemon,建议将OpenVPN Daemon的启动方式设置为“System Startup”而不是“WAN Up”,在我的路由器上,使用“WAN Up”时OpenVPN Daemon和OpenVPN Client会冲突,导致OpenVPN Client启动失败。
解决max-routes
OpenVPN 客户端,默认最多只能添加 100 条路由记录,但是chnroutes正常生成的路由表,可能会在1000条以上,因此100 条是远远不够的。
这个可以通过max-routes配置项来解决,本来打算这个配置同样从服务端推送过来,但是OpenVPN 现在并不支持push “max-routes 1500″ 这样的指令。
在dd-wrt 的OpenVPN配置中,也没有相应的选项,为了解决这个问题,只能采取一个比较取巧的办法来解决。dd-wrt 中的OpenVPN配置都是存在nvram中的,在 dd-wrt 启动后,会自动从nvram中取OpenVPN的相关配置,组合成一个 openvpn.conf,而这个配置除了可以在 dd-wrt 的 Web 界面中修改,还可以直接 SSH 到dd-wrt 上,直接使用nvram命令修改。
在这里要hack的配置是mssfix,当然其他的属性也可以,选择mssfix是因这个属性比较简单,改起来方便。
我这里设置了mssfix 为1400,另外服务器要推送的路由表为1300条左右,直接将max-routes设置为1500,在路由器上运行下面这个指令:
nvram set openvpncl_mssfix="1400max-routes"
需要注意的是,一定要分两行来输入,否则生成的openvpn.conf中,mssfix 1400和max-routes 1500会在同一行而导致配置失效。
这样在生成的OpenVPN配置文件中,就有了max-routes选项,服务端也可以正常推送路由表了。
不过这样也有一点坏处,那就是如果再修改了OpenVPN配置并保存,会把mssfix中的那个回车给去掉,再次导致连接失败。不过OpenVPN一旦配置完成,也不会经常改动,倒也不是很大的问题。
配置 DNSMasq
一般手机上连接上WiFi的时候,设置DNS等内容会比较麻烦,而如果不设置DNS,会导致在手机上解析域名时,使用了国内的DNS服务器,而这也会导致一些问题,可以按照autoddvpn中的说明,将DNS设置为Google Public DNS和OpenDNS:
8.8.8.8和8.8.4.4,或者208.67.222.222 打完收工。
配置完成之后,就可以方便的分配家庭局域网里设备的流量走向了,想要设备的流量走直连,只要分配到 192.168.2.16~31 这个IP段就可以了,至于其他的设备,可以使用静态IP,也可以直接使用DHCP分配。
嗯,这样再在真机上调试Twitter客户端之类的程序就方便了。
PS. 非常感谢@tjmao在折腾过程中帮助。
— EOF — (出处:Architecting Life)
转自:http://www.rosabc.com/article-4963-1.html