文章目录
最近在用 Titanium 写一个 Twitter 客户端,因为要用到 OAuth 认证,所以就在手机连接 VPN,但是速度比较慢。刚好想在家里的路由器上加上 OpenVPN,昨天就折腾了一下。
在家里路由器上加上 OpenVPN 的一个主要问题是,家里的网络中还有下载机,而下载的流量是不想通过 VPN 去传输的。虽然 chnroutes 项目的路由表可以让国内的 IP 走直连,国外的 IP 走 VPN,但是 eMule 或者 BT 下载时,难免会连接到国外的用户或者服务器,这个时候也不想去浪费 VPN 的流量。
因为这些,我的想法是在路由器上做判断,如果是从下载机过来流量,就通过直接连接,如果其他机器,例如笔记本,就根据目标 IP 来判断是通过直接连接还是 VPN 来传输。
下载机是通过 LAN 连接到路由器的,本来想按进入流量的设备来判断是否为下载机,后来发现实现比较麻烦,就决定按流量来源 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="1400
max-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 ---
恭喜折腾成功!
谢谢。我有空再折腾看看能不能两个无线信号出来,一个有VPN一个没有VPN,哈哈
哈哈,有没有折腾成功啊?
请教一个问题,为什么我openvpn连接成功了,电脑却上不了网了?还要有其他设置么?
成功了呀,你可以先在电脑上测试一下,或者在路由器上不要加 –deamon 参数运行 openvpn,看看哪里出问题。
搜Joggler找过来,发现都是网友啊,:D
好棒,房子装好就实验下,折腾星人万岁
:mrgreen: :mrgreen: :mrgreen:
哈哈,原来是你啊!!我也准备折腾路由器呢,不懂了再来咨询你
想問一下,為何我明明加了淘寶的IP進去,但沒有效果?
由於科學上網,但有需要逛淘寶時要常要切換上網模式,
非常麻煩,所以有這需求