基于SNIProxy的路由端网络流量定制分发方案

标题感觉很高大上,其实写得乱七八糟。

前序文章:
SNIProxy Bind Outgoing Interface
Build SNIProxy Debian Package for EdgeRouter
Ubnt EdgeRouter Lite 和 EdgeRouter X 上安装使用SNIProxy

不急,上边三篇可能会在本文内提及。

首先,sniproxy不解释了,但是如标题所属,sniproxy的版本不支持我要的功能,所以我就fork然后改了。
具体思路参考上述第一个链接。

接下来,直接进入正题。

按之前的玩法,我使用路由表来控制流量。这是一个很典型,也很正确的做法;但是也是一个很不好用的玩法。
参考文章:Set up OpenVPN Site-to-Site on UBNT EdgeRouter Lite, EdgeOS PPTP VPN客户端配置
PS:我维护了一份自己的路由表,地址在 https://ip.rst.im/blocks/sskaje

为了让定制化程度高一些,我配了一个Socks代理,实际上是在vpn对端配置的,本地路由做了个DNAT,转发过去了。这样我就可以用firefox+foxyproxy实现本地定制化规则。
参考文章:UBNT VPN + Socks5 代理Set up dante-server on Ubuntu

后来考虑到上述用起来麻烦,又趁着回老家的时候,在家里的ac68u merlin上实践了下WPAD,不过没有在自己家里的edgerouter上搞。
参考文章:Setup WPAD on Asus Merlin

此外,还试了一下基于源IP的firewall modify。印象中没单写blog,但是提过和用路由表的方案的优劣。
基本思路是:定义一个源地址的firewall network group;配置protocol static table;在LAN口的防火墙规则里增加modify,根据源地址组强行修改路由表。

从实际经验看,路由表不是最佳选择。
好处不必提,稳定,稳定,稳定。
坏处是,启动、更新慢慢慢。

而且现阶段,大量网站都用了诸如 cloudflare, amazon cloudfront,akamai,fastly之类的CDN服务,单纯按网段切路由,很不现实也很不灵活。
所以趁着需求,改造了一下sniproxy。
用的时间不长,所以暂时没法评估稳定性。

首先,软件部署在路由上。edgerouter lite 和 edgerouter x的包都打好了,1.9.0的固件可以直接装,下载地址在前边三个链接里有。

为了达到我要的目的,条件如下:
1 需要有本地DNS服务器(我的路由上有dnsmasq);
2 需要有稳定的VPN设备(我的是openvpn site2site,设备名vtun0)。
我的路由LAN IP是 192.168.32.1/24,设备eth0。

首先,为当前路由添加一个新的IP(我的是192.168.32.2/24),与默认IP同网段。
这里,命令行操作的时候务必别写错了设备名。其他没什么要注意的。
大致命令如下:

其次,配置好dnsmasq,将需要劫持的域名解析到 192.168.32.2。解析的配置参考下列例子

实际的经验是,不要用 set service dns forwarding options 来设置dnsmasq,自己维护一个配置文件,放在 /config/ 下,link/etc/dnsmasq.d

第三步,安装配置我的版本的sniproxy,假定监听端口分别问 192.168.32.2:3080 和 192.168.32.2:3443,分别用于接收 80端口和443端口的请求。
安装步骤参考最前边的链接。
配置文件参考

最后,配置DNAT,将192.168.32.2:80和192.168.32.2:443分别转到3080和3443,防止80和443的请求到达路由的lighttpd。

基于SNIProxy的路由端网络流量定制分发方案 by @sskaje: https://sskaje.me/2016/11/%e5%9f%ba%e4%ba%8esniproxy%e7%9a%84%e8%b7%af%e7%94%b1%e7%ab%af%e7%bd%91%e7%bb%9c%e6%b5%81%e9%87%8f%e5%ae%9a%e5%88%b6%e5%88%86%e5%8f%91%e6%96%b9%e6%a1%88/