简介
在美久居,有一项非常不方便的地方,就是无法使用QQ音乐,网易云音乐来听中文歌。大多数歌曲都会显示无法播放。
这些应用的服务器端,会根据你的IP地址来判断你的位置。如果发现你在境外,就会拒绝你的播放请求。
解决这个问题有很多方法,最快的方法是使用VPN软件。然而软件VPN有两个问题,一是所有流量发送到国内不方便,而且还要人为开启连接;二是类似Sonos这样的离线播放器无法使用。
我们这里介绍通过配置Ubiquiti的EdgeRouter来实现全家在线听歌,非常便利。Ubiquiti这个品牌国内不太响亮,他在网络界算是比较特立独行,以互联网直销为主,主打性价比和稳定性,是市值百亿美元上市公司。他家的Edgerouter-X,被国内网友称为弱电箱之王,京东售价不到400元。
这里介绍如何设置家里路由器,方便访问墙内的音乐网站服务。同时我们还利用家里的路由器,作为移动VPN接入点,这样即使出门在外也能随时随地听歌。
下面是这个方案的示意图。这里有4个元素,手机,家里的路由器EdgeOS,中国的虚拟路由器VyOS,以及墙内的服务器,包括DNS服务器(114.114.114.114)以及音乐服务器(music.qq.com等)。
这个方法的原理比较简单,只需要实现几个步骤:
- 建立VPN隧道,连接墙内VyoS和家里的EdgeRouter;
- 智能引流,区分回国流量和其他互联网流量;
- 定向流量转发,只有访问音乐网站的流量走隧道回墙内;
- 手机通过IPSec VPN与本地路由器(USA)建立连接,所有的流量都通过隧道(蓝色)到达本地路由器,在那里,流量根据目的(域名)进行分流:访问墙内音乐网站的流量通过另外一条VPN隧道(红色)流向远端路由器(China),在那里解密出隧道,再通过互联网(绿色)访问相应的网站;而其他流量都从本地路由器直接转发到互联网。
本地路由器在上述方案中扮演了核心角色。其中一个重要的功能是智能分流,也就是根据域名来确定流量的走向。大家可以参考下面的功能概要图。
- 从手机通过IPSec隧道发送过来的流量(esp1) 经过WAN口防火墙转发到IPSec功能模块(红色);解密后的流量(蓝色)再次经过DNAT替换原来的DNS查询包目标地址为路由器内loopback接口地址(10.255.0.254),通过防火墙后发送到DNSMASQ模块(绿色);
- 家里设备流量通过局域网直接使用DNSMASQ作为DNS代理;
- DNSMASQ模块发现域名与预先设置的分流域名匹配,随之向墙内的上游DNS服务器(114.114.114.114)发出查询请求(紫色);
- 路由转发引擎根据路由表将该查询请求(紫色)转发到IPSec加密模块;加密过的流量通过WAN口发送到墙内的远端路由器。
介绍完原理,下面我们来看看具体如何配置。
预先准备
路由设备
实现本文介绍的功能,你需要在家里使用一台EdgeRouter,国内要有一台安装好VyOS的软路由(EdgeRouter也可以)。
配置拨号VPN以及回国IPSec隧道
- 手机到本地路由器的IPSec连接:参见在EdgeOS/VyOS上启用IKEv2 VPN一文
- 本地路由器与VyOS的GRE over IPSec隧道,参见如何设置分支机构互连 (2) GRE over VPN
DNSMASQ智能分流
内部DNS服务器
我们先给loopback接口设置地址:
configure set interfaces loopback lo address 10.255.0.254/32
然后是修改/config/ipsec.d/ipsec.conf,把loopback地址设置为下发的客户端DNS服务器地址
... #rightdns=8.8.8.8,8.8.4.4 rightdns=10.255.0.254 ...
LAN口启用DNS转发服务
要让DNSMASQ起作用,前提是主机需要使用EdgeRouter的DNS服务。因此在配置EdgeRouter的DHCP服务器时,下发的DNS配置必须指向路由器,而不是公网DNS,如114.114.114.114或者8.8.8.8。
set service dhcp-server shared-network-name LAN subnet 10.0.0.0/24 dns-server 10.255.0.254
重定向DNS请求
某些Linux客户端,不一定会使用下发的DNS,因此,需要将所有的DNS请求都重定向到loopback接口。我们知道,DNS的协议非常简单,使用UDP的端口53,查询也就一个包,因此我们可以配置如下目标地址转换来实现重定向。
set service nat rule 1000 destination port 53 set service nat rule 1000 source address 10.255.255.0/24 set service nat rule 1000 inbound-interface eth0 set service nat rule 1000 inside-address address 10.255.0.254 set service nat rule 1000 inside-address port 53 set service nat rule 1000 log disable set service nat rule 1000 protocol udp set service nat rule 1000 type destination
防火墙地址集
我们需要建立一个防火墙地址集,用于收藏远端DNS服务器解析出来的IP地址。
set firewall group address-group MUSIC
启用DNSMASQ
第一步是启用DNSMASQ;然后,确保DNSMASQ会监听loopback接口上收到的DNS请求;
set service dhcp-server use-dnsmasq enable set service dns forwarding cache-size 1500 set service dns forwarding except-interface=eth0 set service dns forwarding name-server 8.8.8.8 set service dns forwarding name-server 8.8.4.4 set service dns forwarding options listen-address=10.255.0.254
注意上文中,我们启用了一条options配置,设置list-address为loopback接口IP,这一条很关键,否则DNSMASQ不会响应来自IPSec隧道的请求。
域名分析
上述智能分流要用到的一个重要数据是相关的域名列表。我们知道,一个应用往往会用到多个域名。光dropbox,就会用到十多个不同的域名。dropbox比较有良心,官网直接列出自己使用的域名,但大多数商家没有这样做,因此我们需要自己有办法来分析哪些域名会被用到。
分析域名的一个最有用的工具就是tcpdump。我们知道DNS请求有一个特定的端口号:53,因此我们只要去截获匹配端口号53以及相应主机的IP,就可以捕获所有的相关DNS请求。参考EdgeOS命令如下:
sudo tcpdump -n -i switch0 port 53 and host 10.1.8.106
下面是捕获的截屏
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on switch0, link-type EN10MB (Ethernet), capture size 262144 bytes 06:46:53.276711 IP 10.1.8.106.52757 > 10.1.8.254.53: 3794+ A? google.com. (28) 06:46:53.277244 IP 10.1.8.254.53 > 10.1.8.106.52757: 3794 1/0/0 A 216.58.194.206 (44)
我们可以看到主机10.1.8.106向路由器发送了一条域名解析申请,域名是”google.com“,以及相应的回复。
我们可以用这个办法,在打开相关应用时,监控DNS请求,再把相应的域名添加到DNSMASQ的域名清单里。
第三方dnsmasq配置文件
如果你需要处理的域名很多,或者想用第三方收集的配置文件,将文件中的server/ipset一行行地添加到配置里,将是一件很繁琐的事情。
经过分析,我们发现在EdgeOS里,所有配置为service dns forwarding options 后面的文本,都会原样不动地转换为/etc/dnsmasq.conf里的对应一行。因此,我们可以调用dnsmasq的conf-file功能,以简化配置。
具体操作时,你可以将相应的配置文件,保存在/config目录下,例如保存为/config/dnsmasq/dnsmasq-china-muisc.conf;然后添加以下配置。
set service dns forwarding options conf-file=/config/dnsmasq/dnsmasq-china-muisc.conf.conf
下面是dnsmasq-china-muisc.conf的示范文件,
ipset=/ximalaya.com/xmcdn.com/163.com/126.net/163yun.com/MUSIC server=/ximalaya.com/xmcdn.com/163.com/126.net/163yun.com/114.114.114.114 server=/kugou.com/kuwo.cn/114.114.114.114 ipset=/hicloud.com/huawei.com/MUSIC server=/hicloud.com/huawei.com/114.114.114.114 ipset=/kugou.com/kuwo.cn/MUSIC server=/y.qq.com/music.qq.com/114.114.114.114 ipset=/y.qq.com/music.qq.com/MUSIC server=/music.tcdn.qq.com/114.114.114.114 ipset=/music.tcdn.qq.com/MUSIC server=/taobao.com/114.114.114.114 server=/alicdn.com/alimama.com/alibabadns.com/tbcache.com/114.114.114.114 server=/alibabacorp.com/114.114.114.114 ipset=/taobao.com/MUSIC ipset=/alicdn.com/alimama.com/alibabadns.com/tbcache.com/MUSIC ipset=/alibabacorp.com/MUSIC server=/sonos.com/114.114.114.114 ipset=/sonos.com/MUSIC server=/sonoschina.com/114.114.114.114 ipset=/sonoschina.com/MUSIC
路由
DNS路由
为了使用国内的域名服务器来解析音乐网站,需要配置一条静态路由,让访问墙内DNS服务器(114.114.114.114)的流量都走GRE over IPSec隧道,转发到远端路由器。
set protocols static interface-route 114.114.114.114/32 next-hop-interface tun0 distance 100
策略路由
DNSMASQ已经把墙内音乐网站的IP地址收录到地址集MUSIC里。我们使用下面的策略路由规则,让所有访问墙内音乐网站的流量走GRE隧道tun0。
set protocols static table 50 interface-route 0.0.0.0/0 next-hop-interface tun0 distance 100 set firewall modify PBR rule 2410 action modify set firewall modify PBR rule 2410 destination group address-group MUSIC set firewall modify PBR rule 2410 modify table 50 set firewall modify PBR rule 2410 protocol all set interfaces eth0 firewall in modify PBR
NAT
当转发的流量通过隧道到达墙内一端后,其源地址还是这边内网的地址,因此返回的流量就需要在墙内路由器上配置相关的路由,否则会因为那边查找不到相应的路由而被丢弃。有个简单的方法可以规避配置这个路由,就是在GRE隧道出口启用masqurade做出口地址转换。这样,进入隧道的流量的源地址包都是隧道口地址,而对端是自然知道返回路由的。
set service nat rule 5100 'nat for GRE tunnel tun0' set service nat rule 5100 outbound-interface tun0 set service nat rule 5100 type masquerade commit;save;exit
验证
你可以使用以下命令来验证配置是否正确:
- show ip route
- show ip route table 50
- show firewall modify PBR statistics
- sudo ipset -L MUSIC
- sudo tcpdump -n -i eth0 port 53
- sudo tcpdump -n -i tun0 port 53